Line data Source code
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 33790 : void* mempool_alloc_tile(struct mempool *mp) { 20 : size_t i; 21 : 22 : /* When a tile is released we add it to the list and simply 23 : * place the next pointer at its offset 0. */ 24 : 25 33790 : assert(mp->tile_size >= sizeof(void*)); 26 33790 : assert(mp->at_least > 0); 27 : 28 33790 : if (mp->freelist) { 29 : void *r; 30 : 31 26946 : r = mp->freelist; 32 26946 : mp->freelist = * (void**) mp->freelist; 33 26946 : return r; 34 : } 35 : 36 6844 : if (_unlikely_(!mp->first_pool) || 37 6635 : _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) { 38 : size_t size, n; 39 : struct pool *p; 40 : 41 240 : n = mp->first_pool ? mp->first_pool->n_tiles : 0; 42 240 : n = MAX(mp->at_least, n * 2); 43 240 : size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size); 44 240 : n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size; 45 : 46 240 : p = malloc(size); 47 240 : if (!p) 48 0 : return NULL; 49 : 50 240 : p->next = mp->first_pool; 51 240 : p->n_tiles = n; 52 240 : p->n_used = 0; 53 : 54 240 : mp->first_pool = p; 55 : } 56 : 57 6844 : i = mp->first_pool->n_used++; 58 : 59 6844 : return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size; 60 : } 61 : 62 33790 : void* mempool_alloc0_tile(struct mempool *mp) { 63 : void *p; 64 : 65 33790 : p = mempool_alloc_tile(mp); 66 33790 : if (p) 67 33790 : memzero(p, mp->tile_size); 68 33790 : return p; 69 : } 70 : 71 33789 : void mempool_free_tile(struct mempool *mp, void *p) { 72 33789 : * (void**) p = mp->freelist; 73 33789 : mp->freelist = p; 74 33789 : } 75 : 76 33819 : bool mempool_enabled(void) { 77 : static int b = -1; 78 : 79 33819 : if (!is_main_thread()) 80 22 : return false; 81 : 82 33797 : if (!mempool_use_allowed) 83 5 : b = false; 84 33797 : if (b < 0) 85 171 : b = getenv_bool("SYSTEMD_MEMPOOL") != 0; 86 : 87 33797 : return b; 88 : } 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