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