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