| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2010 Marek Olšák <maraeo@gmail.com> | 
|  | 3 | * Copyright 2016 Advanced Micro Devices, Inc. | 
|  | 4 | * | 
|  | 5 | * Permission is hereby granted, free of charge, to any person obtaining a | 
|  | 6 | * copy of this software and associated documentation files (the "Software"), | 
|  | 7 | * to deal in the Software without restriction, including without limitation | 
|  | 8 | * on the rights to use, copy, modify, merge, publish, distribute, sub | 
|  | 9 | * license, and/or sell copies of the Software, and to permit persons to whom | 
|  | 10 | * the Software is furnished to do so, subject to the following conditions: | 
|  | 11 | * | 
|  | 12 | * The above copyright notice and this permission notice (including the next | 
|  | 13 | * paragraph) shall be included in all copies or substantial portions of the | 
|  | 14 | * Software. | 
|  | 15 | * | 
|  | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|  | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|  | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | 
|  | 19 | * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | 
|  | 20 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | 
|  | 21 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | 
|  | 22 | * USE OR OTHER DEALINGS IN THE SOFTWARE. */ | 
|  | 23 |  | 
|  | 24 | /** | 
|  | 25 | * Slab allocator for equally sized memory allocations. | 
| Nicolai Hähnle | d8cff81 | 2016-09-27 18:30:18 +0200 | [diff] [blame] | 26 | * | 
|  | 27 | * Objects are allocated from "child" pools that are connected to a "parent" | 
|  | 28 | * pool. | 
|  | 29 | * | 
|  | 30 | * Calls to slab_alloc/slab_free for the same child pool must not occur from | 
|  | 31 | * multiple threads simultaneously. | 
|  | 32 | * | 
|  | 33 | * Allocations obtained from one child pool should usually be freed in the | 
|  | 34 | * same child pool. Freeing an allocation in a different child pool associated | 
|  | 35 | * to the same parent is allowed (and requires no locking by the caller), but | 
|  | 36 | * it is discouraged because it implies a performance penalty. | 
|  | 37 | * | 
|  | 38 | * For convenience and to ease the transition, there is also a set of wrapper | 
|  | 39 | * functions around a single parent-child pair. | 
| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 40 | */ | 
|  | 41 |  | 
|  | 42 | #ifndef SLAB_H | 
|  | 43 | #define SLAB_H | 
|  | 44 |  | 
|  | 45 | #include "c11/threads.h" | 
|  | 46 |  | 
| Nicolai Hähnle | d8cff81 | 2016-09-27 18:30:18 +0200 | [diff] [blame] | 47 | struct slab_element_header; | 
|  | 48 | struct slab_page_header; | 
| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 49 |  | 
| Nicolai Hähnle | d8cff81 | 2016-09-27 18:30:18 +0200 | [diff] [blame] | 50 | struct slab_parent_pool { | 
| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 51 | mtx_t mutex; | 
|  | 52 | unsigned element_size; | 
|  | 53 | unsigned num_elements; | 
| Nicolai Hähnle | d8cff81 | 2016-09-27 18:30:18 +0200 | [diff] [blame] | 54 | }; | 
|  | 55 |  | 
|  | 56 | struct slab_child_pool { | 
|  | 57 | struct slab_parent_pool *parent; | 
|  | 58 |  | 
|  | 59 | struct slab_page_header *pages; | 
|  | 60 |  | 
|  | 61 | /* Free elements. */ | 
|  | 62 | struct slab_element_header *free; | 
|  | 63 |  | 
|  | 64 | /* Elements that are owned by this pool but were freed with a different | 
|  | 65 | * pool as the argument to slab_free. | 
|  | 66 | * | 
|  | 67 | * This list is protected by the parent mutex. | 
|  | 68 | */ | 
|  | 69 | struct slab_element_header *migrated; | 
|  | 70 | }; | 
|  | 71 |  | 
|  | 72 | void slab_create_parent(struct slab_parent_pool *parent, | 
|  | 73 | unsigned item_size, | 
|  | 74 | unsigned num_items); | 
|  | 75 | void slab_destroy_parent(struct slab_parent_pool *parent); | 
|  | 76 | void slab_create_child(struct slab_child_pool *pool, | 
|  | 77 | struct slab_parent_pool *parent); | 
|  | 78 | void slab_destroy_child(struct slab_child_pool *pool); | 
|  | 79 | void *slab_alloc(struct slab_child_pool *pool); | 
|  | 80 | void slab_free(struct slab_child_pool *pool, void *ptr); | 
|  | 81 |  | 
|  | 82 | struct slab_mempool { | 
|  | 83 | struct slab_parent_pool parent; | 
|  | 84 | struct slab_child_pool child; | 
| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 85 | }; | 
|  | 86 |  | 
| Ian Romanick | a6b7d11 | 2018-11-26 10:28:02 -0800 | [diff] [blame] | 87 | void slab_create(struct slab_mempool *mempool, | 
| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 88 | unsigned item_size, | 
|  | 89 | unsigned num_items); | 
| Ian Romanick | a6b7d11 | 2018-11-26 10:28:02 -0800 | [diff] [blame] | 90 | void slab_destroy(struct slab_mempool *mempool); | 
|  | 91 | void *slab_alloc_st(struct slab_mempool *mempool); | 
|  | 92 | void slab_free_st(struct slab_mempool *mempool, void *ptr); | 
| Marek Olšák | 761ff40 | 2016-08-27 19:52:31 +0200 | [diff] [blame] | 93 |  | 
|  | 94 | #endif |