Appropriate limit for dynamic areas
Matthew Phillips (473) 721 posts |
For a while we have been thinking of changing RiscOSM so that it uses dynamic areas to load the map data. One reason for doing this is that RISC OS 4/6 users have a limited Wimp slot and RiscOSM can often exceed that limit in loading data. There are a few people using RiscOSM on a Risc PC (despite the processing demands of the software) but also we have had enquiries from people using emulated hardware. Even on RISC OS 5 there might be some advantages to using a dynamic area as the block can be freed extremely quickly without fragmenting the main malloc heap. My question is, what is a civilised upper limit to place on the size of the dynamic area? We could quite easily partition the data into multiple dynamic areas which might help avoid blocking a huge monolithic chunk of logical address space. But if we make the limit too small then the user will see nothing but RiscOSM in the Task Manager window! On the machine I am using to write this, I see NetSurf is using 7MB of Wimp slot and just over 17MB spread across three dynamic areas. On a map of central London RiscOSM is using 57MB of Wimp slot. Any advice on size limits and whether dynamic area use should be optional or not on RISC OS 5 would be appreciated. |
Rick Murray (539) 13840 posts |
Three considerations: Firstly, if it is possible, it may be a nice idea to have DAs as a configuration option. Secondly, can’t DAs be extended? If so, the default could be something derived from the machine’s memory capacity – for example 16MiB on a 64MiB system, 64MiB on a 256MiB system, something like that? Finally, what happens if multiple copies of RiscOSM are run? I ask because Ovation (the one I’m hacking) used to use DAs but it got itself in a twist of you started up several copies. Since app slots are not (normally) an issue in RISC OS 5, Ovation will revert to using application space for its data in RISC OS versions >4 1 otherwise using DAs in RISC OS versions <=4 because the 26 bit systems are limited in their maximum app space. 1 This, of course, exemplifying why it was a really dumb idea to come up with RISC OS SIX. Well, if anybody considers running Ovation on such a system, and UtilityModule identifies itself as 6.xx, Ovation will take the RO5 behaviour. I will categorically not make code to handle this issue2 as I believe that subsequent incarnations should build upon the previous (as has traditionally been the way in many environments). Plus, I’d just need to fix it all (again) to skip around the obnoxious version numbering hole should Jeffrey decide to roll out his RISC OS 7. 2 Not specifically Ovation, it’s the policy I’m applying to all of my software (although given that I can’t rely upon UtilityModule version, if I am aiming something at the ROOL version of RISC OS, my preferred way of checking is to ask of there is a HAL. If the answer is yes, it’s ROOL). |
Steffen Huber (91) 1953 posts |
Only use DAs on RISC OS 5 if you absolutely need one of the DA features. From what you describe, I can’t see a reason for RiscOSM to have any real need to use a DA. As for running on RISC OS 4 or SIX, I would just allocate a DA with “maximum size”. Users will usually have a DA clamp in place if they have 128MB or 256MB and encountered address space exhaustion previously. Alternatively, make it configurable. |
Jeffrey Lee (213) 6048 posts |
You can use OS_ReadDynamicArea to read the maximum size of application space (DA number -1) – IIRC the returned value will correctly reflect whether Aemulor is running. So I’d recommend using that to decide what strategy to take (<=32MB, use dynamic area, >32MB, use application space). On RISC OS 5 the application space limit is currently 512MB, but that’s likely to go up over time, not down (One of the things I’m considering is a CMOS option to allow the user to configure the limit, say from 512MB up to 2GB – so that software which needs to use large amounts of data can do so without resorting to using DAs)
You’d be trading fragmenting your applications malloc heap with fragmenting the OS’s DA address space. The first is a problem that can be fixed by restarting your app (or using fragmentation-free memory managers like flex), the second is a problem that can probably only be fixed by restarting everything that the user started after they started your app. One of the things that’s on my todo list (but no timescale yet) is to give application space PMP-like abilities, so that applications can be given full control of their memory mapping. That way a fragmented heap can still release pages into the free pool (as long as the free fragments are large enough). And we’d be able to fix the problem where using system() artificially restricts the amount of memory the child process is allowed to use. Hopefully these abilities can easily be built into CLib so that it will benefit existing apps. AIUI the inflexibility of application space is also the main reason why UnixLib (and most of the apps which use it, like NetSurf) default to using dynamic areas instead of application space. So considering that your current problem is only with RISC OS 4/6, and that RISC OS 5’s memory management will change and improve in future, I’d recommend only using DAs for 4/6. If RISC OS 5 starts to become an issue then all you need to do is pester me to fix it ;-) (Seriously – if people are having problems but aren’t making noise about it then myself and the other OS developers won’t have a clue what priority fixing the problem should be, or even whether the problem exists)
They can be extended, but only up to the maximum size that was specified at creation time. Which doesn’t do anything for logical address space exhaustion/fragmentation – when the DA is created it’s reserved enough address space for its maximum size. |
Steve Fryatt (216) 2105 posts |
The downside on RO5 is that for large amounts of data (which applies to RiscOSM), you quickly make a mark on the available DA space. I’d certainly prefer it if RiscOSM continued to not use DAs on RO5. Fragmenting malloc space is, unfortunately, what RISC OS does. |
Steve Fryatt (216) 2105 posts |
When I last mentioned flex over in the newsgroups (in the context of using it to avoud fragmented malloc heaps), ISTR an ex-Acorn person strongly advising against it because it was seriously buggy. I can’t say that I’ve ever had any issues in over 10 years of using it in several applications, but what’s the ‘official’ view? |
Jeffrey Lee (213) 6048 posts |
using fragmentation-free memory managers like flex Good question! I have limited experience with flex. As far as I know there aren’t any bugs in it, but I do know that correctly writing a flex-using app requires a fair amount of care because there’s no way for the compiler to give a warning or error when you’ve done something that causes flex blocks to move. E.g. a few months ago there was a 10+ year old flex-related bug I fixed in Paint, where the declaration of a variable-length array was causing the malloc heap to extend (causing the flex blocks to move), invalidating the sprite area pointer which the containing function had previously fetched. No doubt there are some guidelines you can follow to reduce the chances of bugs, but I suspect the only way of completely avoiding flex-related bugs would be to use a different language where a fragmentation-free heap is a core feature. |
Matthew Phillips (473) 721 posts |
Thanks Jeffrey for that important reminder – another reason for using dynamic areas is that some users have had trouble with RiscOSM because they are running Aemulor. So it would be useful to support DA use on RISC OS 5 also, and your suggestion is the ideal way to distinguish when to do so and when not to.
Yes, we hit that limit for the first time when running OSMConvert on a Pandaboard. None of our previous machines had had more than 512MB RAM anyway. So OSMConvert does use dynamic areas in order to hold the node indexes in memory so far as possible when converting the map data. Thanks for your comments also, Steve. I wish I knew how the heap for a Norcroft C application was structured, tehn it might be possible to do some analysis after RiscOSM has been running for a while to see what the situation is like. To work with DAs on RISC OS 4, 6, or under Aemulor, we are likely to be loading the map data into DAs. The map data remain pretty static once loaded until they are thrown out when a different area of the country is loaded. As far as I remember, the individual block do not need extending after loading, so the allocation mechanism could be as simple as a pointer to the end of the used part of the DA. This would save some overhead in the chain of malloc blocks, but I’m not sure how significant the overhead would be. One could apply the same principle using application space, first allocating a large block with malloc and then filling it as with the DA. When discarding the map data, the pointer to free space could be reset to the start of the block and the block reused to load new data. I’ve no idea whether this would improve the speed of memory allocation for the thousands of individual units of data that are loaded. We’ll need to do some experiments. |