Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2010-2014 Lennart Poettering
7 : Copyright 2014 Michal Schmidt
8 :
9 : systemd is free software; you can redistribute it and/or modify it
10 : under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation; either version 2.1 of the License, or
12 : (at your option) any later version.
13 :
14 : systemd is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 : ***/
22 :
23 : #include "mempool.h"
24 : #include "macro.h"
25 : #include "util.h"
26 :
27 : struct pool {
28 : struct pool *next;
29 : unsigned n_tiles;
30 : unsigned n_used;
31 : };
32 :
33 7316 : void* mempool_alloc_tile(struct mempool *mp) {
34 : unsigned i;
35 :
36 : /* When a tile is released we add it to the list and simply
37 : * place the next pointer at its offset 0. */
38 :
39 7316 : assert(mp->tile_size >= sizeof(void*));
40 7316 : assert(mp->at_least > 0);
41 :
42 7316 : if (mp->freelist) {
43 : void *r;
44 :
45 6165 : r = mp->freelist;
46 6165 : mp->freelist = * (void**) mp->freelist;
47 6165 : return r;
48 : }
49 :
50 2233 : if (_unlikely_(!mp->first_pool) ||
51 1082 : _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) {
52 : unsigned n;
53 : size_t size;
54 : struct pool *p;
55 :
56 73 : n = mp->first_pool ? mp->first_pool->n_tiles : 0;
57 73 : n = MAX(mp->at_least, n * 2);
58 73 : size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size);
59 73 : n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size;
60 :
61 73 : p = malloc(size);
62 73 : if (!p)
63 0 : return NULL;
64 :
65 73 : p->next = mp->first_pool;
66 73 : p->n_tiles = n;
67 73 : p->n_used = 0;
68 :
69 73 : mp->first_pool = p;
70 : }
71 :
72 1151 : i = mp->first_pool->n_used++;
73 :
74 1151 : return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size;
75 : }
76 :
77 7316 : void* mempool_alloc0_tile(struct mempool *mp) {
78 : void *p;
79 :
80 7316 : p = mempool_alloc_tile(mp);
81 7316 : if (p)
82 7316 : memzero(p, mp->tile_size);
83 7316 : return p;
84 : }
85 :
86 7314 : void mempool_free_tile(struct mempool *mp, void *p) {
87 7314 : * (void**) p = mp->freelist;
88 7314 : mp->freelist = p;
89 7314 : }
90 :
91 : #ifdef VALGRIND
92 :
93 : void mempool_drop(struct mempool *mp) {
94 : struct pool *p = mp->first_pool;
95 : while (p) {
96 : struct pool *n;
97 : n = p->next;
98 : free(p);
99 : p = n;
100 : }
101 : }
102 :
103 : #endif
|