/* ------------------------------------------------------- * Definition of Memory Pool for DDT server;
* include sys/types.h before include this file;
------------------------------------------------------- */
#ifndef __POOL_H__
#define __POOL_H__
#include
typedef struct __memory_block
void *start; /* Start address of this block; */
unsigned long long size; /* Size of each node; */
unsigned long max; /* Number of max nodes; */
unsigned char *use_map; /* 1 if used; */
unsigned long used; /* Number of used nodes; */
void *next_free; /* Address of next free node; */
MEMORY_BLOCK;
typedef struct __memory_pool
pthread_mutex_t mutex;
struct __memory_pool *prev;
struct __memory_pool *next;
struct __memory_block *block;
MEMORY_POOL;
struct __memory_block* new_memory_block(unsigned long size, unsigned long max);
void free_memory_block(struct __memory_block* block);
void* get_memory(struct __memory_block* block);
void free_memory(struct __memory_block* block, void *ret);
struct __memory_pool* new_memory_pool(unsigned long size, unsigned long max);
void* get_memory_from_pool(struct __memory_pool* pool, unsigned long size);
void free_memory_from_pool(struct __memory_pool* pool, void *ret);
void free_memory_pool(struct __memory_pool* pool);
void garbage_collect(struct __memory_pool* pool);
/* Get used memory bytes of a memory pool (includes all the linked list); */
unsigned long get_used_bytes(struct __memory_pool* pool);
#endif
/* ----------------------------------------------------
* Implemention of memory pool for DDT server;
---------------------------------------------------- */
#include
#include
#include
#include "include/pool.h"
struct __memory_block* new_memory_block(unsigned long size, unsigned long max)
void free_memory_block(struct __memory_block* block)
free(block->start);
free(block->use_map);
free(block);
void* get_memory(struct __memory_block* block)
if (!block)
return 0;
if (block->used == block->max)
return 0;
void *get = block->next_free;
block->used++;
block->use_map[(block->next_free - block->start) / block->size] = 1;
if (block->used == block->max)
return get;
/* Calculate next free; */
unsigned long i = 0;
for (i = 0; i < block->max; i++)
if (!block->use_map[i])
block->next_free = block->start + block->size * i;
break;
return get;
void free_memory(struct __memory_block* block, void *ret)
if (!block
struct __memory_pool* new_memory_pool(unsigned long size, unsigned long max)
struct __memory_pool *pool = (struct __memory_pool*) malloc(
sizeof(struct __memory_pool));
if (!pool)
return 0;
pthread_mutex_init(&pool->mutex, NULL);
pool->prev = 0;
pool->next = 0;
pool->block = new_memory_block(size, max);
if (!pool->block)
free(pool);
return 0;
return pool;
void* get_memory_from_pool(struct __memory_pool* pool, unsigned long size) !size)
return 0;
pthread_mutex_lock(&pool->mutex);
struct __memory_block *block = pool->block;
if (size <= block->size && size >= block->size * 0.6)
void *get = get_memory(block);
if (!get)
if (!pool->next)
pool->next = new_memory_pool(block->size, block->max);
pool->next->prev = pool;
pthread_mutex_unlock(&pool->mutex);
return get_memory_from_pool(pool->next, size);
else
pthread_mutex_unlock(&pool->mutex);
return get;
else
if (!pool->next)
pool->next = new_memory_pool(size, block->max);
pool->next->prev = pool;
pthread_mutex_unlock(&pool->mutex);
return get_memory_from_pool(pool->next, size);
void free_memory_from_pool(struct __memory_pool* pool, void *ret) !ret)
return;
pthread_mutex_lock(&pool->mutex);
struct __memory_block *block = pool->block;
if (block->start >= ret && block->start + block->max < ret)
free_memory(block, ret);
pthread_mutex_unlock(&pool->mutex);
else
if (pool->next)
pthread_mutex_unlock(&pool->mutex);
free_memory_from_pool(pool->next, ret);
else
pthread_mutex_unlock(&pool->mutex);
void free_memory_pool(struct __memory_pool* pool)
if (pool->prev && pool->next)
pool->prev->next = pool->next;
pool->next->prev = pool->prev;
if (pool->prev && !pool->next)
pool->prev->next = 0;
if (!pool->prev && pool->next)
pool->next->prev = 0;
free_memory_block(pool->block);
pthread_mutex_destroy(&pool->mutex);
free(pool);
void garbage_collect(struct __memory_pool* pool)
if (!pool)
return;
struct __memory_pool *spool = pool;
while (spool->next)
if (!spool->next->block->used && spool->next->next)
struct __memory_pool *garbage = spool->next;
pthread_mutex_lock(&pool->mutex);
free_memory_pool(garbage);
pthread_mutex_unlock(&pool->mutex);
spool = spool->next;
unsigned long get_used_bytes(struct __memory_pool* pool)
if (!pool)
return 0;
unsigned long used = 0;
/* Rewind; */
while (pool->prev)
pool = pool->prev;
while (pool)
used += pool->block->max * pool->block->size;
pool = pool->next;
return used;
没有评论:
发表评论