# Using Private Memory Lists

If you have dynamic components running and allocating memory, it may be necessary to limit the amount of memory certain threads can use. You can create a private memory for those threads, memory list. Those threads would only allocate memory from this list and since you can control the total amount of memory in the private memory list, you can control the maximum amount of memory that certain threads can allocate.

## Creating a Private Memory List

You can create a private memory list by calling the `AllocMemList()` function:

  `MemList *AllocMemList( const void *p, const char *name )`

The `p` argument is a pointer to a memory address of the type of memory (either DRAM or VRAM) you want to store in the list. A single memory list can store either DRAM or VRAM, but not both. You use the `name` argument to name the memory list. The return value is a pointer to the resulting MemList structure, or NULL if an error occurred.

## Adding Memory to a Private Memory List

Initially, the memory list you create with `AllocMemList()` is empty. To add memory to the list, use the `FreeMemToMemList()` function:

  `void FreeMemToMemList( MemList *ml, void *p, int32 size )`

The `ml` argument is a pointer to the memory list from which to free the memory. The `p` argument is a pointer to the memory to free. The memory block must be properly aligned in position and size for the type of memory being manipulated. The alignment granularity can be determined with `GetMemAllocAlignment()`. The number returned by this function indicates the alignment needed for the pointer; the size of the memory block being freed must also be a multiple of this value. Your task must already own this memory. The type of the memory to free must be the same as the type specified in the p argument of `AllocMemList().` The `size` argument specifies the amount of memory to move the free list, in bytes. You can move a block of any size to the free list.

## Allocating Memory From a Private Memory List

Once you've created a private memory list and put memory into it, you can allocate memory from the list with the `AllocMemFromMemList()` function:

  `void *AllocMemFromMemList( MemList *ml, int32 size, uint32 memFlags )`

The `ml` argument is a pointer to the memory list from which to allocate the memory. The `size` argument specifies the size of the block to allocate, in bytes. The `memtype` argument contains flags that specify the type of memory to allocate, the alignment of the block with respect to the page, and so on; these flags can include `MEMTYPE_ANY, MEMTYPE_VRAM`, `MEMTYPE_DRAM, MEMTYPE_BANKSELECT`, `MEMTYPE_BANK1`, `MEMTYPE_BANK2`, `MEMTYPE_DMA`, `MEMTYPE_CEL`,`MEMTYPE_AUDIO`, `MEMTYPE_DSP`, `MEMTYPE_FILL`, `MEMTYPE_INPAGE`, `MEMTYPE_STARTPAGE`, `MEMTYPE_SYSTEMPAGESIZE`, and `MEMTYPE_MYPOOL`. Note that the flags that specify the actual memory type (such as `MEMTYPE_DRAM`) must match the type of the memory contained in the list. For complete descriptions of these flags, see Allocating a Memory Block. The function returns a pointer to the block that was allocated or NULL if there was not enough memory in the list to satisfy the request.

To free memory that you've allocated with `AllocMemFromMemList(),` you must use only `FreeMemToMemList()` (described in the next section). Each memory allocation function has a corresponding deallocation function; if you use another memory allocation function, you must use its corresponding deallocation function.

## Freeing Memory to a Private Memory List

To free a block of memory that you've allocated from a private memory list and return it to the list, you use the `FreeMemToMemList()` function:

  `void FreeMemToMemList( MemList *ml, void *p, int32 size )`

The `ml` argument is a pointer to the memory list from which the block was allocated. The `p` argument is a pointer to the block to free. The `size` argument specifies the size of the block to free, in bytes.

## Deallocating a Private Memory List

To deallocate a private memory list, you first empty it (using `ControlMem()` to return the memory pages to the kernel, as described in Transferring Memory to Other Tasks) and then use the `FreeMemList()` function:

  `void FreeMemList( MemList *ml )`

The `ml` argument is a pointer to the memory list to deallocate. If the list is not empty, any memory it contains is lost.

## Sharing Private Memory Lists Among Threads

To use a single memory list from multiple independent threads, there must be extra protection so the threads don't corrupt the shared data structure. To share a memory list, you must attach a semaphore item to the MemList structure. This is done by creating a semaphore item and putting its Item number in the `meml_Sema4` field of the MemList structure.