199ca880aSopenharmony_ci/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ 299ca880aSopenharmony_ci 399ca880aSopenharmony_ci/*** 499ca880aSopenharmony_ci This file is part of systemd. 599ca880aSopenharmony_ci 699ca880aSopenharmony_ci Copyright 2010-2014 Lennart Poettering 799ca880aSopenharmony_ci Copyright 2014 Michal Schmidt 899ca880aSopenharmony_ci 999ca880aSopenharmony_ci systemd is free software; you can redistribute it and/or modify it 1099ca880aSopenharmony_ci under the terms of the GNU Lesser General Public License as published by 1199ca880aSopenharmony_ci the Free Software Foundation; either version 2.1 of the License, or 1299ca880aSopenharmony_ci (at your option) any later version. 1399ca880aSopenharmony_ci 1499ca880aSopenharmony_ci systemd is distributed in the hope that it will be useful, but 1599ca880aSopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1699ca880aSopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1799ca880aSopenharmony_ci Lesser General Public License for more details. 1899ca880aSopenharmony_ci 1999ca880aSopenharmony_ci You should have received a copy of the GNU Lesser General Public License 2099ca880aSopenharmony_ci along with systemd; If not, see <http://www.gnu.org/licenses/>. 2199ca880aSopenharmony_ci***/ 2299ca880aSopenharmony_ci 2399ca880aSopenharmony_ci#include "mempool.h" 2499ca880aSopenharmony_ci#include "macro.h" 2599ca880aSopenharmony_ci#include "util.h" 2699ca880aSopenharmony_ci 2799ca880aSopenharmony_cistruct pool { 2899ca880aSopenharmony_ci struct pool *next; 2999ca880aSopenharmony_ci unsigned n_tiles; 3099ca880aSopenharmony_ci unsigned n_used; 3199ca880aSopenharmony_ci}; 3299ca880aSopenharmony_ci 3399ca880aSopenharmony_civoid* mempool_alloc_tile(struct mempool *mp) { 3499ca880aSopenharmony_ci unsigned i; 3599ca880aSopenharmony_ci 3699ca880aSopenharmony_ci /* When a tile is released we add it to the list and simply 3799ca880aSopenharmony_ci * place the next pointer at its offset 0. */ 3899ca880aSopenharmony_ci 3999ca880aSopenharmony_ci assert(mp->tile_size >= sizeof(void*)); 4099ca880aSopenharmony_ci assert(mp->at_least > 0); 4199ca880aSopenharmony_ci 4299ca880aSopenharmony_ci if (mp->freelist) { 4399ca880aSopenharmony_ci void *r; 4499ca880aSopenharmony_ci 4599ca880aSopenharmony_ci r = mp->freelist; 4699ca880aSopenharmony_ci mp->freelist = * (void**) mp->freelist; 4799ca880aSopenharmony_ci return r; 4899ca880aSopenharmony_ci } 4999ca880aSopenharmony_ci 5099ca880aSopenharmony_ci if (_unlikely_(!mp->first_pool) || 5199ca880aSopenharmony_ci _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) { 5299ca880aSopenharmony_ci unsigned n; 5399ca880aSopenharmony_ci size_t size; 5499ca880aSopenharmony_ci struct pool *p; 5599ca880aSopenharmony_ci 5699ca880aSopenharmony_ci n = mp->first_pool ? mp->first_pool->n_tiles : 0; 5799ca880aSopenharmony_ci n = MAX(mp->at_least, n * 2); 5899ca880aSopenharmony_ci size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size); 5999ca880aSopenharmony_ci n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size; 6099ca880aSopenharmony_ci 6199ca880aSopenharmony_ci p = malloc(size); 6299ca880aSopenharmony_ci if (!p) 6399ca880aSopenharmony_ci return NULL; 6499ca880aSopenharmony_ci 6599ca880aSopenharmony_ci p->next = mp->first_pool; 6699ca880aSopenharmony_ci p->n_tiles = n; 6799ca880aSopenharmony_ci p->n_used = 0; 6899ca880aSopenharmony_ci 6999ca880aSopenharmony_ci mp->first_pool = p; 7099ca880aSopenharmony_ci } 7199ca880aSopenharmony_ci 7299ca880aSopenharmony_ci i = mp->first_pool->n_used++; 7399ca880aSopenharmony_ci 7499ca880aSopenharmony_ci return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size; 7599ca880aSopenharmony_ci} 7699ca880aSopenharmony_ci 7799ca880aSopenharmony_civoid* mempool_alloc0_tile(struct mempool *mp) { 7899ca880aSopenharmony_ci void *p; 7999ca880aSopenharmony_ci 8099ca880aSopenharmony_ci p = mempool_alloc_tile(mp); 8199ca880aSopenharmony_ci if (p) 8299ca880aSopenharmony_ci memzero(p, mp->tile_size); 8399ca880aSopenharmony_ci return p; 8499ca880aSopenharmony_ci} 8599ca880aSopenharmony_ci 8699ca880aSopenharmony_civoid mempool_free_tile(struct mempool *mp, void *p) { 8799ca880aSopenharmony_ci * (void**) p = mp->freelist; 8899ca880aSopenharmony_ci mp->freelist = p; 8999ca880aSopenharmony_ci} 9099ca880aSopenharmony_ci 9199ca880aSopenharmony_ci#ifdef VALGRIND 9299ca880aSopenharmony_ci 9399ca880aSopenharmony_civoid mempool_drop(struct mempool *mp) { 9499ca880aSopenharmony_ci struct pool *p = mp->first_pool; 9599ca880aSopenharmony_ci while (p) { 9699ca880aSopenharmony_ci struct pool *n; 9799ca880aSopenharmony_ci n = p->next; 9899ca880aSopenharmony_ci free(p); 9999ca880aSopenharmony_ci p = n; 10099ca880aSopenharmony_ci } 10199ca880aSopenharmony_ci} 10299ca880aSopenharmony_ci 10399ca880aSopenharmony_ci#endif 104