Branch data 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 : 134490 : 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 [ - + ]: 134490 : assert(mp->tile_size >= sizeof(void*)); 26 [ - + ]: 134490 : assert(mp->at_least > 0); 27 : : 28 [ + + ]: 134490 : if (mp->freelist) { 29 : : void *r; 30 : : 31 : 107350 : r = mp->freelist; 32 : 107350 : mp->freelist = * (void**) mp->freelist; 33 : 107350 : return r; 34 : : } 35 : : 36 [ + + ]: 27140 : if (_unlikely_(!mp->first_pool) || 37 [ + + ]: 26306 : _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) { 38 : : size_t size, n; 39 : : struct pool *p; 40 : : 41 [ + + ]: 958 : n = mp->first_pool ? mp->first_pool->n_tiles : 0; 42 : 958 : n = MAX(mp->at_least, n * 2); 43 : 958 : size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size); 44 : 958 : n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size; 45 : : 46 : 958 : p = malloc(size); 47 [ - + ]: 958 : if (!p) 48 : 0 : return NULL; 49 : : 50 : 958 : p->next = mp->first_pool; 51 : 958 : p->n_tiles = n; 52 : 958 : p->n_used = 0; 53 : : 54 : 958 : mp->first_pool = p; 55 : : } 56 : : 57 : 27140 : i = mp->first_pool->n_used++; 58 : : 59 : 27140 : return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size; 60 : : } 61 : : 62 : 134490 : void* mempool_alloc0_tile(struct mempool *mp) { 63 : : void *p; 64 : : 65 : 134490 : p = mempool_alloc_tile(mp); 66 [ + - ]: 134490 : if (p) 67 [ + - ]: 134490 : memzero(p, mp->tile_size); 68 : 134490 : return p; 69 : : } 70 : : 71 : 134486 : void mempool_free_tile(struct mempool *mp, void *p) { 72 : 134486 : * (void**) p = mp->freelist; 73 : 134486 : mp->freelist = p; 74 : 134486 : } 75 : : 76 : 134606 : bool mempool_enabled(void) { 77 : : static int b = -1; 78 : : 79 [ + + ]: 134606 : if (!is_main_thread()) 80 : 88 : return false; 81 : : 82 [ + + ]: 134518 : if (!mempool_use_allowed) 83 : 20 : b = false; 84 [ + + ]: 134518 : if (b < 0) 85 : 683 : b = getenv_bool("SYSTEMD_MEMPOOL") != 0; 86 : : 87 : 134518 : 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