Comprehensive reference
A. c ++ application performance optimization, Chapter 6th: Memory Pool
Http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html
And
B. Design of ARP memory pool. Http://www.cnblogs.com/bangerlee/archive/2011/09/01/2161437.html
1. memblock
Typedef struct memblock {uint32_tindex; // sizeuint32_tnfree; // the minimum number of available memory units uint32_tnfirst; // The next smallest available memory unit number struct memblock * pnextblock; // The next memblock with the same index value # ifdef mem_analysisuint32_tmax_used; // The maximum number of chunks used # endif} memblock;
The memblock structure is similar to the structure of a.. The index is derived from the index in ARP. A memblock consists of memblock + nfree chunk memory units.
The chunk size is boundary_size * (index + 1) bytes. The address of the memblock is recorded in the first 4 bytes of each chunk (if there is no pnextblock, you can directly useObtained by index, or calculated by address range),
5-8 bytes to store the ID of the next available chunk.
Then it adds the struct memblock * pnextblock; pointer. When nfree is 0 or the memblock of the index is no longer available for chunk, malloc adds a new memblock and hangs it behind it (one-way linked list ).
2. memblok management mempool
Typedef struct mempool
{
Memblock * freeblock [max_index];
Char * pmemory;
} Mempool;
Pmemory points to the allocated entire large memory pool, and freeblock [I] points to the memblock whose index is I.
Source code:
/* ===================================================== ============================================================ Name: mempool. h Author: MLJ version: 0.1 ============================================== =============================================== */# ifndef mempool _ # define mempool _ # include <stdint. h> # define mem_analysis // calculate memory information # define max_index 20 typedef struct memblock {uint32_tindex; // sizeuint32_tnfree; // The number of available minimum memory units uint32_tnfirst; // The next minimum available memory unit number struct memblock * pnextblock; // The next memblock with the same index value # ifdef mem_analysisuint32_tmax_used; // The maximum number of chunks used to reach # endif} memblock; typedef struct mempool {memblock * freeblock [max_index]; char * pmemory;} mempool; # endif
/* ===================================================== ============================================================ Name: mempool. c Author: MLJ version: 0.1 ============================================== =============================================== */# include <stdio. h> # include <stdlib. h> # include <memory. h> # include "mempool. H "char max_free_chunk [max_index] = {, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0}; mempool mypool; # define boundary_index 12 # Define boundary_size (1 <boundary_index) # define chunk_head_size (sizeof (memblock *) + sizeof (uint32_t) # define chunk_data_size (INDEX) (size_t) boundary_size * (index + 1) // 4096*(1 <19) the default value is int type, and the value is out of the range # define memblock_size (INDEX) (sizeof (memblock) + max_free_chunk [(INDEX)] * (chunk_head_size + chunk_data_size (INDEX) # define apr_align (size, boundary) (size) + (Boundary)-1 )) &~ (Boundary)-1) void memblock_init (memblock * block, uint32_t max_free_chunk) {uint32_t I = 0; char * P = NULL; block-> nfree = max_free_chunk; block-> nfirst = 0; block-> pnextblock = NULL; # ifdef mem_analysisblock-> max_used = 0; # endifp = (char *) block; (char *) P) + = sizeof (memblock); // 0th chunk header addresses for (I = 0; I <block-> nfree; I ++) {(* (memblock **) p) = (memblock *) block; // address of the memblock where the chunk header contains four bytes (char *) P) + = Si Zeof (memblock *); * (uint32_t *) P) = I + 1; // stores the index (char *) P) of the next available chunk in 5-8 bytes) + = sizeof (uint32_t) + chunk_data_size (Block-> index) ;}} void mempool_create (mempool * Pool) {size_t pool_size = 0; // size_t I; char * P = NULL; for (I = 0; I <max_index; I ++) {pool_size + = memblock_size (I);} p = (char *) malloc (pool_size); If (P = NULL) {printf ("memory malloc failed! /N "); exit (0);} memset (p, 0, pool_size); pool-> pmemory = P; for (I = 0; I <max_index; I ++) {pool-> freeblock [I] = (memblock *) (p); pool-> freeblock [I]-> Index = I; memblock_init (pool-> freeblock [I], max_free_chunk [I]); (char *) P) + = memblock_size (I ); // note that when converting to char * with an offset} void mempool_destroy (mempool * Pool) {size_t I; # ifdef mem_analysissize_t pool_size = 0; // max_free_chunk [19] Not 0, the data range of size_t is insufficient for (I = 0; I <max_index; I ++) {Po Ol_size + = memblock_size (I);} printf ("mempool analysis: \ n"); printf ("Total malloc memory size: % dkb % DM \ n ", pool_size> 10, pool_size> 20); printf ("index:"); for (I = 0; I <max_index/2; I ++) {printf ("% 4D", I) ;}printf ("\ nmax_used:"); for (I = 0; I <max_index/2; I ++) {memblock * pblock = NULL; uint32_t max_used = 0; pblock = mypool. freeblock [I]; do {max_used + = pblock-> max_used;} while (pblock = pblock-> pnextblock); printf ("% 4D ", Max_used);} printf (" \ nindex: "); for (I = max_index/2; I <max_index; I ++) {printf (" % 4D ", i);} printf ("\ nmax_used:"); for (I = max_index/2; I <max_index; I ++) {memblock * pblock = NULL; uint32_t max_used = 0; pblock = mypool. freeblock [I]; do {max_used + = pblock-> max_used;} while (pblock = pblock-> pnextblock); printf ("% 4D", max_used );} # endiffor (I = 0; I <max_index; I ++) {memblock * pblock = NULL; pblock = mypool. freeblock [I]; whil E (pblock-> pnextblock) {memblock * TMP = pblock-> pnextblock; pblock-> pnextblock = TMP-> pnextblock; free (TMP );}} free (pool> pmemory); pool-> pmemory = NULL;} void * mempool_malloc (size_t in_size) {size_t size; size_t index; size = apr_align (in_size, boundary_size ); if (size <in_size) {return NULL;} If (size <boundary_size) size = boundary_size;/* Find the index for this node size by * dividing its size By the boundary size */Index = (size> boundary_index)-1; if (index> max_index) {return NULL; // processing of memory larger than max_index} If (index <= max_index) {memblock * pblock = NULL; pblock = mypool. freeblock [Index]; // find the first blockdo with idle chunk in the block linked list {If (pblock-> nfree> 0) // locate and exit {break ;} else if (pblock-> pnextblock = NULL) // full, the next memblock does not exist {char * P = NULL; If (max_free_chunk [Index] = 0) {max_free_chunk [Index] = 1;} p = (char *) malloc (memblock_size (INDEX); If (P = NULL) {printf ("memory malloc failed! /N "); exit (0);} memset (p, 0, memblock_size (INDEX); pblock-> pnextblock = (memblock *) (p ); pblock-> pnextblock-> Index = index; pblock = pblock-> pnextblock; memblock_init (pblock, max_free_chunk [Index]); break ;} else {pblock = pblock-> pnextblock;} while (pblock); If (pblock-> nfree> 0) {uint32_t chunk_id = pblock-> nfirst; // idchar * pchunk = (char *) (pblock) + sizeof (memblock) + chunk_data_size (INDEX) * chunk_id of the chunk to be allocated; // The first address of the index chunk pchunk = pchunk + sizeof (memblock *); // four bytes are offset backward, point to the chunk ID area pblock-> nfirst = * (uint32_t *) pchunk); // update the ID of the next available chunk * (uint32_t *) pchunk) = chunk_id; // The allocated chunk. In the chunkid area, write down your idpblock-> nfree --; # ifdef mem_analysis {uint32_t used_chunk = max_free_chunk [Index]-pblock-> nfree; if (used_chunk> pblock-> max_used) {pblock-> max_used = used_chunk ;}# endifreturn (char *) pchunk + sizeof (uint32_t ));} else {return NULL ;}} return NULL;} void mempool_free (void * _ memory) {memblock * pblock = NULL; pblock = * (memblock **) (char *) _ memory-chunk_head_size); // obtain the chunk block address if (pblock-> index <= max_index) {// The released Chunk is mounted to the top, the first available chunkuint32_t chunk_id = pblock-> nfirst; char * poffset = (char *) _ memory-sizeof (uint32_t )); // chunk_id address pblock-> nfirst = * (uint32_t *) (poffset); * (uint32_t *) (poffset) = chunk_id; memset (_ memory, 0, chunk_data_size (pblock-> index); // data Zone 0 }}int main () {char * P1 [10]; int I; mempool_create (& mypool ); for (I = 0; I <6; I ++) {p1 [I] = (char *) mempool_malloc (1024 <I) ;}for (I = 0; I <6; I ++) {mempool_free (P1 [I]); P1 [I] = NULL;} mempool_destroy (& mypool );}