AMALLOC(3P) AMALLOC(3P) NAME acreate, adelete, amalloc, afree, arealloc, acalloc, amallopt, amallinfo,arecalloc, amallocblksize, amemalign - arbitrary arena main memory allocator SYNOPSIS #include <sys/types.h> #include <malloc.h> void *acreate (void *addr, size_t len, int flags, void *ushdr, void *(*grow)(size_t, void *)); void *amalloc (size_t size, void *ap); void adelete (void *ap); void afree (void *ptr, void *ap); void *arealloc (void *ptr, size_t size, void *ap); void *acalloc (size_t nelem, size_t elsize, void *ap); int amallopt (int cmd, int value, void *ap); struct mallinfo amallinfo (void *ap); size_t amallocblksize (void *ptr, void *ap); void *arecalloc (void *ptr, size_t nelem, size_t elsize, void *ap); void *amemalign (size_t align, size_t size, void *ap); DESCRIPTION The arena malloc package provides a main memory allocator based on the malloc(3X) memory allocator. This allocator has been extended so that an arbitrary memory space ("arena") may be set up as an area from which to malloc. Calls to the arena malloc package differ from calls to the standard malloc(3X) only in that an arena pointer must be supplied. This arena pointer is returned by a call to acreate. acreate sets up an area defined as starting at virtual address addr and extending for len bytes. Arenas may be either growing or non-growing and either shared or unshared. An arena that is non-growing is constrained to use only up to len bytes of memory. The grow parameter should be NULL in this case. If the arena is growable, len specifies the original size (this MUST be a minimum of 1K bytes) and the grow parameter specifies a function that will be called when the allocator requires more memory. Note that the original buffer addr will be used only for the arena header, the first time more memory is required, the grow function will be called. This suggests that when setting up a growable arena a minimal (1K) original buffer be used. The function will be called with two parameters, the number of bytes required and a pointer to the arena requiring the space. The number of bytes requested will always be a multiple of M_BLKSZ (see amallopt below). The function should return the address of suitably large block of memory. This block need not be contiguous with the original arena memory. This block could be obtained from a number of sources, such as by allocating a new shared memory segment (via shmget(2)); by mapping in another file (via mmap(2)); or by calling malloc(3X) to enlarge ones data space. If the grow function decides that it cannot provide any more space it should return (void*)-1. Since the allocator package involves a two-tiered allocation strategy (small blocks and large blocks), various anomalies (such as not being able to allocate any space!) can arise when using very small non- growable arenas ( len less than 64K). For this reason acreate will set M_BLKSZ to 512 and M_MXFAST to 0 for all arenas whose size is less than 64K and is non-growable. These default values may be changed via amallopt. Users creating very small growable arenas may likewise have to tune the resulting arena's parameters. If the arena is to be shared between multiple processes, then the MEM_SHARED flag should be passed, and ushdr must be a pointer to a shared arena as returned from usinit(3P). Calling acreate with the MEM_SHARED flag tells acreate to allocate a lock, which it then uses to single thread all accesses to the arena. It is the callers responsibility to ensure that the arena is accessible by all processes, and to provide a mechanism to exchange the addresses returned by amalloc between the various processes. The MEM_NOAUTOGROW flag to acreate specifies that the memory for the arena is not going to come from a growable mmap file. This flag only has meaning for non-growable arenas. The default grow function (the one that slowly doles out up to len bytes) attempts to make sure that the memory being returned is in fact available. For all but autogrow mapped files, this is always the case - the memory was alloced somehow and by definition is available to the user process. Autogrow mapped files on the other hand can fail when first accessing a new largest page due to the file system on which the mmaped file resides being full. In this case, accesses to the file via a mapping result in a SIGBUS signal being sent. To avoid giving the applications (seemingly) random SIGBUS signals, the default grow function performs a system call to validate the memory, and if it gets a failure, returns -1 (which subsequently causes amalloc to return NULL). adelete causes any resources allocated for the arena (e.g. semaphores) to be freed. Nothing is done with the arena memory itself. No further calls to any arena functions should be made after calling adelete. amalloc returns a pointer to a block of at least size bytes suitably aligned for any use. The argument to afree is a pointer to a block previously allocated by amalloc; after afree is performed this space is made available for further allocation, and its contents are destroyed (see amallopt below for a way to change this behavior). Undefined results will occur if the space assigned by amalloc is overrun or if some random number is handed to afree. It is always permitted to pass NULL to afree. arealloc changes the size of the block pointed to by ptr to size bytes and returns a pointer to the (possibly moved) block. The contents will be unchanged up to the lesser of the new and old sizes. In the special case of a null ptr, arealloc degenerates to amalloc. A zero size causes the passed block to be freed. acalloc allocates space for an array of nelem elements of size elsize. The space is initialized to zeros. arecalloc combines arealloc and acalloc. If the size of the block increases, any new bytes are initialized to zero. Note that for this to work properly, all allocations of a given pointer must go through arecalloc. If the original pointer was allocated with either amalloc or arealloc some new bytes may not be set properly to zero. amemalign allocates size bytes on a specified alignment boundary, and returns a pointer to the allocated block. The value of the returned address is guaranteed to be an even multiple of align. Note: the value of align must be a power of two, and must be greater than or equal to the size of a word, or, for 64 bit objects, the size of a doubleword. amallocblksize returns the actual size of the block pointed to by ptr. The returned size may be greater than the original requested size due to padding and alignment. amallopt provides for control over the allocation algorithm. The available values for cmd are: M_MXFAST Set maxfast to value. The algorithm allocates all blocks at or below the size of maxfast in large groups and then doles them out very quickly. The default value for maxfast is 28. M_NLBLKS Set numlblks to value. The above mentioned ``large groups'' each contain numlblks blocks. numlblks must be greater than 0. The default value for numlblks is 100. M_GRAIN Set grain to value. Requests less than or equal to maxfast will have the size of a pointer added to them and be rounded up to the next multiple of grain. value will be rounded up to a multiple of the alignment size (16 bytes) when grain is set. grain must be greater than 0. The default value of grain is 16. M_KEEP Preserve data in a freed block until the next amalloc, arealloc, or acalloc. This option is provided only for compatibility with the old version of malloc and is not recommended. M_DEBUG Turns debug checking on if value is not equal to 0, otherwise turns debug checking off. When debugging is on, each call to amalloc and afree causes the entire malloc arena to be scanned and checked for consistency. This option may be invoked at any time. Note that when debug checking is on, the performance of amalloc is reduced considerably. M_BLKSZ When amalloc requires additional space, it uses sbrk(2) to allocate enough memory for the current amalloc request rounded up to a minimum size (default is 8K). The new size is set to value after it has been rounded up to the current block alignment. value must be at least 512 bytes. If a lot of space is to be allocated, setting the size larger can cut down on the system overhead. This option may be invoked at any time. M_MXCHK By default, amalloc trades off time versus space - if anywhere in the arena there is a block of the appropriate size, amalloc will find and return it. If the arena has become fragmented due to many amallocs and afrees, it is possible that amalloc will have to search through many blocks to find one of the appropriate size. If the arena is severely fragmented, the average amalloc time can be on the order of tens of milliseconds (as opposed to a normal average of tens of microseconds). This option allows the user to place a limit on the number of blocks that amalloc will search through before allocating a new block of space from the system. Small values (less than 50) can cause much more memory to be allocated. Values around 100 (the default) cause very uniform response time, with a small space penalty. This option may be invoked at any time. M_FREEHD When value is not zero, afree, arecalloc, and arealloc will place any freed memory in the front of the free list(s) instead of at the end (which is the default). Some applications will benefit in processing speed and space compaction by having freed memory placed at the beginning of the free list(s) (a zero value). M_CLRONFREE With this option, all blocks that are freed are set to value. This option may be set at any time, but there is no way to turn it off. That part of the beginning of a freed block which is used for internal pointers will of course not be set to value. M_CRLOCK Instructs the arena to do whatever is necessary to make it MP- safe. This is equivalent to passing the MEM_SHARED option to acreate but may be done at any time. It is used by usinit(3P) to initialize the arena it uses to honor usmalloc calls. These values are defined in the <malloc.h> header file. amallopt may be called repeatedly, but, for most commands, may not be called after the first small block is allocated. amallinfo provides instrumentation describing space usage. It returns the structure: struct mallinfo { int arena; /* total space in arena */ int ordblks; /* number of ordinary blocks */ int smblks; /* number of small blocks */ int hblkhd; /* space in holding block headers */ int hblks; /* number of holding blocks */ int usmblks; /* space in small blocks in use */ int fsmblks; /* space in free small blocks */ int uordblks; /* space in ordinary blocks in use */ int fordblks; /* space in free ordinary blocks */ int keepcost; /* space penalty if keep option */ /* is used */ } This structure is defined in the <malloc.h> header file. The structure is zero until after the first space has been allocated from the arena. Each of the allocation routines returns a pointer to space suitably aligned (after possible pointer coercion) for storage of any type of object. SEE ALSO brk(2), malloc(3X), usinit(3P), usnewlock(3P), usmalloc(3P). DIAGNOSTICS acreate will return NULL and set errno if either len is less than 1K or the MEM_SHARED flag is passed but ushdr is NULL. amalloc, arecalloc, amemalign, arealloc and acalloc return a NULL pointer if there is not enough available memory. On the first call to amalloc, arecalloc, arealloc, or acalloc -1 may be returned and errno set if the MEM_SHARED flag is set and it is impossible to allocate a lock. When arealloc or arecalloc returns NULL, the block pointed to by ptr is left intact. If amallopt is called after any allocation (for most cmd arguments) or if cmd or value are invalid, non-zero is returned. Otherwise, it returns zero. Page 5