From: Julian Seward Date: Thu, 5 Oct 2006 17:56:14 +0000 (+0000) Subject: Excellent documentation from Graydon Hoare on his mempool X-Git-Tag: svn/VALGRIND_3_3_0~662 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68a0c28d679d52006dfcde5f7811e0c0e331b5af;p=thirdparty%2Fvalgrind.git Excellent documentation from Graydon Hoare on his mempool client-request work. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6196 --- diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml index 410ede7ef8..ed2a714267 100644 --- a/memcheck/docs/mc-manual.xml +++ b/memcheck/docs/mc-manual.xml @@ -1072,4 +1072,202 @@ arguments. + + + + + +Memory Pools: describing and working with custom allocators + +Some programs use custom memory allocators, often for performance +reasons. There are many different sorts of memory pool, so Memcheck +attempts to reason about them using a loose, abstract model. We +use the following terminology when describing custom allocation +systems: + + + + Custom allocation involves a set of independent "memory pools". + + + + Memcheck's notion of a a memory pool consists of a single "anchor + address" and a set of non-overlapping "chunks" associated with the + anchor address. + + + Typically a pool's anchor address is the address of a + book-keeping "header" structure. + + + Typically the pool's chunks are drawn from a contiguous + "superblock" acquired through the system malloc() or mmap(). + + + + +Keep in mind that the last two points above say "typically": the +Valgrind mempool client request API is intentionally vague about the +exact structure of a mempool. There is no specific mention made of +headers or superblocks. Nevertheless, the following picture may help +elucidate the intention of the terms in the API: + + + + +Note that the header and the superblock may be contiguous or +discontiguous, and there may be multiple superblocks associated with a +single header; such variations are opaque to Memcheck. The API +only requires that your allocation scheme can present sensible values +of "pool", "addr" and "size". + + +Typically, before making client requests related to mempools, a client +program will have allocated such a header and superblock for their +mempool, and marked the superblock NOACCESS using the +VALGRIND_MAKE_MEM_NOACCESS client request. + + +When dealing with mempools, the goal is to maintain a particular +invariant condition: that Memcheck believes the unallocated portions +of the pool's superblock (including redzones) are NOACCESS. To +maintain this invariant, the client program must ensure that the +superblock starts out in that state; Memcheck cannot make it so, since +Memcheck never explicitly learns about the superblock of a pool, only +the allocated chunks within the pool. + + +Once the header and superblock for a pool are established and properly +marked, there are a number of client requests programs can use to +inform Memcheck about changes to the state of a mempool: + + + + + + VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed): + This request registers the address "pool" as the anchor address + for a memory pool. It also provides a size "rzB", specifying how + large the redzones placed around chunks allocated from the pool + should be. Finally, it provides an "is_zeroed" flag that specifies + whether the pool's chunks are zeroed (more precisely: defined) + when allocated. + + + Upon completion of this request, no chunks are associated with the + pool. The request simply tells Memcheck that the pool exists, so that + subsequent calls can refer to it as a pool. + + + + + VALGRIND_DESTROY_MEMPOOL(pool): + This request tells Memcheck that a pool is being torn down. Memcheck + then removes all records of chunks associated with the pool, as well + as its record of the pool's existence. While destroying its records of + a mempool, Memcheck resets the redzones of any live chunks in the pool + to NOACCESS. + + + + + VALGRIND_MEMPOOL_ALLOC(pool, addr, size): + This request informs Memcheck that a "size"-byte chunk has been + allocated at "addr", and associates the chunk with the specified + "pool". If the pool was created with nonzero "rzB" redzones, Memcheck + will mark the "rzB" bytes before and after the chunk as NOACCESS. If + the pool was created with the "is_zeroed" flag set, Memcheck will mark + the chunk as DEFINED, otherwise Memcheck will mark the chunk as + UNDEFINED. + + + + + VALGRIND_MEMPOOL_FREE(pool, addr): + This request informs Memcheck that the chunk at "addr" should no + longer be considered allocated. Memcheck will mark the chunk + associated with "addr" as NOACCESS, and delete its record of the + chunk's existence. + + + + + VALGRIND_MEMPOOL_TRIM(pool, addr, size): + This request "trims" the chunks associated with "pool". The request + only operates on chunks associated with "pool". Trimming is formally + defined as: + + + All chunks entirely inside the range [addr,addr+size) are + preserved. + + + All chunks entirely outside the range [addr,addr+size) are + discarded, as though VALGRIND_MEMPOOL_FREE + was called on them. + + + All other chunks must intersect with the range + [addr,addr+size); areas outside the intersection are marked as + NOACCESS, as though they had been independently freed with + VALGRIND_MEMPOOL_FREE. + + + This is a somewhat rare request, but can be useful in + implementing the type of mass-free operations common in custom + LIFO allocators. + + + + VALGRIND_MOVE_MEMPOOL(poolA, poolB): + This request informs Memcheck that the pool previously anchored at + address "poolA" has moved to anchor address "poolB". This is a rare + request, typically only needed if you realloc() the header of + a mempool. + No memory-status bits are altered by this request. + + + + + VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size): + This request informs Memcheck that the chunk previously allocated at + address "addrA" within "pool" has been moved and/or resized, and should + be changed to cover the region [addrB,addrB+size). This is a rare + request, typically only needed if you realloc() a superblock or wish + to extend a chunk without changing its memory-status bits. + + No memory-status bits are altered by this request. + + + + + VALGRIND_MEMPOOL_EXISTS(pool): + This request informs the caller whether or not Memcheck is currently + tracking a mempool at anchor address "pool". It evaluates to 1 when + there is a mempool associated with that address, 0 otherwise. This is a + rare request, only useful in circumstances when client code might have + lost track of the set of active mempools. + + + + + + +