### _ucreate -- Create a Memory Heap

Format

>     #include <umalloc.h>
>     Heap_t _ucreate(void *block, size_t initsz, int clean, int memtype,
>                      void *(*getmore_fn)(Heap_t, size_t *, int *)
>                      void  (*release_fn)(Heap_t, void *, size_t);

Language Level: Extension
_ucreate creates your own memory heap that you can allocate and free memory from, just like the IBM C and C++ Compilers runtime heap.

On OS/2, before you call _ucreate, you must first get the initial block of memory for the heap. You can get this block by calling an OS/2 API (such as DosAllocMem or DosAllocSharedMem ) or by statically allocating it. For more details on the OS/2 APIs, see the Control Program Guide and Reference.

For Windows, before you call _ucreate, you must first get the initial block of memory for the heap. You can get this block by calling a Win32 API (such as VirtualAlloc or CreateFileMapping) or by statically allocating it. If required by the application, shared memory must be explicitly mapped by you to the same address in all processes sharing the memory. When the heaps are user-defined, you must explicitly map shared memory. For more details on the Win32 APIs, see the Win32 Programmer's Reference.

Note: You must also return this initial block of memory to the system after you destroy the heap.

When you call _ucreate, you pass it the following parameters:

block | The pointer to the initial block you obtained.
initsz | The size of the initial block, which must be at least _HEAP_MIN_SIZE bytes (defined in <malloc.h>). If you are creating a fixed-size heap, the size must be large enough to satisfy all memory requests your program will make of it.
clean | The macro _BLOCK_CLEAN, if the memory in the block has been initialized to 0, or !_BLOCK_CLEAN, if the memory has not been touched. This improves the efficiency of _ucalloc; if the memory is already initialized to 0, _ucalloc does not need to initialize it. Note: VirtualAlloc and DosAllocMem initialize memory to 0 for you. You can also use memset to initialize the memory; however, memset also commits all the memory at once, an action that could slow overall performance.
memtype | A macro indicating the type of memory in your heap: _HEAP_REGULAR (regular), also, for OS/2, _HEAP_TILED (tiled). If you want the memory to be shared, specify _HEAP_SHARED as well (for example, _HEAP_REGULAR | _HEAP_SHARED). Shared memory can be shared between different processes. Note: Make sure that when you get the initial block, you request the same type of memory that you specify for memtype.
getmore_fn | A function you provide to get more memory from the system (typically using OS/2 or Windows APIs or static allocation). To create a fixed-size heap, specify NULL for this parameter.
release_fn | A function you provide to return memory to the system. To create a fixed-size heap, specify NULL for this parameter.

If you create a fixed-size heap, the initial block of memory must be large enough to satisfy all allocation requests made to it. Once the block is fully allocated, further allocation requests to the heap will fail. If you create an expandable heap, the getmore_fn and release_fn allow your heap to expand and shrink dynamically.

When you call _umalloc (or a similar function) for your heap, if not enough memory is available in the block, it calls the getmore_fn you provide. Your getmore_fn then gets more memory from the system and adds it to the heap, using any method you choose.

Your getmore_fn must have the following prototype:

> `void *(*getmore_fn)(Heap_t uh, size_t *size, int *clean);`

where:

uh | Is the heap to get memory for.
size | Is the size of the allocation request passed by _umalloc. You probably want to return enough memory at a time to satisfy several allocations; otherwise, every subsequent allocation has to call getmore_fn. You should return multiples of 64K (the smallest size that VirtualAlloc or DosAllocMem returns). Make sure you update the size parameter if you return more than the original request.
clean | Within getmore_fn, you must set this variable either to _BLOCK_CLEAN, to indicate that you initialized the memory to 0, or to !_BLOCK_CLEAN, to indicate that the memory is untouched.

Note: Make sure your getmore_fn allocates the right type of memory for the heap.

When you call _uheapmin to coalesce the heap or _udestroy to destroy it, these functions call the release_fn you provide to return the memory to the system.

Your release_fn must have the following prototype:

       void (*release_fn)(Heap_t uh, void *block, size_t size);

The heap uh, the block to be returned, and its size are passed to release_fn by _uheapmin or _udestroy.

Return Value
If successful, _ucreate returns a pointer to the heap created. If errors occur, _ucreate returns NULL.

Example

Example

Memory Management

_uaddmem -- Add Memory to a Heap
_ucalloc -- Reserve and Initialize Memory from User Heap
_uclose -- Close Heap from Use
_udestroy -- Destroy a Heap
_uheapmin -- Release Unused Memory in User Heap
_umalloc -- Reserve Memory Blocks from User Heap
_uopen -- Open Heap for Use
<umalloc.h>