/src/systemd/src/basic/mempool.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | | |
3 | | #include <stdint.h> |
4 | | #include <stdlib.h> |
5 | | |
6 | | #include "env-util.h" |
7 | | #include "macro.h" |
8 | | #include "memory-util.h" |
9 | | #include "mempool.h" |
10 | | #include "process-util.h" |
11 | | #include "util.h" |
12 | | |
13 | | struct pool { |
14 | | struct pool *next; |
15 | | size_t n_tiles; |
16 | | size_t n_used; |
17 | | }; |
18 | | |
19 | 1.44M | void* mempool_alloc_tile(struct mempool *mp) { |
20 | 1.44M | size_t i; |
21 | 1.44M | |
22 | 1.44M | /* When a tile is released we add it to the list and simply |
23 | 1.44M | * place the next pointer at its offset 0. */ |
24 | 1.44M | |
25 | 1.44M | assert(mp->tile_size >= sizeof(void*)); |
26 | 1.44M | assert(mp->at_least > 0); |
27 | 1.44M | |
28 | 1.44M | if (mp->freelist) { |
29 | 1.42M | void *r; |
30 | 1.42M | |
31 | 1.42M | r = mp->freelist; |
32 | 1.42M | mp->freelist = * (void**) mp->freelist; |
33 | 1.42M | return r; |
34 | 1.42M | } |
35 | 13.4k | |
36 | 13.4k | if (_unlikely_(!mp->first_pool) || |
37 | 13.4k | _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) { |
38 | 25 | size_t size, n; |
39 | 25 | struct pool *p; |
40 | 25 | |
41 | 25 | n = mp->first_pool ? mp->first_pool->n_tiles : 0; |
42 | 25 | n = MAX(mp->at_least, n * 2); |
43 | 25 | size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size); |
44 | 25 | n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size; |
45 | 25 | |
46 | 25 | p = malloc(size); |
47 | 25 | if (!p) |
48 | 0 | return NULL; |
49 | 25 | |
50 | 25 | p->next = mp->first_pool; |
51 | 25 | p->n_tiles = n; |
52 | 25 | p->n_used = 0; |
53 | 25 | |
54 | 25 | mp->first_pool = p; |
55 | 25 | } |
56 | 13.4k | |
57 | 13.4k | i = mp->first_pool->n_used++; |
58 | 13.4k | |
59 | 13.4k | return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size; |
60 | 13.4k | } |
61 | | |
62 | 1.44M | void* mempool_alloc0_tile(struct mempool *mp) { |
63 | 1.44M | void *p; |
64 | 1.44M | |
65 | 1.44M | p = mempool_alloc_tile(mp); |
66 | 1.44M | if (p) |
67 | 1.44M | memzero(p, mp->tile_size); |
68 | 1.44M | return p; |
69 | 1.44M | } |
70 | | |
71 | 1.44M | void mempool_free_tile(struct mempool *mp, void *p) { |
72 | 1.44M | * (void**) p = mp->freelist; |
73 | 1.44M | mp->freelist = p; |
74 | 1.44M | } |
75 | | |
76 | 1.44M | bool mempool_enabled(void) { |
77 | 1.44M | static int b = -1; |
78 | 1.44M | |
79 | 1.44M | if (!is_main_thread()) |
80 | 0 | return false; |
81 | 1.44M | |
82 | 1.44M | if (!mempool_use_allowed) |
83 | 0 | b = false; |
84 | 1.44M | if (b < 0) |
85 | 15 | b = getenv_bool("SYSTEMD_MEMPOOL") != 0; |
86 | 1.44M | |
87 | 1.44M | return b; |
88 | 1.44M | } |
89 | | |
90 | | #if VALGRIND |
91 | | void mempool_drop(struct mempool *mp) { |
92 | | struct pool *p = mp->first_pool; |
93 | | while (p) { |
94 | | struct pool *n; |
95 | | n = p->next; |
96 | | free(p); |
97 | | p = n; |
98 | | } |
99 | | } |
100 | | #endif |