#ifndef _MEMMAN_H_
#define _MEMMAN_H_
#include <sys/param.h>
#include <sys/queue.h>
struct memman_block {
LIST_ENTRY(memman_block) links;
void *block;
unsigned static_mem;
unsigned int allocated;
unsigned int available;
unsigned int allocated_mem;
};
LIST_HEAD(memman_block_list, memman_block);
struct memman_node {
LIST_ENTRY(memman_node) links;
void *node;
struct memman_block *memblock;
};
LIST_HEAD(memman_node_list, memman_node);
extern unsigned int memid_unkown;
struct memman_blockman {
unsigned int size;
unsigned int available;
void *initial_block;
unsigned initialized;
struct memman_block_list block_list;
struct memman_node_list free_node_list;
struct memman_node_list occupied_node_list;
};
#define MEMMAN_HISTOGRAM_SIZE 20
struct memman_histogram {
size_t mem_size;
int count;
};
struct memman_flexmem_info {
LIST_ENTRY(memman_flexmem_info) links;
void *addr;
size_t mem_size;
};
LIST_HEAD(memman_flexmem_info_list, memman_flexmem_info);
struct memman {
struct memman_blockman *blockman;
unsigned int max_memid;
unsigned int alloc_called;
unsigned int free_called;
unsigned int salloc_called;
unsigned int sfree_called;
size_t required_mem;
size_t allocated_mem;
size_t reclaimed_mem;
unsigned int flex_alloc_called;
unsigned int flex_free_called;
unsigned int flex_salloc_called;
unsigned int flex_sfree_called;
size_t flex_required_mem;
size_t flex_allocated_mem;
size_t flex_reclaimed_mem;
size_t flex_mem_size_min;
size_t flex_mem_size_max;
size_t flex_peak_mem_usage;
struct memman_histogram *flex_mem_histogram;
unsigned int flex_mem_histogram_ptr;
int flex_mem_histogram_initial_tolerance;
unsigned flex_mem_initialized;
struct memman_flexmem_info_list flexmem_info_list;
};
#define MEMMAN_BLOCKNODE_SIZE(entries) sizeof(struct memman_block) + \
sizeof(struct memman_node) * entries
#ifndef ROUNDUP_UNIT
#define ROUNDUP_UNIT 4
#endif
#if !defined(MEMMAN_INITIAL_SIZE) || MEMMAN_INITIAL_SIZE < 2048
#define MEMMAN_INITIAL_SIZE 2048
#endif
#if !defined(MEMMAN_INCR_SIZE) || MEMMAN_INCR_SIZE < 512
#define MEMMAN_INCR_SIZE 512
#endif
#define MEMMAN_INITIALSTORAGE_DESC(type, name) \
static struct { \
char blocknodes[MEMMAN_BLOCKNODE_SIZE(MEMMAN_INITIAL_SIZE)]; \
type realblock[MEMMAN_INITIAL_SIZE]; \
} name
#define MEMMAN_MEMBLOCK_DESC(siz, initial_storage) \
{ \
.size = siz, \
.available = MEMMAN_INITIAL_SIZE, \
.initial_block = &initial_storage, \
}
#define MEMMAN_MEMMANAGER_DESC(block_man, maxmemid, histogram, tolerance) \
{ \
.blockman = block_man, \
.max_memid = maxmemid, \
.flex_mem_histogram = histogram, \
.flex_mem_histogram_initial_tolerance = tolerance, \
}
void *memman_alloc(struct memman *, unsigned int);
void *memman_alloc_flexsize(struct memman *, size_t);
void memman_free(struct memman *, unsigned int, void *);
void memman_free_flexsize(struct memman *, void *);
void memman_freeall(struct memman *);
void memman_statistics(struct memman *);
size_t memman_memid2size(struct memman *, unsigned int);
#ifdef _KERNEL
#define MEMMAN_SYSMALLOC(size) malloc(size, M_MEMMAN, M_WAITOK)
#define MEMMAN_SYSFREE(ptr) free(ptr, M_MEMMAN)
#define MEMMAN_SYSABORT()
#else
#define MEMMAN_SYSMALLOC(size) malloc(size)
#define MEMMAN_SYSFREE(ptr) free(ptr)
#define MEMMAN_SYSABORT() abort()
#endif
#endif