|#define||pool_free_element(ps, eltpointer) pool_free_elementF((ps),(eltpointer))|
|typedef struct pool_store_header *||pool_store_t|
|ASC_DLLSPEC void||pool_get_stats (struct pool_statistics *p_stats, pool_store_t ps)|
|ASC_DLLSPEC pool_store_t||pool_create_store (int length, int width, size_t eltsize, int deltalen, int deltapool)|
|ASC_DLLSPEC void *||pool_get_element (pool_store_t ps)|
|void||pool_get_element_list (pool_store_t ps, int len, void **ellist)|
|ASC_DLLSPEC void||pool_free_elementF (pool_store_t ps, void *eltpointer)|
|ASC_DLLSPEC void||pool_clear_storeF (pool_store_t ps)|
|ASC_DLLSPEC void||pool_destroy_store (pool_store_t ps)|
|void||pool_print_store (FILE *fp, pool_store_t ps, unsigned detail)|
|size_t||pool_sizeof_store (pool_store_t ps)|
|#define pool_DEBUG FALSE|
|#define pool_LIGHTENING FALSE|
Flag controlling extent of internal sanity checking. Setting pool_LIGHTENING to TRUE causes pool_store routines to assume the user is perfect: i.e. no sanity checks are at all necessary and most internal accounting can be disabled. No one with an ounce of sanity would ever set this flag to TRUE unless the code using the pool module was proven bug free. It makes the allocator smaller and faster, though, by ~15%.
This flag exists to make it easy to test the theory that the accounting overhead in this code is not of significant cost. Below 1e5 elements it really isn't bad enough to justify the assumption that the user is perfect.
Releases an element back to the store. If you return the same pointer twice, we will have no qualms about returning it to you twice. We won't necessarily return it to you twice, though.
If pool_DEBUG is TRUE, eltpointer will be checked for belonging to ps. If you call pool_free_element() with a pointer the ps does not recognize, it will not be freed and a message will be sent to ASCERR.
If pool_DEBUG is FALSE, eltpointer will be assumed to belong with the ps in question. The implications of handing pool_free_element() an element of the wrong size or from the wrong ps (bearing in mind the LIFO reuse of elements) should be obvious. If they are not, stop using these routines.
If at any time the number of elements freed exceeds the number handed out, we will whine (unless pool_LIGHTENING). If ps is NULL, and error message is printed and the function returns. If eltpointer is NULL, we will ignore it completely.
|ps||pool_store_t, the pool store to modify.|
|eltpointer||void*, the element to return to the pool.|
Clears the books in ps. That is, we reset the ps to think that __all__ elements are freshly available and have never been handed out. If ps is NULL, an error message is printed and the function returns.
If pool_DEBUG is TRUE, it first verifies that all elements have been pool_freed first and whines if not. Get and free calls will be balanced to see if spurious elements have been handed in. (This is a heuristic check). The clear process will cause any spurious pointers that were turned in via pool_free_element() to be forgotten about.
Clearing a store is not necessary for pool_destroy_store(). Recycling is faster from the recycle list than from a cleared store, ~2%. Clear is provided for users who want to obtain elements with a higher probability of successive elements being near each other.
|ps||pool_store_t, the pool store to clear.|
Get statistics about a pool store. Stuffs the user's interface structure, p_stats, with info derived from ps given. If pool_LIGHTENING (see below) is TRUE, no statistics except elt_total, elt_taken, elt_onlist, and elt_size are available.
|p_stats||Pointer to a pool_statistics struct to receive the info. If p_stats is NULL, an error message is printed and the function returns.|
|ps||Pointer to the pool store to query.|
References pool_store_header::active, ASC_PROG_ERR, ascbzero, pool_store_header::curbar, pool_store_header::curelt, pool_statistics::elt_inuse, pool_statistics::elt_onlist, pool_statistics::elt_size, pool_statistics::elt_taken, pool_statistics::elt_total, pool_store_header::eltsize, pool_store_header::eltsize_req, ERROR_REPORTER_HERE, pool_store_header::highwater, pool_store_header::inuse, pool_store_header::len, pool_store_header::onlist, pool_statistics::p_eff, pool_statistics::p_recycle, pool_sizeof_store(), pool_statistics::str_len, pool_statistics::str_wid, pool_store_header::total, and pool_store_header::wid.
|ASC_DLLSPEC pool_store_t pool_create_store||(||int||length,|
Creates and returns a new pool store. The returned pool_store_t contains all the necessary accounting information, but in particular the eltsize is fixed at creation. All elements requested from ps will be pointers to eltsize bytes of memory. Returns NULL if a store of the requested length*width*eltsize cannot be initially allocated.
The user may request more than length*width elements from the store: this will cause it to grow. It will grow (internally) in chunks of deltalen*width elements. The pool vector above grows in chunks of deltapool, the extra pointers in it being NULL until needed.
|length||The initial number of width*eltsize blocks that the new pool store will contain. If length < 1, an error message is printed and NULL is returned.|
|width||Number of elements in each block. Width should (for some architectures) be such that width*eltsize = 2^n - 32 for some n fairly large (heuristic: n= 9..13). Widths that are too large may be prone to causing excess page faults, though the process cpu time reported by the clock() can be much better for extremely large sizes. If width < 1, an error message is printed and NULL is returned.|
Widths that are too small will result in an excessive number of pool expansions, which may severely limit performance on some VM systems. See deltapool below about pool expansions.
If you know something about the page size of your architecture, fiddling with width may help you reduce your page fault or cache miss count in some uses.
|eltsize||Element size maintained by the pool. For maximum efficiency, eltsize should be an integer multiple of sizeof(void *). If it is not, elts will be padded so that this is the case. This is to avoid pointer data misalignment. This restriction may or may not help avoid alignment problems with items inside the user's element structure.|
|deltalen||Number of additional pointers in the pool that will be allocated when more elements are needed than are available internally. deltalen must be at least 1 or creation of the new pool will fail.|
|deltapool||Size change of the pool array when expanded. It should be as large as you are willing to tolerate. The pool array starts out completely filled (all pointers allocated). When the pool needs more pointers it gets them in chunks of at least deltapool. These additional pointers will not automatically have elements allocated to them; rather, they will be initialized to NULL and filled in only as the chunks of deltalen*width elements are required.|
References ASC_PROG_ERR, pool_store_header::barsize, CONSOLE_DEBUG, DESTROYED, pool_store_header::eltsize, pool_store_header::eltsize_req, ERROR_REPORTER_HERE, pool_store_header::expand, pool_store_header::growpool, pool_store_header::integrity, pool_store_header::len, pool_store_header::maxlen, NULL, OK, PMEM_calloc, PMEM_free, PMEM_malloc, PMEM_MINBARSIZE, PMEM_MINPOOLGROW, PMEM_MINPOOLSIZE, PMX, pool_store_header::pool, pool_store_header::total, and pool_store_header::wid.
Referenced by gl_init_pool(), InitInstanceNanny(), InitLogRelInstantiator(), InitPendingPool(), InitRelInstantiator(), InitSetManager(), InitValueManager(), ppe_init_pool(), and RelationIO_init_pool().
|ASC_DLLSPEC void* pool_get_element||(||pool_store_t||ps||)|
Get a usable element from the pool. Returns a void pointer to a blob of memory of the eltsize set when ps was created. You must cast it appropriately. The blob data is not initialized in any particular way.
|ps||The pool store from which to retrieve an element. If ps is NULL, then an error message is printed and NULL is returned.|
References pool_store_header::active, ASC_PROG_ERR, pool_store_header::curbar, pool_store_header::curelt, pool_store_header::eltsize, ERROR_REPORTER_HERE, pool_store_header::highwater, pool_store_header::inuse, pool_store_header::len, pool_store_header::list, pool_element::nextelt, NULL, pool_store_header::onlist, pool_store_header::pool, and pool_store_header::wid.
Takes the pointer array, ellist, of length len provided by the user and fills it with pointers to elements from the store. There is not necessarily any relation (memory map wise) between the locations pointed to by successive entries in the ellist returned. Ellist should point to an array with enough space for len pointers. Returns NULL in ellist iff store growth is required and the operating system is unable to allocate the required memory.
The user is reminded that if he knows how many elements he needs ahead of time, he is probably better off mallocing the array himself.
|ASC_DLLSPEC void pool_free_elementF||(||pool_store_t||ps,|
|ASC_DLLSPEC void pool_clear_storeF||(||pool_store_t||ps||)|
References pool_store_header::active, ASC_PROG_ERR, ASC_PROG_WARNING, pool_store_header::curbar, pool_store_header::curelt, ERROR_REPORTER_HERE, pool_store_header::highwater, pool_store_header::inuse, pool_store_header::list, NULL, pool_store_header::onlist, pool_store_header::retned, and pool_store_header::wid.
|ASC_DLLSPEC void pool_destroy_store||(||pool_store_t||ps||)|
Deallocates everything associated with the ps. If pool_DEBUG is TRUE, it first verifies that all elements have been pool_freed first and whines if not. If pool_DEBUG is FALSE, just nukes everything unconditionally. If ps is NULL, an error message is printed and the function returns.
|ps||The pool store to destroy.|
References ASC_PROG_ERR, ASC_PROG_WARNING, DESTROYED, ERROR_REPORTER_HERE, pool_store_header::highwater, pool_store_header::integrity, pool_store_header::inuse, pool_store_header::len, OK, pool_store_header::onlist, PMEM_free, and pool_store_header::pool.
Referenced by DestroyInstanceNanny(), DestroyLogRelInstantiator(), DestroyPendingPool(), DestroyRelInstantiator(), DestroySetManager(), DestroyValueManager(), gl_destroy_pool(), ppe_destroy_pool(), and RelationIO_destroy_pool().
|void pool_print_store||(||FILE *||fp,|
Prints statistics about a pool_store_t to the file stream given. Which stats get printed depends on detail.
|fp||The open file stream on which to print the report.|
|ps||The pool store on which to report.|
|detail||The level of detail to print: 0 = summary, 1 = internal stats, >1 = both.|
References pool_store_header::active, ASC_PROG_ERR, pool_store_header::barsize, pool_store_header::curbar, pool_store_header::curelt, pool_store_header::eltsize, pool_store_header::eltsize_req, ERROR_REPORTER_HERE, pool_store_header::expand, FPRINTF, pool_store_header::growpool, pool_store_header::highwater, pool_store_header::integrity, pool_store_header::inuse, pool_store_header::len, pool_store_header::maxlen, OK, pool_store_header::onlist, pool_sizeof_store(), pool_store_header::retned, pool_store_header::total, and pool_store_header::wid.
Referenced by gl_report_pool(), ppe_report_pool(), RelationIO_report_pool(), ReportInstanceNanny(), ReportLogRelInstantiator(), ReportPendingPool(), ReportRelInstantiator(), ReportSetManager(), and ReportValueManager().
Retrieves the current total byte usage of the store. Returns 0 if an invalid pool store is specified.
|ps||pool_store_t, the pool store to query.|