]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
b3dcf58e | 2 | /*** |
b3dcf58e MS |
3 | Copyright 2010-2014 Lennart Poettering |
4 | Copyright 2014 Michal Schmidt | |
b3dcf58e MS |
5 | ***/ |
6 | ||
11c3a366 TA |
7 | #include <stdint.h> |
8 | #include <stdlib.h> | |
9 | ||
b3dcf58e | 10 | #include "macro.h" |
cf0fbc49 | 11 | #include "mempool.h" |
b3dcf58e MS |
12 | #include "util.h" |
13 | ||
14 | struct pool { | |
15 | struct pool *next; | |
da6053d0 LP |
16 | size_t n_tiles; |
17 | size_t n_used; | |
b3dcf58e MS |
18 | }; |
19 | ||
20 | void* mempool_alloc_tile(struct mempool *mp) { | |
da6053d0 | 21 | size_t i; |
b3dcf58e MS |
22 | |
23 | /* When a tile is released we add it to the list and simply | |
24 | * place the next pointer at its offset 0. */ | |
25 | ||
26 | assert(mp->tile_size >= sizeof(void*)); | |
27 | assert(mp->at_least > 0); | |
28 | ||
29 | if (mp->freelist) { | |
30 | void *r; | |
31 | ||
32 | r = mp->freelist; | |
33 | mp->freelist = * (void**) mp->freelist; | |
34 | return r; | |
35 | } | |
36 | ||
37 | if (_unlikely_(!mp->first_pool) || | |
38 | _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) { | |
da6053d0 | 39 | size_t size, n; |
b3dcf58e MS |
40 | struct pool *p; |
41 | ||
42 | n = mp->first_pool ? mp->first_pool->n_tiles : 0; | |
43 | n = MAX(mp->at_least, n * 2); | |
44 | size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size); | |
45 | n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size; | |
46 | ||
47 | p = malloc(size); | |
48 | if (!p) | |
49 | return NULL; | |
50 | ||
51 | p->next = mp->first_pool; | |
52 | p->n_tiles = n; | |
53 | p->n_used = 0; | |
54 | ||
55 | mp->first_pool = p; | |
56 | } | |
57 | ||
58 | i = mp->first_pool->n_used++; | |
59 | ||
60 | return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size; | |
61 | } | |
62 | ||
52fc5ce3 MS |
63 | void* mempool_alloc0_tile(struct mempool *mp) { |
64 | void *p; | |
65 | ||
66 | p = mempool_alloc_tile(mp); | |
67 | if (p) | |
68 | memzero(p, mp->tile_size); | |
69 | return p; | |
70 | } | |
71 | ||
b3dcf58e MS |
72 | void mempool_free_tile(struct mempool *mp, void *p) { |
73 | * (void**) p = mp->freelist; | |
74 | mp->freelist = p; | |
75 | } | |
76 | ||
d18cb393 | 77 | #if VALGRIND |
b3dcf58e MS |
78 | |
79 | void mempool_drop(struct mempool *mp) { | |
80 | struct pool *p = mp->first_pool; | |
81 | while (p) { | |
82 | struct pool *n; | |
83 | n = p->next; | |
84 | free(p); | |
85 | p = n; | |
86 | } | |
87 | } | |
88 | ||
89 | #endif |