On Mon, Jun 10, 2002 at 11:46:46AM +0300, Zeev Suraski wrote: > What we need for efficient thread-safe operation is a mechanism like the > Win32 heaps - mutexless heaps, that provide malloc and free services on a > (preferably) contiguous pre-allocated block of memory. The question is > whether the APR allocators fall into that category: > > 1. Can you make them mutexless completely? I.e., will they never call > malloc()?
APR's pools only use malloc() as a portable way to retrieve large chunks of heapspace that are never returned. I don't know of any other portable way to do this. In any case, at some level you will always have a mutex. Either you are mapping new segments in to the memory space of the process, or you are dealing with freelists in userspace. APR pools take the approach that by doing more up-front segment mapping and delayed freeing of chunks, we avoid many of the mutexes and overhead of freelist management. It's still got to happen somewhere though. > 2. They definitely do provide alloc/free services, we're ok there Pretty much, but it's not exactly the same. I'll outline some thoughts on a potential memory allocation abstraction that could be implemented w/ apr_pools or Win32 heaps below... > 3. As far as I can tell, they don't use a contiguous block of memory, > which means more fragmentation... I'm not sure how contiguity relates to fragmentation. With a pool you can do mallocs all day long, slowly accumulating more 8K blocks (which may or may not be contiguous). At the end of the pool lifetime (let's say, for example, at the end of a request) then those blocks are placed on a freelist, and the sub-partitions within those blocks are simply forgotten. On the next request, the process starts over again. I think to properly abstract a memory allocation scheme that can be implemented in a way that is optimized for the particular SAPI module, we'll have to abstract out a few concepts. This list is not exhaustive, but is just a quick sketch based on my understanding of Win32 heaps and APR pools: - creation (called once per server lifetime) - malloc (called many times per request) - free (called many times per request) - end-of-request (called many times per request) - destruction (called once per serve lifetime) Does this cover all our bases? For example, when using pools, the free() call would do nothing, and the end-of-request call would simply call apr_pool_clear(). Note that this only applies to dynamically allocated memory required for the lifetime of a request. For memory with longer lifetimes we could make the creation and destruction routines more generic. -aaron -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php