-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create generic pool & use it for context , lines
- Loading branch information
Showing
10 changed files
with
247 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include "generic_pool.h" | ||
#include "utils/mathutils.h" | ||
#include "ww.h" | ||
|
||
#define GENERIC_POOL_DEFAULT_WIDTH ((unsigned long) ((16 * ram_profile))) | ||
|
||
extern void poolReCharge(generic_pool_t *pool); | ||
extern void poolShrink(generic_pool_t *pool); | ||
extern pool_item_t *popPoolItem(generic_pool_t *pool); | ||
extern void reusePoolItem(generic_pool_t *pool, pool_item_t *b); | ||
|
||
static void poolFirstCharge(generic_pool_t *pool) | ||
{ | ||
pool->len = pool->cap / 2; | ||
for (size_t i = 0; i < pool->len; i++) | ||
{ | ||
pool->available[i] = pool->create_item_handle(pool); | ||
} | ||
} | ||
|
||
static generic_pool_t *allocateGenericPool(unsigned long pool_width, PoolItemCreateHandle create_h, | ||
PoolItemDestroyHandle destroy_h) | ||
{ | ||
|
||
pool_width = (unsigned long) pow(2, floor(log2((double) (max(16, (ssize_t) pool_width))))); | ||
// half of the pool is used, other half is free at startup | ||
pool_width = 2 * pool_width; | ||
|
||
const unsigned long container_len = pool_width * sizeof(pool_item_t *); | ||
generic_pool_t *pool = malloc(sizeof(generic_pool_t) + container_len); | ||
#ifdef DEBUG | ||
memset(pool, 0xEE, sizeof(generic_pool_t) + container_len); | ||
#endif | ||
memset(pool, 0, sizeof(generic_pool_t)); | ||
pool->cap = pool_width; | ||
pool->free_threshould = (pool->cap * 2) / 3; | ||
pool->create_item_handle = create_h; | ||
pool->destroy_item_handle = destroy_h; | ||
poolFirstCharge(pool); | ||
return pool; | ||
} | ||
|
||
generic_pool_t *newGenericPool(PoolItemCreateHandle create_h, PoolItemDestroyHandle destroy_h) | ||
{ | ||
return allocateGenericPool(GENERIC_POOL_DEFAULT_WIDTH, create_h, destroy_h); | ||
} | ||
generic_pool_t *newGenericPoolWithSize(unsigned long pool_width, PoolItemCreateHandle create_h, | ||
PoolItemDestroyHandle destroy_h) | ||
{ | ||
return allocateGenericPool(pool_width, create_h, destroy_h); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#pragma once | ||
#include <stdatomic.h> | ||
#include <stddef.h> | ||
#ifdef OS_UNIX | ||
#include <malloc.h> | ||
#endif | ||
|
||
/* | ||
A growable pool, very simple. | ||
preallocates (n) number of buffers at each call to charge(), | ||
recharing is done autmatically and internally. | ||
pool width is affected by ww memory profile | ||
when DEBUG is true, you can: | ||
define POOL_DEBUG to view debug logs about how many itmes are in use or in pool | ||
define BYPASS_POOL to bypass the pool for your debug goals or leak finding | ||
*/ | ||
|
||
struct generic_pool_s; | ||
|
||
typedef void pool_item_t; | ||
typedef pool_item_t *(*PoolItemCreateHandle)(struct generic_pool_s *pool); | ||
typedef void (*PoolItemDestroyHandle)(struct generic_pool_s *pool, pool_item_t *item); | ||
|
||
#if defined(DEBUG) && defined(POOL_DEBUG) | ||
#define GENERIC_POOL_FIELDS \ | ||
unsigned int len; \ | ||
unsigned int cap; \ | ||
unsigned int free_threshould; \ | ||
atomic_size_t in_use; \ | ||
PoolItemCreateHandle create_item_handle; \ | ||
PoolItemDestroyHandle destroy_item_handle; \ | ||
pool_item_t *available[]; | ||
#else | ||
|
||
#define GENERIC_POOL_FIELDS \ | ||
unsigned int len; \ | ||
unsigned int cap; \ | ||
unsigned int free_threshould; \ | ||
PoolItemCreateHandle create_item_handle; \ | ||
PoolItemDestroyHandle destroy_item_handle; \ | ||
pool_item_t *available[]; | ||
|
||
#endif | ||
|
||
struct generic_pool_s | ||
{ | ||
GENERIC_POOL_FIELDS | ||
}; | ||
|
||
typedef struct generic_pool_s generic_pool_t; | ||
|
||
inline void poolReCharge(generic_pool_t *pool) | ||
{ | ||
const size_t increase = ((pool->cap - pool->len) < (pool->cap) / 2 ? (pool->cap - pool->len) : (pool->cap / 2)); | ||
|
||
for (size_t i = pool->len; i < (pool->len + increase); i++) | ||
{ | ||
pool->available[i] = pool->create_item_handle(pool); | ||
} | ||
pool->len += increase; | ||
#if defined(DEBUG) && defined(POOL_DEBUG) | ||
LOGD("BufferPool: allocated %d new buffers, %zu are in use", increase, pool->in_use); | ||
#endif | ||
} | ||
|
||
inline void poolShrink(generic_pool_t *pool) | ||
{ | ||
const size_t decrease = (pool->len < (pool->cap / 2) ? pool->len : (pool->cap / 2)); | ||
|
||
for (size_t i = pool->len - decrease; i < pool->len; i++) | ||
{ | ||
pool->destroy_item_handle(pool, pool->available[i]); | ||
} | ||
pool->len -= decrease; | ||
|
||
#if defined(DEBUG) && defined(POOL_DEBUG) | ||
LOGD("BufferPool: freed %d buffers, %zu are in use", decrease, pool->in_use); | ||
#endif | ||
#ifdef OS_UNIX | ||
malloc_trim(0); | ||
#endif | ||
} | ||
|
||
inline pool_item_t *popPoolItem(generic_pool_t *pool) | ||
{ | ||
#if defined(DEBUG) && defined(BYPASS_POOL) | ||
return pool->create_item_handle(pool); | ||
#endif | ||
|
||
if (pool->len <= 0) | ||
{ | ||
poolReCharge(pool); | ||
} | ||
|
||
#if defined(DEBUG) && defined(POOL_DEBUG) | ||
pool->in_use += 1; | ||
#endif | ||
--(pool->len); | ||
return pool->available[pool->len]; | ||
} | ||
|
||
inline void reusePoolItem(generic_pool_t *pool, pool_item_t *b) | ||
{ | ||
#if defined(DEBUG) && defined(BYPASS_POOL) | ||
pool->destroy_item_handle(pool, b); | ||
return; | ||
#endif | ||
|
||
#if defined(DEBUG) && defined(POOL_DEBUG) | ||
pool->in_use -= 1; | ||
#endif | ||
if (pool->len > pool->free_threshould) | ||
{ | ||
poolShrink(pool); | ||
} | ||
|
||
pool->available[(pool->len)++] = b; | ||
} | ||
|
||
generic_pool_t *newGenericPool(PoolItemCreateHandle create_h, PoolItemDestroyHandle destroy_h); | ||
generic_pool_t *newGenericPoolWithSize(unsigned long pool_width, PoolItemCreateHandle create_h, | ||
PoolItemDestroyHandle destroy_h); | ||
|
||
#undef BYPASS_POOL | ||
#undef POOL_DEBUG |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.