Lines Matching refs:pool

49 // info about pool
67 int enlarge_by; // number of blocks to enlarge pool by
96 #define NEXT_PTR(pool, a) ((void **)(((char *)a) + pool->next_ofs))
99 /*! Enlarge memory pool by <num_block> blocks */
101 enlarge_pool(locked_pool *pool, int numBlocks)
115 chunkSize = numBlocks * pool->block_size + pool->header_size;
118 status = area = create_area(pool->name,
120 pool->lock_flags, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
122 dprintf("cannot enlarge pool (%s)\n", strerror(status));
137 lastBlock = (char *)chunk + pool->header_size +
138 (numBlocks-1) * pool->block_size;
141 ++i, block = (char *)block - pool->block_size)
143 if (pool->add_hook) {
144 if ((status = pool->add_hook(block, pool->hook_arg)) < B_OK)
148 *NEXT_PTR(pool, block) = next;
158 block = (char *)block - pool->block_size) {
159 if (pool->remove_hook)
160 pool->remove_hook(block, pool->hook_arg);
169 // add new blocks to pool
170 mutex_lock(&pool->mutex);
173 *NEXT_PTR(pool, lastBlock) = pool->free_list;
174 pool->free_list = next;
176 chunk->next = pool->chunks;
177 pool->chunks = chunk;
179 pool->num_blocks += numBlocks;
180 pool->free_blocks += numBlocks;
183 pool->num_blocks, pool->free_blocks, pool->num_waiting));
185 numWaiting = min_c(pool->num_waiting, numBlocks);
186 pool->num_waiting -= numWaiting;
188 mutex_unlock(&pool->mutex);
191 release_sem_etc(pool->sem, numWaiting, 0);
197 /*! Background thread that adjusts pool size */
202 locked_pool *pool;
210 // block destroy_pool() to not clean up a pool we are enlarging
213 for (pool = sLockedPools; pool; pool = pool->next) {
219 mutex_lock(&pool->mutex);
220 num_free = pool->free_blocks;
221 mutex_unlock(&pool->mutex);
223 // perhaps blocks got freed meanwhile, i.e. pool is large enough
224 if (num_free > pool->min_free_blocks)
227 // enlarge pool as much as possible
230 if (pool->num_blocks < pool->max_blocks) {
231 enlarge_pool(pool,
232 min(pool->enlarge_by, pool->max_blocks - pool->num_blocks));
243 /*! Free all chunks belonging to pool */
245 free_chunks(locked_pool *pool)
249 for (chunk = pool->chunks; chunk; chunk = next) {
255 lastBlock = (char *)chunk + pool->header_size +
256 (chunk->num_blocks-1) * pool->block_size;
259 for (i = 0, block = lastBlock; i < pool->num_blocks; ++i, block = (char *)block - pool->block_size) {
260 if (pool->remove_hook)
261 pool->remove_hook(block, pool->hook_arg);
267 pool->chunks = NULL;
323 /*! Alloc memory from pool */
325 pool_alloc(locked_pool *pool)
331 mutex_lock(&pool->mutex);
333 --pool->free_blocks;
335 if (pool->free_blocks > 0) {
339 pool->free_blocks, pool->free_list));
341 block = pool->free_list;
342 pool->free_list = *NEXT_PTR(pool, block);
344 TRACE(("new free_list=%p\n", pool->free_list));
346 mutex_unlock(&pool->mutex);
350 // entire pool is in use
359 ++pool->num_waiting;
361 TRACE(("%d waiting allocs\n", pool->num_waiting));
363 mutex_unlock(&pool->mutex);
368 acquire_sem(pool->sem);
370 mutex_lock(&pool->mutex);
372 TRACE(("continuing alloc (%d free blocks)\n", pool->free_blocks));
374 block = pool->free_list;
375 pool->free_list = *NEXT_PTR(pool, block);
377 mutex_unlock(&pool->mutex);
383 pool_free(locked_pool *pool, void *block)
387 mutex_lock(&pool->mutex);
390 *NEXT_PTR(pool, block) = pool->free_list;
391 pool->free_list = block;
393 ++pool->free_blocks;
395 TRACE(("freeblocks=%d, free_list=%p\n", pool->free_blocks,
396 pool->free_list));
398 if (pool->num_waiting == 0) {
400 mutex_unlock(&pool->mutex);
406 TRACE(("%d waiting allocs\n", pool->num_waiting));
407 pool->num_waiting--;
409 mutex_unlock(&pool->mutex);
412 release_sem(pool->sem);
424 locked_pool *pool;
429 pool = (locked_pool *)malloc(sizeof(*pool));
430 if (pool == NULL)
433 memset(pool, 0, sizeof(*pool));
435 mutex_init(&pool->mutex, "locked_pool");
437 if ((status = pool->sem = create_sem(0, "locked_pool")) < 0)
440 if ((pool->name = strdup(name)) == NULL) {
445 pool->alignment = alignment;
448 pool->block_size = (block_size + pool->alignment) & ~pool->alignment;
450 pool->next_ofs = next_ofs;
451 pool->lock_flags = lock_flags;
453 pool->header_size = max((sizeof( chunk_header ) + pool->alignment) & ~pool->alignment,
454 pool->alignment + 1);
456 pool->enlarge_by = (((chunkSize + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1)) - pool->header_size)
457 / pool->block_size;
459 pool->max_blocks = max_blocks;
460 pool->min_free_blocks = min_free_blocks;
461 pool->free_blocks = 0;
462 pool->num_blocks = 0;
463 pool->num_waiting = 0;
464 pool->free_list = NULL;
465 pool->add_hook = add_hook;
466 pool->remove_hook = remove_hook;
467 pool->hook_arg = hook_arg;
468 pool->chunks = NULL;
471 (int)pool->block_size, (int)pool->alignment, (int)pool->next_ofs,
472 (int)pool->lock_flags, (int)pool->header_size, pool->enlarge_by));
474 // if there is a minimum size, enlarge pool right now
476 if ((status = enlarge_pool(pool, min(pool->enlarge_by, pool->max_blocks))) < 0)
480 // add to global list, so enlarger thread takes care of pool
482 ADD_DL_LIST_HEAD(pool, sLockedPools, );
485 return pool;
488 free(pool->name);
490 delete_sem(pool->sem);
492 mutex_destroy(&pool->mutex);
493 free(pool);
499 destroy_pool(locked_pool *pool)
504 // won't touch this pool anymore
506 REMOVE_DL_LIST(pool, sLockedPools, );
509 // then cleanup pool
510 free_chunks(pool);
512 free(pool->name);
513 delete_sem(pool->sem);
514 mutex_destroy(&pool->mutex);
516 free(pool);