X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fslab.h;h=5a25adaf7f4aafff47d420285fe38f1691f48c70;hb=012b7aab260d4d46c5e2d276485ec693a75cceeb;hp=9d13f6ad69d69b972be070df32c91450e4fda3f5;hpb=761ff403024e31aacb345efaa527377894724fad;p=mesa.git diff --git a/src/util/slab.h b/src/util/slab.h index 9d13f6ad69d..5a25adaf7f4 100644 --- a/src/util/slab.h +++ b/src/util/slab.h @@ -23,8 +23,20 @@ /** * Slab allocator for equally sized memory allocations. - * The thread-safe path ("*_mt" functions) is usually slower than malloc/free. - * The single-threaded path ("*_st" functions) is faster than malloc/free. + * + * Objects are allocated from "child" pools that are connected to a "parent" + * pool. + * + * Calls to slab_alloc/slab_free for the same child pool must not occur from + * multiple threads simultaneously. + * + * Allocations obtained from one child pool should usually be freed in the + * same child pool. Freeing an allocation in a different child pool associated + * to the same parent is allowed (and requires no locking by the caller), but + * it is discouraged because it implies a performance penalty. + * + * For convenience and to ease the transition, there is also a set of wrapper + * functions around a single parent-child pair. */ #ifndef SLAB_H @@ -32,31 +44,51 @@ #include "c11/threads.h" -/* The page is an array of allocations in one block. */ -struct slab_page_header { - /* The header (linked-list pointers). */ - struct slab_page_header *prev, *next; +struct slab_element_header; +struct slab_page_header; + +struct slab_parent_pool { + mtx_t mutex; + unsigned element_size; + unsigned num_elements; +}; + +struct slab_child_pool { + struct slab_parent_pool *parent; + + struct slab_page_header *pages; + + /* Free elements. */ + struct slab_element_header *free; - /* Memory after the last member is dedicated to the page itself. - * The allocated size is always larger than this structure. + /* Elements that are owned by this pool but were freed with a different + * pool as the argument to slab_free. + * + * This list is protected by the parent mutex. */ + struct slab_element_header *migrated; }; +void slab_create_parent(struct slab_parent_pool *parent, + unsigned item_size, + unsigned num_items); +void slab_destroy_parent(struct slab_parent_pool *parent); +void slab_create_child(struct slab_child_pool *pool, + struct slab_parent_pool *parent); +void slab_destroy_child(struct slab_child_pool *pool); +void *slab_alloc(struct slab_child_pool *pool); +void slab_free(struct slab_child_pool *pool, void *ptr); + struct slab_mempool { - mtx_t mutex; - unsigned element_size; - unsigned num_elements; - struct slab_element_header *first_free; - struct slab_page_header list; + struct slab_parent_pool parent; + struct slab_child_pool child; }; -void slab_create(struct slab_mempool *pool, +void slab_create(struct slab_mempool *mempool, unsigned item_size, unsigned num_items); -void slab_destroy(struct slab_mempool *pool); -void *slab_alloc_st(struct slab_mempool *pool); -void slab_free_st(struct slab_mempool *pool, void *ptr); -void *slab_alloc_mt(struct slab_mempool *pool); -void slab_free_mt(struct slab_mempool *pool, void *ptr); +void slab_destroy(struct slab_mempool *mempool); +void *slab_alloc_st(struct slab_mempool *mempool); +void slab_free_st(struct slab_mempool *mempool, void *ptr); #endif