pb_bufmgr_slab.c revision bd4eec0561fb021849ac4047fdbf40a616fb68b3
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é Fonsecastruct pb_slab; 5121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5221c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_slab_buffer 5321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 5421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_buffer base; 5521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 5621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab; 5721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head head; 5821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned mapCount; 5921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t start; 6021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_Cond event; 6121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 6221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 6321c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_slab 6421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 6521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head head; 6621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head freeBuffers; 6721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t numBuffers; 6821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t numFree; 6921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buffers; 70a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr; 7121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 7221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_buffer *bo; 7321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca void *virtual; 7421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 7521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 76a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastruct pb_slab_manager 7721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 78a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager base; 79a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 80a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager *provider; 81a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize; 82a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t slabSize; 83a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_desc desc; 84a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 8521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head slabs; 8621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head freeSlabs; 87a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 8821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_Mutex mutex; 8921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 9021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 9121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca/** 9221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * The data of this structure remains constant after 9321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * initialization and thus needs no mutex protection. 9421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 95a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastruct pb_slab_range_manager 9621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 9721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_manager base; 9821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 99a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager *provider; 100a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t minBufSize; 101a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t maxBufSize; 10221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_desc desc; 103a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 104a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned numBuckets; 10521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t *bucketSizes; 106a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_manager **buckets; 10721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 10821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 10921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 11021c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic INLINE struct pb_slab_buffer * 11121c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer(struct pb_buffer *buf) 11221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 11321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca assert(buf); 11421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return (struct pb_slab_buffer *)buf; 11521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 11621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 11721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 11821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic INLINE struct pb_slab_manager * 11921c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_manager(struct pb_manager *mgr) 12021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 12121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca assert(mgr); 12221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return (struct pb_slab_manager *)mgr; 12321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 12421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 12521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 126a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic INLINE struct pb_slab_range_manager * 127a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager(struct pb_manager *mgr) 128a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 129a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca assert(mgr); 130a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return (struct pb_slab_range_manager *)mgr; 131a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 132a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 133a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 13421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca/** 135a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca * Delete a buffer from the slab delayed list and put 13621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * it on the slab FREE list. 13721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 13821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 13921c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_destroy(struct pb_buffer *_buf) 14021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 14121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 14221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab = buf->slab; 143a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr = slab->mgr; 14421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head *list = &buf->head; 14521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 146a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_LOCK_MUTEX(mgr->mutex); 14721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 14821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca assert(buf->base.base.refcount == 0); 14921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->mapCount = 0; 15121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DEL(list); 15321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_ADDTAIL(list, &slab->freeBuffers); 15421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numFree++; 15521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (slab->head.next == &slab->head) 157a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_ADDTAIL(&slab->head, &mgr->slabs); 15821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 15921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (slab->numFree == slab->numBuffers) { 16021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca list = &slab->head; 16121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DEL(list); 162a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_ADDTAIL(list, &mgr->freeSlabs); 16321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 16421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 165a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (mgr->slabs.next == &mgr->slabs || slab->numFree 16621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca != slab->numBuffers) { 16721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 16821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head *next; 16921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 170a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (list = mgr->freeSlabs.next, next = list->next; list 171a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca != &mgr->freeSlabs; list = next, next = list->next) { 17221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 17321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab = LIST_ENTRY(struct pb_slab, list, head); 17421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 17521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DELINIT(list); 17621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_reference(&slab->bo, NULL); 17721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca FREE(slab->buffers); 17821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca FREE(slab); 17921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 18021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 18121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 182a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 18321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 18421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 18521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 18621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void * 18721c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_map(struct pb_buffer *_buf, 18821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned flags) 18921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 19021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 19121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 19221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca ++buf->mapCount; 19321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return (void *) ((uint8_t *) buf->slab->virtual + buf->start); 19421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 19521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 19621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 19721c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 19821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_unmap(struct pb_buffer *_buf) 19921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 20021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 20121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 20221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca --buf->mapCount; 20321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (buf->mapCount == 0) 20421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_COND_BROADCAST(buf->event); 20521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 20621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 20721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 20821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 20921c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_get_base_buffer(struct pb_buffer *_buf, 21021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_buffer **base_buf, 21121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned *offset) 21221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 21321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf = pb_slab_buffer(_buf); 21421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_get_base_buffer(buf->slab->bo, base_buf, offset); 21521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca *offset += buf->start; 21621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 21721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 21821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 21921c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic const struct pb_vtbl 22021c302b0ec39480a7eaab7827cce5b609d196606José Fonsecapb_slab_buffer_vtbl = { 22121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_destroy, 22221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_map, 22321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_unmap, 22421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_slab_buffer_get_base_buffer 22521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca}; 22621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 22721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 22821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic enum pipe_error 229a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_create(struct pb_slab_manager *mgr) 23021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 23121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab; 23221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab_buffer *buf; 233a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned numBuffers; 23421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca unsigned i; 235a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca enum pipe_error ret; 23621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 23721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab = CALLOC_STRUCT(pb_slab); 23821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (!slab) 23921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return PIPE_ERROR_OUT_OF_MEMORY; 24021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 24121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca /* 24221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * FIXME: We should perhaps allow some variation in slabsize in order 24321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca * to efficiently reuse slabs. 24421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca */ 24521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 246a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca slab->bo = mgr->provider->create_buffer(mgr->provider, mgr->slabSize, &mgr->desc); 247a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!slab->bo) { 248a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 24921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err0; 250a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 25121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 25221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->virtual = pb_map(slab->bo, 253a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca PIPE_BUFFER_USAGE_CPU_READ | 254a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca PIPE_BUFFER_USAGE_CPU_WRITE); 255a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!slab->virtual) { 256a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 25721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err1; 258a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 25921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 26021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_unmap(slab->bo); 26121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 262a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca numBuffers = slab->bo->base.size / mgr->bufSize; 26321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 26421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->buffers = CALLOC(numBuffers, sizeof(*slab->buffers)); 26521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (!slab->buffers) { 26621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 26721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err1; 26821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 26921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 27021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_INITHEAD(&slab->head); 27121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_INITHEAD(&slab->freeBuffers); 27221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numBuffers = numBuffers; 27321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numFree = 0; 274a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca slab->mgr = mgr; 27521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 27621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf = slab->buffers; 27721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca for (i=0; i < numBuffers; ++i) { 27821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.base.refcount = 0; 279a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->base.base.size = mgr->bufSize; 28021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.base.alignment = 0; 28121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.base.usage = 0; 28221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->base.vtbl = &pb_slab_buffer_vtbl; 28321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->slab = slab; 284a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->start = i* mgr->bufSize; 28521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf->mapCount = 0; 28621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca _glthread_INIT_COND(buf->event); 28721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_ADDTAIL(&buf->head, &slab->freeBuffers); 28821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab->numFree++; 28921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf++; 29021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 29121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 292a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_ADDTAIL(&slab->head, &mgr->slabs); 29321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 29421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return PIPE_OK; 29521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 29621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err1: 29721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca pb_reference(&slab->bo, NULL); 29821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err0: 29921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca FREE(slab); 30021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return ret; 30121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 30221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 30321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 30421c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic struct pb_buffer * 305a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_manager_create_buffer(struct pb_manager *_mgr, 30621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca size_t size, 30721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca const struct pb_desc *desc) 30821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 309a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr = pb_slab_manager(_mgr); 31021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca static struct pb_slab_buffer *buf; 31121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct pb_slab *slab; 31221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca struct list_head *list; 31321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 314a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* check size */ 315a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca assert(size == mgr->bufSize); 316a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(size != mgr->bufSize) 317a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 318a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 319a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* check if we can provide the requested alignment */ 32095aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca assert(pb_check_alignment(desc->alignment, mgr->desc.alignment)); 32195aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca if(!pb_check_alignment(desc->alignment, mgr->desc.alignment)) 322a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 32395aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca assert(pb_check_alignment(desc->alignment, mgr->bufSize)); 32495aeeb6d746e57473116ef4d72c05330902f68a5José Fonseca if(!pb_check_alignment(desc->alignment, mgr->bufSize)) 325a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 32621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 327a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* XXX: check for compatible buffer usage too? */ 328a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 329a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_LOCK_MUTEX(mgr->mutex); 330bd4eec0561fb021849ac4047fdbf40a616fb68b3José Fonseca if (mgr->slabs.next == &mgr->slabs) { 331a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca (void) pb_slab_create(mgr); 332bd4eec0561fb021849ac4047fdbf40a616fb68b3José Fonseca if (mgr->slabs.next == &mgr->slabs) { 333bd4eec0561fb021849ac4047fdbf40a616fb68b3José Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 334bd4eec0561fb021849ac4047fdbf40a616fb68b3José Fonseca return NULL; 335bd4eec0561fb021849ac4047fdbf40a616fb68b3José Fonseca } 33621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 337a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca list = mgr->slabs.next; 33821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca slab = LIST_ENTRY(struct pb_slab, list, head); 33921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca if (--slab->numFree == 0) 34021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DELINIT(list); 34121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 34221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca list = slab->freeBuffers.next; 34321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca LIST_DELINIT(list); 34421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 345a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_UNLOCK_MUTEX(mgr->mutex); 34621c302b0ec39480a7eaab7827cce5b609d196606José Fonseca buf = LIST_ENTRY(struct pb_slab_buffer, list, head); 347a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 34821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca ++buf->base.base.refcount; 349a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->base.base.alignment = desc->alignment; 350a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca buf->base.base.usage = desc->usage; 351a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 35221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return &buf->base; 35321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 35421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 35521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 35621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastatic void 357a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_manager_destroy(struct pb_manager *_mgr) 35821c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 359a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr = pb_slab_manager(_mgr); 36021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 361a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* TODO: cleanup all allocated buffers */ 362a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr); 36321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 36421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 36521c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 36621c302b0ec39480a7eaab7827cce5b609d196606José Fonsecastruct pb_manager * 367a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_manager_create(struct pb_manager *provider, 368a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize, 369a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t slabSize, 370a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca const struct pb_desc *desc) 371a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 372a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_manager *mgr; 373a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 374a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr = CALLOC_STRUCT(pb_slab_manager); 375a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (!mgr) 376a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return NULL; 377a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 378a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.destroy = pb_slab_manager_destroy; 379a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.create_buffer = pb_slab_manager_create_buffer; 380a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 381a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->provider = provider; 382a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->bufSize = bufSize; 383a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->slabSize = slabSize; 384a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->desc = *desc; 385a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 386a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_INITHEAD(&mgr->slabs); 387a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca LIST_INITHEAD(&mgr->freeSlabs); 388a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 389a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca _glthread_INIT_MUTEX(mgr->mutex); 390a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 391a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return &mgr->base; 392a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 393a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 394a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 395a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic struct pb_buffer * 396a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager_create_buffer(struct pb_manager *_mgr, 397a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t size, 398a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca const struct pb_desc *desc) 39921c302b0ec39480a7eaab7827cce5b609d196606José Fonseca{ 400a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); 401a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize; 402a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned i; 40321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 404a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize = mgr->minBufSize; 405a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) { 406a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(bufSize >= size) 407a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return mgr->buckets[i]->create_buffer(mgr->buckets[i], size, desc); 408a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize *= 2; 409a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 410a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 411a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca /* Fall back to allocate a buffer object directly from the provider. */ 412a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return mgr->provider->create_buffer(mgr->provider, size, desc); 413a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 414a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 415a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 416a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastatic void 417a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager_destroy(struct pb_manager *_mgr) 418a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 419a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); 420a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned i; 421a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 422a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) 423a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets[i]->destroy(mgr->buckets[i]); 424a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr->buckets); 425a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr->bucketSizes); 426a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr); 427a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca} 428a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 429a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 430a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecastruct pb_manager * 431a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonsecapb_slab_range_manager_create(struct pb_manager *provider, 432a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t minBufSize, 433a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t maxBufSize, 434a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t slabSize, 435a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca const struct pb_desc *desc) 436a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca{ 437a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca struct pb_slab_range_manager *mgr; 438a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca size_t bufSize; 439a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca unsigned i; 440a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 441a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr = CALLOC_STRUCT(pb_slab_range_manager); 442a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (!mgr) 44321c302b0ec39480a7eaab7827cce5b609d196606José Fonseca goto out_err0; 44421c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 445a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.destroy = pb_slab_range_manager_destroy; 446a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->base.create_buffer = pb_slab_range_manager_create_buffer; 44721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 448a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->provider = provider; 449a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->minBufSize = minBufSize; 450a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->maxBufSize = maxBufSize; 451a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 452a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->numBuckets = 1; 453a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize = minBufSize; 454a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca while(bufSize < maxBufSize) { 455a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize *= 2; 456a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca ++mgr->numBuckets; 45721c302b0ec39480a7eaab7827cce5b609d196606José Fonseca } 458a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca 459a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets = CALLOC(mgr->numBuckets, sizeof(*mgr->buckets)); 460a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if (!mgr->buckets) 461a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca goto out_err1; 46221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 463a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize = minBufSize; 464a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) { 465a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets[i] = pb_slab_manager_create(provider, bufSize, slabSize, desc); 466a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(!mgr->buckets[i]) 467a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca goto out_err2; 468a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca bufSize *= 2; 469a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca } 47021c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 471a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca return &mgr->base; 47221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca 47321c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err2: 474a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca for (i = 0; i < mgr->numBuckets; ++i) 475a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca if(mgr->buckets[i]) 476a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca mgr->buckets[i]->destroy(mgr->buckets[i]); 477a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr->buckets); 47821c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err1: 479a175e15f20b2a231cc9d09099e7b6d8aea6c624eJosé Fonseca FREE(mgr); 48021c302b0ec39480a7eaab7827cce5b609d196606José Fonsecaout_err0: 48121c302b0ec39480a7eaab7827cce5b609d196606José Fonseca return NULL; 48221c302b0ec39480a7eaab7827cce5b609d196606José Fonseca} 483