pb_bufmgr_slab.c revision a175e15f20b2a231cc9d09099e7b6d8aea6c624e
121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca/************************************************************************** 221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA 421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * All Rights Reserved. 521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * Permission is hereby granted, FREE of charge, to any person obtaining a 721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * copy of this software and associated documentation files (the 821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * "Software"), to deal in the Software without restriction, including 921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * without limitation the rights to use, copy, modify, merge, publish, 1021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * distribute, sub license, and/or sell copies of the Software, and to 1121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * permit persons to whom the Software is furnished to do so, subject to 1221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * the following conditions: 1321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 1421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 1821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 1921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * USE OR OTHER DEALINGS IN THE SOFTWARE. 2121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 2221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * The above copyright notice and this permission notice (including the 2321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * next paragraph) shall be included in all copies or substantial portions 2421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * of the Software. 2521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 2621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 2721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca **************************************************************************/ 2821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 2921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca/** 3021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * @file 3121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * S-lab pool implementation. 3221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * 3321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * @author Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> 3421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * @author Jose Fonseca <jrfonseca@tungstengraphics.com> 3521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 3621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 3721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pipe/p_compiler.h" 3821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pipe/p_error.h" 3921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pipe/p_debug.h" 4021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pipe/p_thread.h" 4121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pipe/p_defines.h" 4221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pipe/p_util.h" 4321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "util/u_double_list.h" 4421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "util/u_time.h" 4521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 4621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pb_buffer.h" 4721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#include "pb_bufmgr.h" 4821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 4921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca#define DRI_SLABPOOL_ALLOC_RETRIES 100 5121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5321c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_slab; 5421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5521c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_slab_buffer 5621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 5721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_buffer base; 5821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab; 6021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head head; 6121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned mapCount; 6221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t start; 6321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_Cond event; 6421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 6521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 6621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_slab 6721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 6821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head head; 6921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head freeBuffers; 7021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t numBuffers; 7121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t numFree; 7221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buffers; 73a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr; 7421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 7521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_buffer *bo; 7621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca void *virtual; 7721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 7821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 79a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastruct pb_slab_manager 8021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 81a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager base; 82a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 83a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager *provider; 84a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize; 85a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t slabSize; 86a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_desc desc; 87a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 8821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head slabs; 8921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head freeSlabs; 90a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 9121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_Mutex mutex; 9221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 9321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 9421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca/** 9521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * The data of this structure remains constant after 9621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * initialization and thus needs no mutex protection. 9721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 98a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastruct pb_slab_range_manager 9921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 10021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_manager base; 10121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 102a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager *provider; 103a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t minBufSize; 104a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t maxBufSize; 10521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_desc desc; 106a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 107a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned numBuckets; 10821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t *bucketSizes; 109a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager **buckets; 11021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 11121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 11221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 11321c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic INLINE struct pb_slab_buffer * 11421c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer(struct pb_buffer *buf) 11521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 11621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca assert(buf); 11721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return (struct pb_slab_buffer *)buf; 11821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 11921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 12021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 12121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic INLINE struct pb_slab_manager * 12221c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_manager(struct pb_manager *mgr) 12321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 12421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca assert(mgr); 12521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return (struct pb_slab_manager *)mgr; 12621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 12721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 12821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 129a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic INLINE struct pb_slab_range_manager * 130a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager(struct pb_manager *mgr) 131a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 132a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca assert(mgr); 133a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return (struct pb_slab_range_manager *)mgr; 134a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 135a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 136a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 13721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca/** 138a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca * Delete a buffer from the slab delayed list and put 13921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * it on the slab FREE list. 14021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 14121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 14221c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_destroy(struct pb_buffer *_buf) 14321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 14421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 14521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab = buf->slab; 146a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr = slab->mgr; 14721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head *list = &buf->head; 14821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 149a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_LOCK_MUTEX(mgr->mutex); 15021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca assert(buf->base.base.refcount == 0); 15221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->mapCount = 0; 15421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DEL(list); 15621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_ADDTAIL(list, &slab->freeBuffers); 15721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numFree++; 15821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (slab->head.next == &slab->head) 160a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_ADDTAIL(&slab->head, &mgr->slabs); 16121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 16221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (slab->numFree == slab->numBuffers) { 16321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca list = &slab->head; 16421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DEL(list); 165a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_ADDTAIL(list, &mgr->freeSlabs); 16621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 16721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 168a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (mgr->slabs.next == &mgr->slabs || slab->numFree 16921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca != slab->numBuffers) { 17021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 17121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head *next; 17221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 173a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (list = mgr->freeSlabs.next, next = list->next; list 174a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca != &mgr->freeSlabs; list = next, next = list->next) { 17521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 17621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab = LIST_ENTRY(struct pb_slab, list, head); 17721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 17821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DELINIT(list); 17921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_reference(&slab->bo, NULL); 18021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca FREE(slab->buffers); 18121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca FREE(slab); 18221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 18321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 18421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 185a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 18621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 18721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 18821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 18921c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void * 19021c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_map(struct pb_buffer *_buf, 19121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned flags) 19221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 19321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 19421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 19521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca ++buf->mapCount; 19621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return (void *) ((uint8_t *) buf->slab->virtual + buf->start); 19721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 19821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 19921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 20021c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 20121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_unmap(struct pb_buffer *_buf) 20221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 20321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 20421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 20521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca --buf->mapCount; 20621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (buf->mapCount == 0) 20721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_COND_BROADCAST(buf->event); 20821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 20921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 21021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 21121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 21221c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_get_base_buffer(struct pb_buffer *_buf, 21321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_buffer **base_buf, 21421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned *offset) 21521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 21621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 21721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_get_base_buffer(buf->slab->bo, base_buf, offset); 21821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca *offset += buf->start; 21921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 22021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 22121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 22221c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic const struct pb_vtbl 22321c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_vtbl = { 22421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_destroy, 22521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_map, 22621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_unmap, 22721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_get_base_buffer 22821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 22921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 23021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 23121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic enum pipe_error 232a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_create(struct pb_slab_manager *mgr) 23321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 23421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab; 23521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf; 236a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned numBuffers; 23721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned i; 238a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca enum pipe_error ret; 23921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 24021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab = CALLOC_STRUCT(pb_slab); 24121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (!slab) 24221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return PIPE_ERROR_OUT_OF_MEMORY; 24321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 24421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca /* 24521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * FIXME: We should perhaps allow some variation in slabsize in order 24621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * to efficiently reuse slabs. 24721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 24821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 249a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca slab->bo = mgr->provider->create_buffer(mgr->provider, mgr->slabSize, &mgr->desc); 250a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!slab->bo) { 251a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 25221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err0; 253a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 25421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 25521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->virtual = pb_map(slab->bo, 256a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca PIPE_BUFFER_USAGE_CPU_READ | 257a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca PIPE_BUFFER_USAGE_CPU_WRITE); 258a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!slab->virtual) { 259a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 26021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err1; 261a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 26221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 26321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_unmap(slab->bo); 26421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 265a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca numBuffers = slab->bo->base.size / mgr->bufSize; 26621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 26721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->buffers = CALLOC(numBuffers, sizeof(*slab->buffers)); 26821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (!slab->buffers) { 26921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 27021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err1; 27121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 27221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 27321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_INITHEAD(&slab->head); 27421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_INITHEAD(&slab->freeBuffers); 27521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numBuffers = numBuffers; 27621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numFree = 0; 277a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca slab->mgr = mgr; 27821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 27921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf = slab->buffers; 28021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca for (i=0; i < numBuffers; ++i) { 28121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.base.refcount = 0; 282a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->base.base.size = mgr->bufSize; 28321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.base.alignment = 0; 28421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.base.usage = 0; 28521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.vtbl = &pb_slab_buffer_vtbl; 28621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->slab = slab; 287a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->start = i* mgr->bufSize; 28821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->mapCount = 0; 28921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_INIT_COND(buf->event); 29021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_ADDTAIL(&buf->head, &slab->freeBuffers); 29121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numFree++; 29221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf++; 29321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 29421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 295a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_ADDTAIL(&slab->head, &mgr->slabs); 29621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 29721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return PIPE_OK; 29821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 29921c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err1: 30021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_reference(&slab->bo, NULL); 30121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err0: 30221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca FREE(slab); 30321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return ret; 30421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 30521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 30621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 307a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic int 308a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecacheck_alignment(size_t requested, size_t provided) 309a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 310a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return requested <= provided && (provided % requested) == 0; 311a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 312a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 313a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 31421c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic struct pb_buffer * 315a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_manager_create_buffer(struct pb_manager *_mgr, 31621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t size, 31721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca const struct pb_desc *desc) 31821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 319a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr = pb_slab_manager(_mgr); 32021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca static struct pb_slab_buffer *buf; 32121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab; 32221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head *list; 32321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca int count = DRI_SLABPOOL_ALLOC_RETRIES; 32421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 325a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* check size */ 326a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca assert(size == mgr->bufSize); 327a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(size != mgr->bufSize) 328a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 329a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 330a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* check if we can provide the requested alignment */ 331a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca assert(check_alignment(desc->alignment, mgr->desc.alignment)); 332a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!check_alignment(desc->alignment, mgr->desc.alignment)) 333a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 334a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca assert(check_alignment(desc->alignment, mgr->bufSize)); 335a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!check_alignment(desc->alignment, mgr->bufSize)) 336a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 33721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 338a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* XXX: check for compatible buffer usage too? */ 339a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 340a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_LOCK_MUTEX(mgr->mutex); 341a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca while (mgr->slabs.next == &mgr->slabs && count > 0) { 342a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (mgr->slabs.next != &mgr->slabs) 34321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca break; 34421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 345a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 34621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (count != DRI_SLABPOOL_ALLOC_RETRIES) 34721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca util_time_sleep(1); 348a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_LOCK_MUTEX(mgr->mutex); 349a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca (void) pb_slab_create(mgr); 35021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca count--; 35121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 35221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 353a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca list = mgr->slabs.next; 354a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (list == &mgr->slabs) { 355a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 35621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return NULL; 35721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 35821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab = LIST_ENTRY(struct pb_slab, list, head); 35921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (--slab->numFree == 0) 36021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DELINIT(list); 36121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 36221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca list = slab->freeBuffers.next; 36321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DELINIT(list); 36421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 365a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 36621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf = LIST_ENTRY(struct pb_slab_buffer, list, head); 367a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 36821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca ++buf->base.base.refcount; 369a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->base.base.alignment = desc->alignment; 370a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->base.base.usage = desc->usage; 371a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 37221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return &buf->base; 37321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 37421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 37521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 37621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 377a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_manager_destroy(struct pb_manager *_mgr) 37821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 379a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr = pb_slab_manager(_mgr); 38021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 381a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* TODO: cleanup all allocated buffers */ 382a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr); 38321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 38421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 38521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 38621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_manager * 387a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_manager_create(struct pb_manager *provider, 388a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize, 389a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t slabSize, 390a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca const struct pb_desc *desc) 391a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 392a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr; 393a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 394a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr = CALLOC_STRUCT(pb_slab_manager); 395a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (!mgr) 396a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 397a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 398a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.destroy = pb_slab_manager_destroy; 399a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.create_buffer = pb_slab_manager_create_buffer; 400a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 401a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->provider = provider; 402a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->bufSize = bufSize; 403a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->slabSize = slabSize; 404a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->desc = *desc; 405a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 406a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_INITHEAD(&mgr->slabs); 407a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_INITHEAD(&mgr->freeSlabs); 408a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 409a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_INIT_MUTEX(mgr->mutex); 410a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 411a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return &mgr->base; 412a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 413a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 414a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 415a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic struct pb_buffer * 416a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager_create_buffer(struct pb_manager *_mgr, 417a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t size, 418a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca const struct pb_desc *desc) 41921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 420a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); 421a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize; 422a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned i; 42321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 424a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize = mgr->minBufSize; 425a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) { 426a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(bufSize >= size) 427a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return mgr->buckets[i]->create_buffer(mgr->buckets[i], size, desc); 428a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize *= 2; 429a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 430a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 431a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* Fall back to allocate a buffer object directly from the provider. */ 432a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return mgr->provider->create_buffer(mgr->provider, size, desc); 433a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 434a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 435a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 436a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic void 437a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager_destroy(struct pb_manager *_mgr) 438a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 439a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); 440a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned i; 441a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 442a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) 443a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets[i]->destroy(mgr->buckets[i]); 444a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr->buckets); 445a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr->bucketSizes); 446a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr); 447a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 448a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 449a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 450a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastruct pb_manager * 451a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager_create(struct pb_manager *provider, 452a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t minBufSize, 453a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t maxBufSize, 454a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t slabSize, 455a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca const struct pb_desc *desc) 456a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 457a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_range_manager *mgr; 458a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize; 459a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned i; 460a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 461a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr = CALLOC_STRUCT(pb_slab_range_manager); 462a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (!mgr) 46321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err0; 46421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 465a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.destroy = pb_slab_range_manager_destroy; 466a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.create_buffer = pb_slab_range_manager_create_buffer; 46721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 468a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->provider = provider; 469a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->minBufSize = minBufSize; 470a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->maxBufSize = maxBufSize; 471a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 472a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->numBuckets = 1; 473a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize = minBufSize; 474a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca while(bufSize < maxBufSize) { 475a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize *= 2; 476a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca ++mgr->numBuckets; 47721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 478a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 479a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets = CALLOC(mgr->numBuckets, sizeof(*mgr->buckets)); 480a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (!mgr->buckets) 481a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca goto out_err1; 48221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 483a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize = minBufSize; 484a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) { 485a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets[i] = pb_slab_manager_create(provider, bufSize, slabSize, desc); 486a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!mgr->buckets[i]) 487a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca goto out_err2; 488a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize *= 2; 489a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 49021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 491a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return &mgr->base; 49221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 49321c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err2: 494a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) 495a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(mgr->buckets[i]) 496a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets[i]->destroy(mgr->buckets[i]); 497a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr->buckets); 49821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err1: 499a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr); 50021c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err0: 50121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return NULL; 50221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 503