Skip to content

Commit 158dfef

Browse files
jamillgitster
authored andcommitted
mem-pool: add life cycle management functions
Add initialization and discard functions to mem_pool type. As the memory allocated by mem_pool can now be freed, we also track the large allocations. If the there are existing mp_blocks in the mem_poo's linked list of mp_blocksl, then the mp_block for a large allocation is inserted behind the head block. This is because only the head mp_block is considered when searching for availble space. This results in the following desirable properties: 1) The mp_block allocated for the large request will not be included not included in the search for available in future requests, the large mp_block is sized for the specific request and does not contain any spare space. 2) The head mp_block will not bumped from considation for future memory requests just because a request for a large chunk of memory came in. These changes are in preparation for a future commit that will utilize creating and discarding memory pool. Signed-off-by: Jameson Miller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8fb8e3f commit 158dfef

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

mem-pool.c

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,65 @@
55
#include "cache.h"
66
#include "mem-pool.h"
77

8-
static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool, size_t block_alloc)
8+
#define BLOCK_GROWTH_SIZE 1024*1024 - sizeof(struct mp_block);
9+
10+
/*
11+
* Allocate a new mp_block and insert it after the block specified in
12+
* `insert_after`. If `insert_after` is NULL, then insert block at the
13+
* head of the linked list.
14+
*/
15+
static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool, size_t block_alloc, struct mp_block *insert_after)
916
{
1017
struct mp_block *p;
1118

1219
mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc;
1320
p = xmalloc(st_add(sizeof(struct mp_block), block_alloc));
14-
p->next_block = mem_pool->mp_block;
21+
1522
p->next_free = (char *)p->space;
1623
p->end = p->next_free + block_alloc;
17-
mem_pool->mp_block = p;
24+
25+
if (insert_after) {
26+
p->next_block = insert_after->next_block;
27+
insert_after->next_block = p;
28+
} else {
29+
p->next_block = mem_pool->mp_block;
30+
mem_pool->mp_block = p;
31+
}
1832

1933
return p;
2034
}
2135

36+
void mem_pool_init(struct mem_pool **mem_pool, size_t initial_size)
37+
{
38+
struct mem_pool *pool;
39+
40+
if (*mem_pool)
41+
return;
42+
43+
pool = xcalloc(1, sizeof(*pool));
44+
45+
pool->block_alloc = BLOCK_GROWTH_SIZE;
46+
47+
if (initial_size > 0)
48+
mem_pool_alloc_block(pool, initial_size, NULL);
49+
50+
*mem_pool = pool;
51+
}
52+
53+
void mem_pool_discard(struct mem_pool *mem_pool)
54+
{
55+
struct mp_block *block, *block_to_free;
56+
57+
while ((block = mem_pool->mp_block))
58+
{
59+
block_to_free = block;
60+
block = block->next_block;
61+
free(block_to_free);
62+
}
63+
64+
free(mem_pool);
65+
}
66+
2267
void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
2368
{
2469
struct mp_block *p = NULL;
@@ -33,12 +78,10 @@ void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
3378
p = mem_pool->mp_block;
3479

3580
if (!p) {
36-
if (len >= (mem_pool->block_alloc / 2)) {
37-
mem_pool->pool_alloc += len;
38-
return xmalloc(len);
39-
}
81+
if (len >= (mem_pool->block_alloc / 2))
82+
return mem_pool_alloc_block(mem_pool, len, mem_pool->mp_block);
4083

41-
p = mem_pool_alloc_block(mem_pool, mem_pool->block_alloc);
84+
p = mem_pool_alloc_block(mem_pool, mem_pool->block_alloc, NULL);
4285
}
4386

4487
r = p->next_free;

mem-pool.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ struct mem_pool {
2121
size_t pool_alloc;
2222
};
2323

24+
/*
25+
* Initialize mem_pool with specified initial size.
26+
*/
27+
void mem_pool_init(struct mem_pool **mem_pool, size_t initial_size);
28+
29+
/*
30+
* Discard a memory pool and free all the memory it is responsible for.
31+
*/
32+
void mem_pool_discard(struct mem_pool *mem_pool);
33+
2434
/*
2535
* Alloc memory from the mem_pool.
2636
*/

0 commit comments

Comments
 (0)