Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /*
3 : : * This file provides some functions to manage a pool of pre-allocated
4 : : * objects. It also provides a method to reserve a pre-defined number
5 : : * of objects for higher priorty requests. The allocations follow the
6 : : * following rules:
7 : : *
8 : : * 1. An allocation will succeed at any priority if there is more than
9 : : * the reserved number of objects free.
10 : : * 2. Only high priority allocations will succeed when there are less
11 : : * than the reserved number of objects free.
12 : : * 3. When an allocation is freed it is always added to the high priority
13 : : * pool if there are less than the reserved number of allocations
14 : : * available.
15 : : *
16 : : * Copyright 2013-2014 IBM Corp.
17 : : */
18 : :
19 : : #include <pool.h>
20 : : #include <string.h>
21 : : #include <stdlib.h>
22 : : #include <ccan/list/list.h>
23 : :
24 : 13 : void* pool_get(struct pool *pool, enum pool_priority priority)
25 : : {
26 : : void *obj;
27 : :
28 : 13 : if (!pool->free_count ||
29 : 13 : ((pool->free_count <= pool->reserved) && priority == POOL_NORMAL))
30 : 1 : return NULL;
31 : :
32 : 12 : pool->free_count--;
33 : 12 : obj = (void *) list_pop_(&pool->free_list, 0);
34 : 12 : assert(obj);
35 : 12 : memset(obj, 0, pool->obj_size);
36 : 12 : return obj;
37 : : }
38 : :
39 : 2 : void pool_free_object(struct pool *pool, void *obj)
40 : : {
41 : 2 : pool->free_count++;
42 : 2 : list_add_tail(&pool->free_list,
43 : : (struct list_node *) (obj));
44 : 2 : }
45 : :
46 : 1 : int pool_init(struct pool *pool, size_t obj_size, int count, int reserved)
47 : : {
48 : : int i;
49 : :
50 : 1 : if (obj_size < sizeof(struct list_node))
51 : 1 : obj_size = sizeof(struct list_node);
52 : :
53 : 1 : assert(count >= reserved);
54 : 1 : pool->buf = malloc(obj_size*count);
55 : 1 : if (!pool->buf)
56 : 0 : return -1;
57 : :
58 : 1 : pool->obj_size = obj_size;
59 : 1 : pool->free_count = count;
60 : 1 : pool->reserved = reserved;
61 : 1 : list_head_init(&pool->free_list);
62 : :
63 : 11 : for(i = 0; i < count; i++)
64 : 10 : list_add_tail(&pool->free_list,
65 : : (struct list_node *) (pool->buf + obj_size*i));
66 : :
67 : 1 : return 0;
68 : : }
|