HM Memory Pool Design (1) Memory Pool Design

Source: Internet
Author: User

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 );}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.