add debug, bits, and pool
This commit is contained in:
167
c/bits.h
Normal file
167
c/bits.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/* bits.h - bits functions.
|
||||
*
|
||||
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*
|
||||
*/
|
||||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* next include will define __WORDSIZE: 32 or 64
|
||||
*/
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
/* no plan to support 32bits for now...
|
||||
*/
|
||||
#if __WORDSIZE != 64
|
||||
ERROR_64_BYTES_WORDSIZE_ONLY
|
||||
#endif
|
||||
|
||||
typedef int64_t s64;
|
||||
typedef int32_t s32;
|
||||
typedef int16_t s16;
|
||||
typedef int8_t s8;
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char uchar;
|
||||
|
||||
/* count trailing zeroes : 00101000 -> 3
|
||||
* ^^^
|
||||
*/
|
||||
static inline int ctz64(u64 n)
|
||||
{
|
||||
# if __has_builtin(__builtin_ctzl)
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "builtin ctzl.\n");
|
||||
# endif
|
||||
return __builtin_ctzl(n);
|
||||
|
||||
# elif __has_builtin(__builtin_clzl)
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "builtin clzl.\n");
|
||||
# endif
|
||||
return __WORDSIZE - (__builtin_clzl(n & -n) + 1);
|
||||
|
||||
# else
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "emulated.\n");
|
||||
# endif
|
||||
return popcount64((n & −n) − 1);
|
||||
# endif
|
||||
}
|
||||
|
||||
/* count leading zeroes : 00101000 -> 2
|
||||
* ^^
|
||||
*/
|
||||
static inline int clz64(u64 n)
|
||||
{
|
||||
# if __has_builtin(__builtin_clzl)
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "builtin.\n");
|
||||
# endif
|
||||
return __builtin_clzl(n);
|
||||
|
||||
# else
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "emulated.\n");
|
||||
# endif
|
||||
u64 r, q;
|
||||
|
||||
r = (n > 0xFFFFFFFF) << 5; n >>= r;
|
||||
q = (n > 0xFFFF) << 4; n >>= q; r |= q;
|
||||
q = (n > 0xFF ) << 3; n >>= q; r |= q;
|
||||
q = (n > 0xF ) << 2; n >>= q; r |= q;
|
||||
q = (n > 0x3 ) << 1; n >>= q; r |= q;
|
||||
r |= (n >> 1);
|
||||
return __WORDSIZE - r - 1;
|
||||
# endif
|
||||
}
|
||||
|
||||
/* find first set : 00101000 -> 4
|
||||
* ^
|
||||
*/
|
||||
static inline uint ffs64(u64 n)
|
||||
{
|
||||
# if __has_builtin(__builtin_ffsl)
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "builtin ffsl.\n");
|
||||
# endif
|
||||
return __builtin_ffsll(n);
|
||||
|
||||
# elif __has_builtin(__builtin_ctzl)
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "builtin ctzl.\n");
|
||||
# endif
|
||||
if (n == 0)
|
||||
return (0);
|
||||
return __builtin_ctzl(n) + 1;
|
||||
|
||||
# else
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "emulated.\n");
|
||||
# endif
|
||||
return popcount64(n ^ ~-n);
|
||||
# endif
|
||||
}
|
||||
|
||||
static inline int popcount64(u64 n)
|
||||
{
|
||||
# if __has_builtin(__builtin_popcountl)
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "builtin.\n");
|
||||
# endif
|
||||
return __builtin_popcountl(n);
|
||||
|
||||
# else
|
||||
# ifdef DEBUG_BITS
|
||||
log_f(1, "emulated.\n");
|
||||
# endif
|
||||
int count = 0;
|
||||
while (n) {
|
||||
count++;
|
||||
n &= (n - 1);
|
||||
}
|
||||
return count;
|
||||
# endif
|
||||
}
|
||||
|
||||
/** bit_for_each64 - iterate over an u64 bits
|
||||
* @pos: an int used as current bit
|
||||
* @tmp: a temp u64 used as temporary storage
|
||||
* @ul: the u64 to loop over
|
||||
*
|
||||
* Usage:
|
||||
* u64 u=139, _t; // u=b10001011
|
||||
* int cur;
|
||||
* bit_for_each64(cur, _t, u) {
|
||||
* printf("%d\n", cur);
|
||||
* }
|
||||
* This will display the position of each bit set in ul: 1, 2, 4, 8
|
||||
*
|
||||
* I should probably re-think the implementation...
|
||||
*/
|
||||
#define bit_for_each64(pos, tmp, ul) \
|
||||
for (tmp = ul, pos = ffs64(tmp); tmp; tmp &= (tmp - 1), pos = ffs64(tmp))
|
||||
|
||||
/** or would it be more useful (counting bits from zero instead of 1) ?
|
||||
*/
|
||||
#define bit_for_each64_2(pos, tmp, ul) \
|
||||
for (tmp = ul, pos = ctz64(tmp); tmp; tmp ^= 1<<pos, pos = ctz64(tmp))
|
||||
|
||||
#endif /* BITS_H */
|
111
c/debug.c
Normal file
111
c/debug.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/* debug.c - debug/log management
|
||||
*
|
||||
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef DEBUG_DEBUG
|
||||
#define DEBUG_DEBUG
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define NANOSEC 1000000000 /* nano sec in sec */
|
||||
#define MILLISEC 1000000 /* milli sec in sec */
|
||||
|
||||
static s64 timer_start; /* in nanosecond */
|
||||
static u32 debug_level=0;
|
||||
|
||||
void debug_level_set(u32 level)
|
||||
{
|
||||
debug_level = level;
|
||||
|
||||
log(1, "debug level set to %u\n", level);
|
||||
}
|
||||
|
||||
void debug_init(u32 level)
|
||||
{
|
||||
struct timespec timer;
|
||||
|
||||
debug_level_set(level);
|
||||
if (!clock_gettime(CLOCK_MONOTONIC, &timer)) {
|
||||
timer_start = timer.tv_sec * NANOSEC + timer.tv_nsec;
|
||||
}
|
||||
else {
|
||||
timer_start = 0;
|
||||
}
|
||||
log(0, "timer started.\n");
|
||||
}
|
||||
|
||||
inline static s64 timer_elapsed()
|
||||
{
|
||||
struct timespec timer;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &timer);
|
||||
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
|
||||
}
|
||||
|
||||
|
||||
/* void debug - log function
|
||||
* @timestamp : boolean
|
||||
* @indent : indent level (2 spaces each)
|
||||
* @src : source file/func name (or NULL)
|
||||
* @line : line number
|
||||
*/
|
||||
void debug(u32 level, bool timestamp, u32 indent, const char *src,
|
||||
u32 line, const char *fmt, ...)
|
||||
{
|
||||
if (level > debug_level)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
|
||||
if (indent)
|
||||
printf("%*s", 2*(indent-1), "");
|
||||
|
||||
if (timestamp) {
|
||||
s64 diff = timer_elapsed();
|
||||
printf("%ld.%03ld ", diff/NANOSEC, (diff/1000000)%1000);
|
||||
printf("%010ld ", diff);
|
||||
}
|
||||
|
||||
if (src) {
|
||||
if (line)
|
||||
printf("[%s:%u] ", src, line);
|
||||
else
|
||||
printf("[%s] ", src);
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef BIN_debug
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int foo=1;
|
||||
debug_init(5);
|
||||
|
||||
log(0, "log0=%d\n", foo++);
|
||||
log(1, "log1=%d\n", foo++);
|
||||
log(2, "log2=%d\n", foo++);
|
||||
log_i(2, "log_i 2=%d\n", foo++);
|
||||
log_i(5, "log_i 5=%d\n", foo++);
|
||||
log_i(6, "log_i 6=%d\n", foo++);
|
||||
log_it(4, "log_it 4=%d\n", foo++);
|
||||
log_f(1, "log_f 5=%d\n", foo++);
|
||||
}
|
||||
#endif
|
83
c/debug.h
Normal file
83
c/debug.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* move.h - debug/log management.
|
||||
*
|
||||
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bits.h"
|
||||
|
||||
#ifdef DEBUG_DEBUG
|
||||
void debug_init(u32 level);
|
||||
void debug_level_set(u32 level);
|
||||
void debug_devel_set(u32 level);
|
||||
void debug(u32 level, bool timestamp, u32 indent,
|
||||
const char *src, u32 line, const char *, ...);
|
||||
#else /* DEBUG_DEBUG */
|
||||
#define _unused __attribute__((__unused__))
|
||||
static inline void debug_init(_unused u32 level) {}
|
||||
static inline void debug_level_set(_unused u32 level) {}
|
||||
static inline void debug_devel_set(_unused u32 level) {}
|
||||
static inline void debug(_unused u32 level, _unused bool timestamp,
|
||||
_unused u32 indent, _unused const char *src,
|
||||
_unused u32 line, const char *, ...) {}
|
||||
#undef _unused
|
||||
#endif /* DEBUG_DEBUG */
|
||||
|
||||
/* format: only printf
|
||||
*/
|
||||
#define log(level, fmt, args...) \
|
||||
debug((level), false, 0, NULL, 0, fmt, ##args)
|
||||
|
||||
/* format : indent, no func name, no timestamp
|
||||
* >>>>val=2
|
||||
*/
|
||||
#define log_i(level, fmt, args...) \
|
||||
debug((level), false, (level), NULL, 0, fmt, ##args)
|
||||
|
||||
/* format : func name, no indent, no timestamp
|
||||
* [foo] val=2
|
||||
*/
|
||||
#define log_f(level, fmt, args...) \
|
||||
debug((level), false, 0, __func__, 0, fmt, ##args)
|
||||
|
||||
/* format : func name, no indent, no timestamp
|
||||
* >>>> [foo:15] val=2
|
||||
*/
|
||||
#define log_if(level, fmt, args...) \
|
||||
debug((level), false, (level), __func__, __LINE__, fmt, ##args)
|
||||
|
||||
/* format : func name, indent, timestamp
|
||||
* >>>>foo:15 val=2
|
||||
*/
|
||||
#define log_it(level, fmt, args...) \
|
||||
debug((level), true, (level), __func__, __LINE__, fmt, ##args)
|
||||
|
||||
/* format: file name, no indent, no timestamp
|
||||
* foo:15 val=2
|
||||
*
|
||||
* #define log_f(level, fmt, args...) \
|
||||
* debug((level), false, 0, __FILE__, __LINE__, fmt, args)
|
||||
*/
|
||||
|
||||
#else
|
||||
#define log(level, fmt, args...)
|
||||
#define log_i(...)
|
||||
#define log_f(...)
|
||||
#define log_if(...)
|
||||
#define log_it(...)
|
||||
#define log_f(...)
|
||||
|
||||
#endif /* DEBUG_H */
|
216
c/pool.c
Normal file
216
c/pool.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/* pool.c - A simple pool manager.
|
||||
*
|
||||
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
#include "debug.h"
|
||||
#include "bits.h"
|
||||
|
||||
void pool_stats(pool_t *pool)
|
||||
{
|
||||
if (pool) {
|
||||
# ifdef DEBUG_POOL
|
||||
block_t *block;
|
||||
|
||||
log_f(1, "[%s] pool [%p]: blocks:%u avail:%u alloc:%u grow:%u eltsize:%lu\n",
|
||||
pool->name, (void *)pool, pool->nblocks, pool->available, pool->allocated,
|
||||
pool->growsize, pool->eltsize);
|
||||
log(5, "\tblocks: ");
|
||||
list_for_each_entry(block, &pool->list_blocks, list_blocks) {
|
||||
log(5, "%p ", block);
|
||||
}
|
||||
log(5, "\n");
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
pool_t *pool_create(const char *name, u32 growsize, size_t eltsize)
|
||||
{
|
||||
pool_t *pool;
|
||||
|
||||
# ifdef DEBUG_POOL
|
||||
log_f(1, "name=[%s] growsize=%u eltsize=%lu\n",
|
||||
name, growsize, eltsize);
|
||||
# endif
|
||||
/* we need at least this space in struct */
|
||||
if (eltsize < sizeof (struct list_head))
|
||||
return NULL;
|
||||
if ((pool = malloc(sizeof (*pool)))) {
|
||||
strncpy(pool->name, name, POOL_NAME_LENGTH - 1);
|
||||
pool->name[POOL_NAME_LENGTH - 1] = 0;
|
||||
pool->growsize = growsize;
|
||||
pool->eltsize = eltsize;
|
||||
pool->available = 0;
|
||||
pool->allocated = 0;
|
||||
pool->nblocks = 0;
|
||||
INIT_LIST_HEAD(&pool->list_available);
|
||||
INIT_LIST_HEAD(&pool->list_blocks);
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
static u32 _pool_add(pool_t *pool, struct list_head *elt)
|
||||
{
|
||||
# ifdef DEBUG_POOL
|
||||
log_f(6, "pool=%p &head=%p elt=%p off1=%lu off2=%lu\n",
|
||||
(void *)pool,
|
||||
(void *)&pool->list_available,
|
||||
(void *)elt,
|
||||
(void *)&pool->list_available-(void *)pool,
|
||||
offsetof(pool_t, list_available));
|
||||
# endif
|
||||
|
||||
list_add(elt, &pool->list_available);
|
||||
return ++pool->available;
|
||||
}
|
||||
|
||||
u32 pool_add(pool_t *pool, void *elt)
|
||||
{
|
||||
return _pool_add(pool, elt);
|
||||
}
|
||||
|
||||
static struct list_head *_pool_get(pool_t *pool)
|
||||
{
|
||||
struct list_head *res = pool->list_available.next;
|
||||
pool->available--;
|
||||
list_del(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void *pool_get(pool_t *pool)
|
||||
{
|
||||
if (!pool)
|
||||
return NULL;
|
||||
if (!pool->available) {
|
||||
block_t *block = malloc(sizeof(block_t) + pool->eltsize * pool->growsize);
|
||||
void *cur;
|
||||
u32 i;
|
||||
|
||||
if (!block) {
|
||||
# ifdef DEBUG_POOL
|
||||
log_f(1, "[%s]: failed block allocation\n");
|
||||
# endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* maintain list of allocated blocks
|
||||
*/
|
||||
list_add(&block->list_blocks, &pool->list_blocks);
|
||||
pool->nblocks++;
|
||||
|
||||
# ifdef DEBUG_POOL
|
||||
log_f(1, "[%s]: growing pool from %u to %u elements. block=%p nblocks=%u\n",
|
||||
pool->name,
|
||||
pool->allocated,
|
||||
pool->allocated + pool->growsize,
|
||||
block,
|
||||
pool->nblocks);
|
||||
# endif
|
||||
|
||||
pool->allocated += pool->growsize;
|
||||
for (i = 0; i < pool->growsize; ++i) {
|
||||
cur = block->data + i * pool->eltsize;
|
||||
# ifdef DEBUG_POOL
|
||||
log_f(7, "alloc=%p cur=%p\n", block, cur);
|
||||
# endif
|
||||
_pool_add(pool, (struct list_head *)cur);
|
||||
}
|
||||
//pool_stats(pool);
|
||||
}
|
||||
/* this is the effective address if the object (and also the
|
||||
* pool list_head address)
|
||||
*/
|
||||
return _pool_get(pool);
|
||||
}
|
||||
|
||||
void pool_destroy(pool_t *pool)
|
||||
{
|
||||
block_t *block, *tmp;
|
||||
if (!pool)
|
||||
return;
|
||||
/* release memory blocks */
|
||||
# ifdef DEBUG_POOL
|
||||
log_f(1, "[%s]: releasing %d blocks and main structure\n", pool->name, pool->nblocks);
|
||||
log(5, "blocks:");
|
||||
# endif
|
||||
list_for_each_entry_safe(block, tmp, &pool->list_blocks, list_blocks) {
|
||||
list_del(&block->list_blocks);
|
||||
free(block);
|
||||
# ifdef DEBUG_POOL
|
||||
log(5, " %p", block);
|
||||
# endif
|
||||
}
|
||||
# ifdef DEBUG_POOL
|
||||
log(5, "\n");
|
||||
# endif
|
||||
free(pool);
|
||||
}
|
||||
|
||||
#ifdef BIN_pool
|
||||
struct d {
|
||||
u16 data1;
|
||||
char c;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static LIST_HEAD (head);
|
||||
|
||||
int main(int ac, char**av)
|
||||
{
|
||||
pool_t *pool;
|
||||
int total;
|
||||
int action=0;
|
||||
u16 icur=0;
|
||||
char ccur='z';
|
||||
struct d *elt;
|
||||
|
||||
debug_init(3);
|
||||
log_f(1, "%s: sizeof(d)=%lu sizeof(*d)=%lu off=%lu\n", *av, sizeof(elt),
|
||||
sizeof(*elt), offsetof(struct d, list));
|
||||
|
||||
if ((pool = pool_create("dummy", 3, sizeof(*elt)))) {
|
||||
pool_stats(pool);
|
||||
for (int cur=1; cur<ac; ++cur) {
|
||||
total = atoi(av[cur]);
|
||||
if (action == 0) { /* add elt to list */
|
||||
log_f(2, "adding %d elements\n", total);
|
||||
for (int i = 0; i < total; ++i) {
|
||||
elt = pool_get(pool);
|
||||
elt->data1 = icur++;
|
||||
elt->c = ccur--;
|
||||
list_add(&elt->list, &head);
|
||||
}
|
||||
pool_stats(pool);
|
||||
action = 1;
|
||||
} else { /* remove one elt from list */
|
||||
log_f(2, "deleting %d elements\n", total);
|
||||
for (int i = 0; i < total; ++i) {
|
||||
if (!list_empty(&head)) {
|
||||
elt = list_last_entry(&head, struct d, list);
|
||||
printf("elt=[%d, %c]\n", elt->data1, elt->c);
|
||||
list_del(&elt->list);
|
||||
pool_add(pool, elt);
|
||||
}
|
||||
}
|
||||
pool_stats(pool);
|
||||
action = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
pool_stats(pool);
|
||||
}
|
||||
#endif
|
77
c/pool.h
Normal file
77
c/pool.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* pool.h - A simple memory pool manager.
|
||||
*
|
||||
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef POOL_H
|
||||
#define POOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "list.h"
|
||||
#include "bits.h"
|
||||
|
||||
#define POOL_NAME_LENGTH (16) /* max name length including trailing \0 */
|
||||
|
||||
typedef struct {
|
||||
struct list_head list_blocks; /* list of allocated blocks in pool */
|
||||
char data[]; /* objects block */
|
||||
} block_t;
|
||||
|
||||
typedef struct {
|
||||
char name[POOL_NAME_LENGTH]; /* pool name */
|
||||
u32 available; /* current available elements */
|
||||
u32 allocated; /* total objects allocated */
|
||||
u32 growsize; /* number of objects per block allocated */
|
||||
size_t eltsize; /* object size */
|
||||
u32 nblocks; /* number of blocks allocated */
|
||||
struct list_head list_available; /* available nodes */
|
||||
struct list_head list_blocks; /* allocated blocks */
|
||||
} pool_t;
|
||||
|
||||
/**
|
||||
* pool_stats - display some pool statistics
|
||||
* @pool: the pool address.
|
||||
*/
|
||||
void pool_stats(pool_t *pool);
|
||||
|
||||
/**
|
||||
* pool_create - create a new memory pool
|
||||
* @name: the name to give to the pool.
|
||||
* @grow: the number of elements to add when no more available.
|
||||
* @size: the size of an element in pool.
|
||||
*/
|
||||
pool_t *pool_create(const char *name, u32 grow, size_t size);
|
||||
|
||||
/**
|
||||
* pool_get - get an element from a pool
|
||||
* @pool: the pool address.
|
||||
*/
|
||||
void *pool_get(pool_t *pool);
|
||||
|
||||
/**
|
||||
* pool_add - add (release) an element to a pool
|
||||
* @pool: the pool address.
|
||||
* @elt: the address of the object to add to the pool.
|
||||
*/
|
||||
u32 pool_add(pool_t *pool, void *elt);
|
||||
|
||||
/**
|
||||
* pool_destroy - destroy a pool.
|
||||
* @pool: the pool address.
|
||||
*
|
||||
* Attention: All memory is freed, but no check is done whether all pool
|
||||
* elements has been released. Referencing any pool object after this call
|
||||
* is strongly discouraged.
|
||||
*/
|
||||
void pool_destroy(pool_t *pool);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user