Repository: incubator-mynewt-site Updated Branches: refs/heads/os_mempool [created] 9cc22d92e
MYNEWT-162: documentation for os memory pools Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/commit/6afd1393 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/tree/6afd1393 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/diff/6afd1393 Branch: refs/heads/os_mempool Commit: 6afd13930733b1b8ccedb28a83df1989b91120e9 Parents: 97d68dc Author: wes3 <w...@micosa.io> Authored: Wed Feb 24 22:23:12 2016 -0800 Committer: wes3 <w...@micosa.io> Committed: Wed Feb 24 22:23:12 2016 -0800 ---------------------------------------------------------------------- docs/os/core_os/memory_pool/OS_MEMPOOL_BYTES.md | 15 +++--- docs/os/core_os/memory_pool/memory_pool.md | 48 ++++++++++++++++---- docs/os/core_os/memory_pool/os_memblock_put.md | 18 ++++---- docs/os/core_os/memory_pool/os_mempool_init.md | 20 ++++---- mkdocs.yml | 1 + 5 files changed, 68 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/6afd1393/docs/os/core_os/memory_pool/OS_MEMPOOL_BYTES.md ---------------------------------------------------------------------- diff --git a/docs/os/core_os/memory_pool/OS_MEMPOOL_BYTES.md b/docs/os/core_os/memory_pool/OS_MEMPOOL_BYTES.md index b08fdea..94b7a82 100644 --- a/docs/os/core_os/memory_pool/OS_MEMPOOL_BYTES.md +++ b/docs/os/core_os/memory_pool/OS_MEMPOOL_BYTES.md @@ -6,7 +6,7 @@ OS_MEMPOOL_BYTES(n,blksize) Calculates how many bytes of memory is used by *n* number of elements, when individual element size is *blksize* bytes. - +<br> #### Arguments | Arguments | Description | @@ -15,22 +15,21 @@ Calculates how many bytes of memory is used by *n* number of elements, when indi | blksize | Size of an element is number of bytes | #### Returned values +The number of bytes used by the memory pool. -List any values returned. -Error codes? - +<br> #### Notes +OS_MEMPOOL_BYTES is a macro and not a function. - +<br> #### Example Here we allocate memory to be used as a pool. ```no-highlight -void *nffs_file_mem; + void *nffs_file_mem; -nffs_file_mem = malloc( - OS_MEMPOOL_BYTES(nffs_config.nc_num_files, sizeof (struct nffs_file))); + nffs_file_mem = malloc(OS_MEMPOOL_BYTES(nffs_config.nc_num_files, sizeof (struct nffs_file))); if (nffs_file_mem == NULL) { return FS_ENOMEM; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/6afd1393/docs/os/core_os/memory_pool/memory_pool.md ---------------------------------------------------------------------- diff --git a/docs/os/core_os/memory_pool/memory_pool.md b/docs/os/core_os/memory_pool/memory_pool.md index 25d0554..def6462 100644 --- a/docs/os/core_os/memory_pool/memory_pool.md +++ b/docs/os/core_os/memory_pool/memory_pool.md @@ -1,35 +1,66 @@ # Memory Pools -Memory can be pre-allocated to a pool of fixed size elements. +A memory pool is a collection of fixed sized elements called memory blocks. Generally, memory pools are used when the developer wants to allocate a certain amount of memory to a given feature. Unlike the heap, where a code module is at the mercy of other code modules to insure there is sufficient memory, memory pools can insure sufficient memory allocation. ## Description -Sometimes it's useful to have several memory blocks of same size preallocated for specific use. E.g. you want to limit the amount of memory used for it, or you want to make sure that there is memory available when you ask for it. +In order to create a memory pool the developer needs to do a few things. The first task is to define the memory pool itself. This is a data structure which contains information about the pool itself (i.e. number of blocks, size of the blocks, etc). -This can be done using a memory pool. You allocate memory either statically or from heap, and then designate that memory to be used as storage for fixed size elements. +```no-highlight +struct os_mempool my_pool; +``` +<br> +The next order of business is to allocate the memory used by the memory pool. This memory can either be statically allocated (i.e. a global variable) or dynamically allocated (i.e. from the heap). When determining the amount of memory required for the memory pool, simply multiplying the number of blocks by the size of each block is not sufficient as the OS may have alignment requirements. The alignment size definition is named `OS_ALIGNMENT` and can be found in os_arch.h as it is architecture specific. The memory block alignment is usually for efficiency but may be due to other reasons. Generally, blocks are aligned on 32-bit boundaries. Note that memory blocks must also be of sufficient size to hold a list pointer as this is needed to chain memory blocks on the free list. -Pool will be initialized by calling *os_mempool_init()*. Element can be allocated from it with *os_mempool_get()*, and released back with *os_mempool_put()*. +In order to simplify this for the user two macros have been provided: `OS_MEMPOOL_BYTES(n, blksize)` and `OS_MEMPOOL_SIZE(n, blksize)`. The first macro returns the number of bytes needed for the memory pool while the second returns the number of `os_membuf_t` elements required by the memory pool. The `os_membuf_t` type is used to guarantee that the memory buffer used by the memory pool is aligned on the correct boundary. -## Data structures +Here are some examples. Note that if a custom malloc implementation is used it must guarantee that the memory buffer used by the pool is allocated on the correct boundary (i.e. OS_ALIGNMENT). + +```no-highlight +void *my_memory_buffer; +my_memory_buffer = malloc(OS_MEMPOOL_BYTES(NUM_BLOCKS, BLOCK_SIZE)); +``` ```no-highlight +os_membuf_t my_memory_buffer[OS_MEMPOOL_SIZE(NUM_BLOCKS, BLOCK_SIZE)]; +``` +<br> +Now that the memory pool has been defined as well as the memory required for the memory blocks which make up the pool the user needs to initialize the memory pool by calling `os_mempool_init`. + +```no-highlight +os_mempool_init(&my_pool, NUM_BLOCKS, BLOCK_SIZE, my_memory_buffer, + "MyPool"); +``` +<br> +Once the memory pool has been initialized the developer can allocate memory blocks from the pool by calling `os_memblock_get`. When the memory block is no longer needed the memory can be freed by calling `os_memblock_put`. + +## Data structures +```no-highlight struct os_mempool { int mp_block_size; int mp_num_blocks; int mp_num_free; + uint32_t mp_membuf_addr; + STAILQ_ENTRY(os_mempool) mp_list; SLIST_HEAD(,os_memblock); char *name; }; ``` -| Element | Description | +<br> + +| **Element** | **Description** | |-----------|-------------| -| mp_block_size | Size of the memory blocks, in bytes | +| mp_block_size | Size of the memory blocks, in bytes. This is not the actual number of bytes used by each block; it is the requested size of each block. The actual memory block size will be aligned to OS_ALIGNMENT bytes | | mp_num_blocks | Number of memory blocks in the pool | | mp_num_free | Number of free blocks left | +| mp_membuf_addr | The address of the memory block. This is used to check that a valid memory block is being freed. | +| mp_list | List pointer to chain memory pools so they can be displayed by newt tools | +| SLIST_HEAD(,os_memblock) | List pointer to chain free memory blocks | | name | Name for the memory block | - + + ## List of Functions The functions available in mem_pool are: @@ -38,5 +69,6 @@ The functions available in mem_pool are: * [os_mempool_init](os_mempool_init) * [os_memblock_put](os_memblock_put) * [OS_MEMPOOL_BYTES](OS_MEMPOOL_BYTES) +* [OS_MEMPOOL_SIZE](OS_MEMPOOL_SIZE) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/6afd1393/docs/os/core_os/memory_pool/os_memblock_put.md ---------------------------------------------------------------------- diff --git a/docs/os/core_os/memory_pool/os_memblock_put.md b/docs/os/core_os/memory_pool/os_memblock_put.md index a790cab..9f9339b 100644 --- a/docs/os/core_os/memory_pool/os_memblock_put.md +++ b/docs/os/core_os/memory_pool/os_memblock_put.md @@ -4,25 +4,23 @@ os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr) ``` -Releases previously allocated element back to the pool. - +Releases previously allocated element back to the pool. +<br> #### Arguments | Arguments | Description | |-----------|-------------| -| mp | Pointer to memory pool where element is put | +| mp | Pointer to memory pool from which block was allocated | | block_addr | Pointer to element getting freed | +<br> #### Returned values -OS_OK: operation was a success: -OS_INVALID_PARAM: If either mp or block_addr were NULL. - -#### Notes - - +OS_OK: operation was a success: +OS_INVALID_PARAM: If either mp or block_addr were NULL, or the block being freed was outside the range of the memory buffer or not on a true block size boundary. +<br> #### Example <Add text to set up the context for the example here> @@ -31,7 +29,7 @@ OS_INVALID_PARAM: If either mp or block_addr were NULL. if (file != NULL) { rc = os_memblock_put(&nffs_file_pool, file); if (rc != 0) { - return FS_EOS; + /* Error freeing memory block */ } } ``` http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/6afd1393/docs/os/core_os/memory_pool/os_mempool_init.md ---------------------------------------------------------------------- diff --git a/docs/os/core_os/memory_pool/os_mempool_init.md b/docs/os/core_os/memory_pool/os_mempool_init.md index 33a7f66..9ab7d3d 100644 --- a/docs/os/core_os/memory_pool/os_mempool_init.md +++ b/docs/os/core_os/memory_pool/os_mempool_init.md @@ -4,7 +4,7 @@ os_error_t os_mempool_init(struct os_mempool *mp, int blocks, int block_size, void *membuf, char *name) ``` -Initializes the memory pool. Memory pointed by *membuf* is taken and *blocks* number of elements of size *block_size* are added to the pool. *name* is optional, and names the memory pool. +Initializes the memory pool. Memory pointed to by *membuf* is divided into *blocks* number of elements of size OS_ALIGN(*block_size*). The *name* is optional, and names the memory pool. It is assumed that the amount of memory pointed by *membuf* has at least *OS_MEMPOOL_BYTES(blocks, block_size)* number of bytes. @@ -16,32 +16,36 @@ It is assumed that the amount of memory pointed by *membuf* has at least *OS_MEM |-----------|-------------| | mp | Memory pool being initialized | | blocks | Number of elements in the pool | -| block_size | Size of an individual element in pool | +| block_size | Minimum size of an individual element in pool | | membuf | Backing store for the memory pool elements | | name | Name of the memory pool | #### Returned values -OS_OK: operation was successful. -OS_INVALID_PARAM: invalid parameters. Block count or block size was negative, or membuf or mp was NULL. -OS_MEM_NOT_ALIGNED: membuf has to be aligned to 4 byte boundary. +OS_OK: operation was successful. +OS_INVALID_PARAM: invalid parameters. Block count or block size was negative, or membuf or mp was NULL. +OS_MEM_NOT_ALIGNED: membuf was not aligned on correct byte boundary. #### Notes -Note that os_mempool_init() does not allocate backing storage. *membuf* has to be allocated by the caller. +Note that os_mempool_init() does not allocate backing storage; *membuf* has to be allocated by the caller. -It's recommended that you use *OS_MEMPOOL_BYTES()* to figure out how much memory to allocate for the pool. +It's recommended that you use *OS_MEMPOOL_BYTES()* or *OS_MEMPOOL_SIZE()* to figure out how much memory to allocate for the pool. #### Example <Add text to set up the context for the example here> ```no-highlight + void *nffs_file_mem; + + nffs_file_mem = malloc(OS_MEMPOOL_BYTES(nffs_config.nc_num_files, sizeof (struct nffs_file))); + rc = os_mempool_init(&nffs_file_pool, nffs_config.nc_num_files, sizeof (struct nffs_file), nffs_file_mem, "nffs_file_pool"); if (rc != 0) { - return FS_EOS; + /* Memory pool initialization failure */ } ``` http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/6afd1393/mkdocs.yml ---------------------------------------------------------------------- diff --git a/mkdocs.yml b/mkdocs.yml index 80b533f..d0d84f5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,6 +79,7 @@ pages: - 'os_mempool_init': 'os/core_os/memory_pool/os_mempool_init.md' - 'os_memblock_put': 'os/core_os/memory_pool/os_memblock_put.md' - 'OS_MEMPOOL_BYTES': 'os/core_os/memory_pool/OS_MEMPOOL_BYTES.md' + - 'OS_MEMPOOL_SIZE': 'os/core_os/memory_pool/OS_MEMPOOL_SIZE.md' - Heap: - 'Overview': 'os/core_os/heap/heap.md' - 'Functions':