Go to the source code of this file.
Data Structures | |
struct | pb_manager |
Abstract base class for all buffer managers. More... | |
Functions | |
struct pb_manager * | pb_malloc_bufmgr_create (void) |
Malloc buffer provider. | |
struct pb_manager * | pool_bufmgr_create (struct pb_manager *provider, size_t n, size_t size, const struct pb_desc *desc) |
Static buffer pool sub-allocator. | |
struct pb_manager * | mm_bufmgr_create (struct pb_manager *provider, size_t size, size_t align2) |
Static sub-allocator based the old memory manager. | |
struct pb_manager * | mm_bufmgr_create_from_buffer (struct pb_buffer *buffer, size_t size, size_t align2) |
Same as mm_bufmgr_create. | |
struct pb_manager * | pb_slab_manager_create (struct pb_manager *provider, size_t bufSize, size_t slabSize, const struct pb_desc *desc) |
Slab sub-allocator. | |
struct pb_manager * | pb_slab_range_manager_create (struct pb_manager *provider, size_t minBufSize, size_t maxBufSize, size_t slabSize, const struct pb_desc *desc) |
Allow a range of buffer size, by aggregating multiple slabs sub-allocators with different bucket sizes. | |
struct pb_manager * | pb_cache_manager_create (struct pb_manager *provider, unsigned usecs) |
Time-based buffer cache. | |
struct pb_manager * | fenced_bufmgr_create (struct pb_manager *provider, struct pipe_winsys *winsys) |
Fenced buffer manager. | |
struct pb_manager * | pb_alt_manager_create (struct pb_manager *provider1, struct pb_manager *provider2) |
struct pb_manager * | pb_debug_manager_create (struct pb_manager *provider, size_t band_size) |
Debug buffer manager to detect buffer under- and overflows. |
A buffer manager does only one basic thing: it creates buffers. Actually, "buffer factory" would probably a more accurate description.
You can chain buffer managers so that you can have a finer grained memory management and pooling.
For example, for a simple batch buffer manager you would chain:
Definition in file pb_bufmgr.h.
struct pb_manager* fenced_bufmgr_create | ( | struct pb_manager * | provider, | |
struct pipe_winsys * | winsys | |||
) | [read] |
Fenced buffer manager.
This manager is just meant for convenience. It wraps the buffers returned by another manager in fenced buffers, so that
NOTE: the buffer manager that provides the buffers will be destroyed at the same time.
Definition at line 129 of file pb_bufmgr_fenced.c.
References fenced_pb_manager::base, CALLOC_STRUCT, pb_manager::create_buffer, pb_manager::destroy, fenced_buffer_list_create(), fenced_bufmgr_create_buffer(), fenced_bufmgr_destroy(), fenced_bufmgr_flush(), fenced_pb_manager::fenced_list, pb_manager::flush, FREE, and fenced_pb_manager::provider.
00131 { 00132 struct fenced_pb_manager *fenced_mgr; 00133 00134 if(!provider) 00135 return NULL; 00136 00137 fenced_mgr = CALLOC_STRUCT(fenced_pb_manager); 00138 if (!fenced_mgr) 00139 return NULL; 00140 00141 fenced_mgr->base.destroy = fenced_bufmgr_destroy; 00142 fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer; 00143 fenced_mgr->base.flush = fenced_bufmgr_flush; 00144 00145 fenced_mgr->provider = provider; 00146 fenced_mgr->fenced_list = fenced_buffer_list_create(winsys); 00147 if(!fenced_mgr->fenced_list) { 00148 FREE(fenced_mgr); 00149 return NULL; 00150 } 00151 00152 return &fenced_mgr->base; 00153 }
struct pb_manager* mm_bufmgr_create | ( | struct pb_manager * | provider, | |
size_t | size, | |||
size_t | align2 | |||
) | [read] |
Static sub-allocator based the old memory manager.
It managers buffers of different sizes. It does so by allocating a buffer with the size of the heap, and then using the old mm memory manager to manage that heap.
Definition at line 271 of file pb_bufmgr_mm.c.
References pb_desc::alignment, pb_manager::create_buffer, mm_bufmgr_create_from_buffer(), and pb_reference().
00273 { 00274 struct pb_buffer *buffer; 00275 struct pb_manager *mgr; 00276 struct pb_desc desc; 00277 00278 if(!provider) 00279 return NULL; 00280 00281 memset(&desc, 0, sizeof(desc)); 00282 desc.alignment = 1 << align2; 00283 00284 buffer = provider->create_buffer(provider, size, &desc); 00285 if (!buffer) 00286 return NULL; 00287 00288 mgr = mm_bufmgr_create_from_buffer(buffer, size, align2); 00289 if (!mgr) { 00290 pb_reference(&buffer, NULL); 00291 return NULL; 00292 } 00293 00294 return mgr; 00295 }
struct pb_manager* mm_bufmgr_create_from_buffer | ( | struct pb_buffer * | buffer, | |
size_t | size, | |||
size_t | align2 | |||
) | [read] |
Same as mm_bufmgr_create.
Buffer will be release when the manager is destroyed.
Definition at line 224 of file pb_bufmgr_mm.c.
References mm_pb_manager::align2, mm_pb_manager::base, mm_pb_manager::buffer, CALLOC_STRUCT, pb_manager::create_buffer, pb_manager::destroy, pb_manager::flush, FREE, mm_pb_manager::heap, mm_pb_manager::map, mm_bufmgr_create_buffer(), mm_bufmgr_destroy(), mm_bufmgr_flush(), mmDestroy(), mmInit(), mm_pb_manager::mutex, pb_map(), pb_unmap(), PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_mutex_init, mm_pb_manager::size, and SUPER.
00226 { 00227 struct mm_pb_manager *mm; 00228 00229 if(!buffer) 00230 return NULL; 00231 00232 mm = CALLOC_STRUCT(mm_pb_manager); 00233 if (!mm) 00234 return NULL; 00235 00236 mm->base.destroy = mm_bufmgr_destroy; 00237 mm->base.create_buffer = mm_bufmgr_create_buffer; 00238 mm->base.flush = mm_bufmgr_flush; 00239 00240 mm->size = size; 00241 mm->align2 = align2; /* 64-byte alignment */ 00242 00243 pipe_mutex_init(mm->mutex); 00244 00245 mm->buffer = buffer; 00246 00247 mm->map = pb_map(mm->buffer, 00248 PIPE_BUFFER_USAGE_CPU_READ | 00249 PIPE_BUFFER_USAGE_CPU_WRITE); 00250 if(!mm->map) 00251 goto failure; 00252 00253 mm->heap = mmInit(0, size); 00254 if (!mm->heap) 00255 goto failure; 00256 00257 return SUPER(mm); 00258 00259 failure: 00260 if(mm->heap) 00261 mmDestroy(mm->heap); 00262 if(mm->map) 00263 pb_unmap(mm->buffer); 00264 if(mm) 00265 FREE(mm); 00266 return NULL; 00267 }
struct pb_manager* pb_alt_manager_create | ( | struct pb_manager * | provider1, | |
struct pb_manager * | provider2 | |||
) | [read] |
Definition at line 101 of file pb_bufmgr_alt.c.
References pb_alt_manager::base, CALLOC_STRUCT, pb_manager::create_buffer, pb_manager::destroy, pb_manager::flush, pb_alt_manager_create_buffer(), pb_alt_manager_destroy(), pb_alt_manager_flush(), pb_alt_manager::provider1, and pb_alt_manager::provider2.
00103 { 00104 struct pb_alt_manager *mgr; 00105 00106 if(!provider1 || !provider2) 00107 return NULL; 00108 00109 mgr = CALLOC_STRUCT(pb_alt_manager); 00110 if (!mgr) 00111 return NULL; 00112 00113 mgr->base.destroy = pb_alt_manager_destroy; 00114 mgr->base.create_buffer = pb_alt_manager_create_buffer; 00115 mgr->base.flush = pb_alt_manager_flush; 00116 mgr->provider1 = provider1; 00117 mgr->provider2 = provider2; 00118 00119 return &mgr->base; 00120 }
struct pb_manager* pb_cache_manager_create | ( | struct pb_manager * | provider, | |
unsigned | usecs | |||
) | [read] |
Time-based buffer cache.
This manager keeps a cache of destroyed buffers during a time interval.
Definition at line 342 of file pb_bufmgr_cache.c.
References pb_cache_manager::base, CALLOC_STRUCT, pb_manager::create_buffer, pb_cache_manager::delayed, pb_manager::destroy, pb_manager::flush, LIST_INITHEAD, pb_cache_manager::mutex, pb_cache_manager::numDelayed, pb_cache_manager_create_buffer(), pb_cache_manager_destroy(), pb_cache_manager_flush(), pipe_mutex_init, pb_cache_manager::provider, and pb_cache_manager::usecs.
00344 { 00345 struct pb_cache_manager *mgr; 00346 00347 if(!provider) 00348 return NULL; 00349 00350 mgr = CALLOC_STRUCT(pb_cache_manager); 00351 if (!mgr) 00352 return NULL; 00353 00354 mgr->base.destroy = pb_cache_manager_destroy; 00355 mgr->base.create_buffer = pb_cache_manager_create_buffer; 00356 mgr->base.flush = pb_cache_manager_flush; 00357 mgr->provider = provider; 00358 mgr->usecs = usecs; 00359 LIST_INITHEAD(&mgr->delayed); 00360 mgr->numDelayed = 0; 00361 pipe_mutex_init(mgr->mutex); 00362 00363 return &mgr->base; 00364 }
struct pb_manager* pb_debug_manager_create | ( | struct pb_manager * | provider, | |
size_t | band_size | |||
) | [read] |
Debug buffer manager to detect buffer under- and overflows.
Band size should be a multiple of the largest alignment
Definition at line 358 of file pb_bufmgr_debug.c.
struct pb_manager* pb_malloc_bufmgr_create | ( | void | ) | [read] |
Malloc buffer provider.
Simple wrapper around pb_malloc_buffer_create for convenience.
Definition at line 163 of file pb_buffer_malloc.c.
00164 { 00165 return &pb_malloc_bufmgr; 00166 }
struct pb_manager* pb_slab_manager_create | ( | struct pb_manager * | provider, | |
size_t | bufSize, | |||
size_t | slabSize, | |||
const struct pb_desc * | desc | |||
) | [read] |
Slab sub-allocator.
Definition at line 431 of file pb_bufmgr_slab.c.
References pb_slab_manager::base, pb_slab_manager::bufSize, CALLOC_STRUCT, pb_manager::create_buffer, pb_slab_manager::desc, pb_manager::destroy, pb_manager::flush, LIST_INITHEAD, pb_slab_manager::mutex, pb_slab_manager_create_buffer(), pb_slab_manager_destroy(), pb_slab_manager_flush(), pipe_mutex_init, pb_slab_manager::provider, pb_slab_manager::slabs, and pb_slab_manager::slabSize.
00435 { 00436 struct pb_slab_manager *mgr; 00437 00438 mgr = CALLOC_STRUCT(pb_slab_manager); 00439 if (!mgr) 00440 return NULL; 00441 00442 mgr->base.destroy = pb_slab_manager_destroy; 00443 mgr->base.create_buffer = pb_slab_manager_create_buffer; 00444 mgr->base.flush = pb_slab_manager_flush; 00445 00446 mgr->provider = provider; 00447 mgr->bufSize = bufSize; 00448 mgr->slabSize = slabSize; 00449 mgr->desc = *desc; 00450 00451 LIST_INITHEAD(&mgr->slabs); 00452 00453 pipe_mutex_init(mgr->mutex); 00454 00455 return &mgr->base; 00456 }
struct pb_manager* pb_slab_range_manager_create | ( | struct pb_manager * | provider, | |
size_t | minBufSize, | |||
size_t | maxBufSize, | |||
size_t | slabSize, | |||
const struct pb_desc * | desc | |||
) | [read] |
Allow a range of buffer size, by aggregating multiple slabs sub-allocators with different bucket sizes.
Definition at line 508 of file pb_bufmgr_slab.c.
References pb_slab_range_manager::base, pb_slab_range_manager::buckets, CALLOC, CALLOC_STRUCT, pb_manager::create_buffer, pb_manager::destroy, pb_manager::flush, FREE, pb_slab_range_manager::maxBufSize, pb_slab_range_manager::minBufSize, pb_slab_range_manager::numBuckets, pb_slab_manager_create(), pb_slab_range_manager_create_buffer(), pb_slab_range_manager_destroy(), pb_slab_range_manager_flush(), and pb_slab_range_manager::provider.
00513 { 00514 struct pb_slab_range_manager *mgr; 00515 size_t bufSize; 00516 unsigned i; 00517 00518 if(!provider) 00519 return NULL; 00520 00521 mgr = CALLOC_STRUCT(pb_slab_range_manager); 00522 if (!mgr) 00523 goto out_err0; 00524 00525 mgr->base.destroy = pb_slab_range_manager_destroy; 00526 mgr->base.create_buffer = pb_slab_range_manager_create_buffer; 00527 mgr->base.flush = pb_slab_range_manager_flush; 00528 00529 mgr->provider = provider; 00530 mgr->minBufSize = minBufSize; 00531 mgr->maxBufSize = maxBufSize; 00532 00533 mgr->numBuckets = 1; 00534 bufSize = minBufSize; 00535 while(bufSize < maxBufSize) { 00536 bufSize *= 2; 00537 ++mgr->numBuckets; 00538 } 00539 00540 mgr->buckets = CALLOC(mgr->numBuckets, sizeof(*mgr->buckets)); 00541 if (!mgr->buckets) 00542 goto out_err1; 00543 00544 bufSize = minBufSize; 00545 for (i = 0; i < mgr->numBuckets; ++i) { 00546 mgr->buckets[i] = pb_slab_manager_create(provider, bufSize, slabSize, desc); 00547 if(!mgr->buckets[i]) 00548 goto out_err2; 00549 bufSize *= 2; 00550 } 00551 00552 return &mgr->base; 00553 00554 out_err2: 00555 for (i = 0; i < mgr->numBuckets; ++i) 00556 if(mgr->buckets[i]) 00557 mgr->buckets[i]->destroy(mgr->buckets[i]); 00558 FREE(mgr->buckets); 00559 out_err1: 00560 FREE(mgr); 00561 out_err0: 00562 return NULL; 00563 }
struct pb_manager* pool_bufmgr_create | ( | struct pb_manager * | provider, | |
size_t | n, | |||
size_t | size, | |||
const struct pb_desc * | desc | |||
) | [read] |
Static buffer pool sub-allocator.
Manages the allocation of equally sized buffers. It does so by allocating a single big buffer and divide it equally sized buffers.
It is meant to manage the allocation of batch buffer pools.
Definition at line 230 of file pb_bufmgr_pool.c.
References pipe_buffer::alignment, pb_desc::alignment, pb_buffer::base, pool_buffer::base, pool_pb_manager::base, pool_pb_manager::bufAlign, pool_pb_manager::buffer, pool_pb_manager::bufs, pool_pb_manager::bufSize, CALLOC, CALLOC_STRUCT, pb_manager::create_buffer, pb_manager::destroy, pb_manager::flush, FREE, pool_pb_manager::free, pool_buffer::head, LIST_ADDTAIL, LIST_INITHEAD, pool_pb_manager::map, pool_buffer::mgr, pool_pb_manager::mutex, pool_pb_manager::numFree, pool_pb_manager::numTot, pb_map(), pb_reference(), pb_unmap(), PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_mutex_init, pool_bufmgr_create_buffer(), pool_bufmgr_destroy(), pool_bufmgr_flush(), pipe_buffer::refcount, pipe_buffer::size, pool_buffer::start, SUPER, pipe_buffer::usage, and pb_buffer::vtbl.
00234 { 00235 struct pool_pb_manager *pool; 00236 struct pool_buffer *pool_buf; 00237 size_t i; 00238 00239 if(!provider) 00240 return NULL; 00241 00242 pool = CALLOC_STRUCT(pool_pb_manager); 00243 if (!pool) 00244 return NULL; 00245 00246 pool->base.destroy = pool_bufmgr_destroy; 00247 pool->base.create_buffer = pool_bufmgr_create_buffer; 00248 pool->base.flush = pool_bufmgr_flush; 00249 00250 LIST_INITHEAD(&pool->free); 00251 00252 pool->numTot = numBufs; 00253 pool->numFree = numBufs; 00254 pool->bufSize = bufSize; 00255 pool->bufAlign = desc->alignment; 00256 00257 pipe_mutex_init(pool->mutex); 00258 00259 pool->buffer = provider->create_buffer(provider, numBufs*bufSize, desc); 00260 if (!pool->buffer) 00261 goto failure; 00262 00263 pool->map = pb_map(pool->buffer, 00264 PIPE_BUFFER_USAGE_CPU_READ | 00265 PIPE_BUFFER_USAGE_CPU_WRITE); 00266 if(!pool->map) 00267 goto failure; 00268 00269 pool->bufs = (struct pool_buffer *)CALLOC(numBufs, sizeof(*pool->bufs)); 00270 if (!pool->bufs) 00271 goto failure; 00272 00273 pool_buf = pool->bufs; 00274 for (i = 0; i < numBufs; ++i) { 00275 pool_buf->base.base.refcount = 0; 00276 pool_buf->base.base.alignment = 0; 00277 pool_buf->base.base.usage = 0; 00278 pool_buf->base.base.size = bufSize; 00279 pool_buf->base.vtbl = &pool_buffer_vtbl; 00280 pool_buf->mgr = pool; 00281 pool_buf->start = i * bufSize; 00282 LIST_ADDTAIL(&pool_buf->head, &pool->free); 00283 pool_buf++; 00284 } 00285 00286 return SUPER(pool); 00287 00288 failure: 00289 if(pool->bufs) 00290 FREE(pool->bufs); 00291 if(pool->map) 00292 pb_unmap(pool->buffer); 00293 if(pool->buffer) 00294 pb_reference(&pool->buffer, NULL); 00295 if(pool) 00296 FREE(pool); 00297 return NULL; 00298 }