mblock add stat function
parent
cb81992905
commit
e2ef7c87b6
3
HISTORY
3
HISTORY
|
|
@ -1,8 +1,9 @@
|
||||||
|
|
||||||
Version 1.23 2015-10-26
|
Version 1.23 2015-10-30
|
||||||
* sched_thread.c: task can execute in a new thread
|
* sched_thread.c: task can execute in a new thread
|
||||||
* sched_thread.c: support delay tasks
|
* sched_thread.c: support delay tasks
|
||||||
* add function get_current_time_us and get_current_time_ms
|
* add function get_current_time_us and get_current_time_ms
|
||||||
|
* mblock add stat function
|
||||||
|
|
||||||
Version 1.22 2015-10-10
|
Version 1.22 2015-10-10
|
||||||
* export php function: fastcommon_get_first_local_ip
|
* export php function: fastcommon_get_first_local_ip
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,199 @@
|
||||||
#include "pthread_func.h"
|
#include "pthread_func.h"
|
||||||
#include "sched_thread.h"
|
#include "sched_thread.h"
|
||||||
|
|
||||||
int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size,
|
struct _fast_mblock_manager
|
||||||
const int alloc_elements_once, fast_mblock_alloc_init_func init_func,
|
{
|
||||||
const bool need_lock)
|
bool initialized;
|
||||||
|
struct fast_mblock_man head;
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define INIT_HEAD(head) (head)->next = (head)->prev = head
|
||||||
|
#define IS_EMPTY(head) ((head)->next == (head)->prev)
|
||||||
|
|
||||||
|
static struct _fast_mblock_manager mblock_manager = {false};
|
||||||
|
|
||||||
|
int fast_mblock_manager_init()
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
if ((result=init_pthread_lock(&(mblock_manager.lock))) != 0)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"init_pthread_lock fail, errno: %d, error info: %s", \
|
||||||
|
__LINE__, result, STRERROR(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
INIT_HEAD(&mblock_manager.head);
|
||||||
|
mblock_manager.initialized = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmp_mblock_info(struct fast_mblock_man *mb1, struct fast_mblock_man *mb2)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result = strcmp(mb1->info.name, mb2->info.name);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mb1->info.element_size - mb2->info.element_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_to_mblock_list(struct fast_mblock_man *mblock)
|
||||||
|
{
|
||||||
|
struct fast_mblock_man *current;
|
||||||
|
if (!mblock_manager.initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*mblock->info.name == '\0')
|
||||||
|
{
|
||||||
|
snprintf(mblock->info.name, sizeof(mblock->info.name),
|
||||||
|
"size-%d", mblock->info.element_size);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&(mblock_manager.lock));
|
||||||
|
current = mblock_manager.head.next;
|
||||||
|
while (current != &mblock_manager.head)
|
||||||
|
{
|
||||||
|
if (cmp_mblock_info(mblock, current) <= 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
mblock->next = current;
|
||||||
|
current->prev = mblock;
|
||||||
|
mblock->prev = current->prev;
|
||||||
|
current->prev->next = mblock;
|
||||||
|
pthread_mutex_unlock(&(mblock_manager.lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_from_mblock_list(struct fast_mblock_man *mblock)
|
||||||
|
{
|
||||||
|
if (!mblock_manager.initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(mblock_manager.lock));
|
||||||
|
mblock->prev->next = mblock->next;
|
||||||
|
mblock->next->prev = mblock->prev;
|
||||||
|
pthread_mutex_unlock(&(mblock_manager.lock));
|
||||||
|
|
||||||
|
INIT_HEAD(mblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fast_mblock_manager_stat(struct fast_mblock_info *stats,
|
||||||
|
const int size, int *count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct fast_mblock_man *current;
|
||||||
|
struct fast_mblock_info *pStat;
|
||||||
|
|
||||||
|
if (!mblock_manager.initialized)
|
||||||
|
{
|
||||||
|
*count = 0;
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size <= 0)
|
||||||
|
{
|
||||||
|
*count = 0;
|
||||||
|
return EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
pStat = stats;
|
||||||
|
memset(stats, 0, sizeof(struct fast_mblock_info) * size);
|
||||||
|
pthread_mutex_lock(&(mblock_manager.lock));
|
||||||
|
current = mblock_manager.head.next;
|
||||||
|
while (current != &mblock_manager.head)
|
||||||
|
{
|
||||||
|
strcpy(pStat->name, current->info.name);
|
||||||
|
pStat->element_size = current->info.element_size;
|
||||||
|
pStat->total_count += current->info.total_count;
|
||||||
|
pStat->used_count += current->info.used_count;
|
||||||
|
if (current->prev != &mblock_manager.head)
|
||||||
|
{
|
||||||
|
if (cmp_mblock_info(current, current->prev) != 0)
|
||||||
|
{
|
||||||
|
if (size <= (int)(pStat - stats))
|
||||||
|
{
|
||||||
|
result = EOVERFLOW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pStat++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_EMPTY(&mblock_manager.head))
|
||||||
|
{
|
||||||
|
if (size <= (int)(pStat - stats))
|
||||||
|
{
|
||||||
|
result = EOVERFLOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pStat++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&(mblock_manager.lock));
|
||||||
|
|
||||||
|
*count = (int)(pStat - stats);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fast_mblock_manager_stat_print()
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int count;
|
||||||
|
int alloc_size;
|
||||||
|
struct fast_mblock_info *stats;
|
||||||
|
struct fast_mblock_info *pStat;
|
||||||
|
struct fast_mblock_info *stat_end;
|
||||||
|
|
||||||
|
stats = NULL;
|
||||||
|
count = 0;
|
||||||
|
alloc_size = 128;
|
||||||
|
result = EOVERFLOW;
|
||||||
|
while (result == EOVERFLOW)
|
||||||
|
{
|
||||||
|
alloc_size *= 2;
|
||||||
|
stats = realloc(stats, sizeof(struct fast_mblock_info) * alloc_size);
|
||||||
|
if (stats == NULL)
|
||||||
|
{
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
result = fast_mblock_manager_stat(stats,
|
||||||
|
alloc_size, &count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
logInfo("mblock manager stat count: %d", count);
|
||||||
|
logInfo("name element_size alloc_count used_count used_ratio");
|
||||||
|
stat_end = stats + count;
|
||||||
|
for (pStat=stats; pStat<stat_end; pStat++)
|
||||||
|
{
|
||||||
|
logInfo("%32s %8d %8d %8d %4.2f", pStat->name, pStat->total_count,
|
||||||
|
pStat->used_count, (double)pStat->used_count /
|
||||||
|
(double)pStat->total_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats != NULL) free(stats);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
|
||||||
|
const int element_size, const int alloc_elements_once,
|
||||||
|
fast_mblock_alloc_init_func init_func, const bool need_lock)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
|
@ -24,7 +214,7 @@ int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size,
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mblock->element_size = MEM_ALIGN(element_size);
|
mblock->info.element_size = MEM_ALIGN(element_size);
|
||||||
if (alloc_elements_once > 0)
|
if (alloc_elements_once > 0)
|
||||||
{
|
{
|
||||||
mblock->alloc_elements_once = alloc_elements_once;
|
mblock->alloc_elements_once = alloc_elements_once;
|
||||||
|
|
@ -33,7 +223,7 @@ int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size,
|
||||||
{
|
{
|
||||||
int block_size;
|
int block_size;
|
||||||
block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) \
|
block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) \
|
||||||
+ mblock->element_size);
|
+ mblock->info.element_size);
|
||||||
mblock->alloc_elements_once = (1024 * 1024) / block_size;
|
mblock->alloc_elements_once = (1024 * 1024) / block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,9 +240,20 @@ int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size,
|
||||||
mblock->free_chain_head = NULL;
|
mblock->free_chain_head = NULL;
|
||||||
mblock->delay_free_chain.head = NULL;
|
mblock->delay_free_chain.head = NULL;
|
||||||
mblock->delay_free_chain.tail = NULL;
|
mblock->delay_free_chain.tail = NULL;
|
||||||
mblock->total_count = 0;
|
mblock->info.total_count = 0;
|
||||||
|
mblock->info.used_count = 0;
|
||||||
mblock->need_lock = need_lock;
|
mblock->need_lock = need_lock;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
{
|
||||||
|
snprintf(mblock->info.name, sizeof(mblock->info.name), "%s", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*mblock->info.name = '\0';
|
||||||
|
}
|
||||||
|
add_to_mblock_list(mblock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +270,7 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
|
||||||
int alloc_size;
|
int alloc_size;
|
||||||
|
|
||||||
block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) + \
|
block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) + \
|
||||||
mblock->element_size);
|
mblock->info.element_size);
|
||||||
alloc_size = sizeof(struct fast_mblock_malloc) + block_size * \
|
alloc_size = sizeof(struct fast_mblock_malloc) + block_size * \
|
||||||
mblock->alloc_elements_once;
|
mblock->alloc_elements_once;
|
||||||
|
|
||||||
|
|
@ -117,7 +318,7 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
|
||||||
|
|
||||||
pMallocNode->next = mblock->malloc_chain_head;
|
pMallocNode->next = mblock->malloc_chain_head;
|
||||||
mblock->malloc_chain_head = pMallocNode;
|
mblock->malloc_chain_head = pMallocNode;
|
||||||
mblock->total_count += mblock->alloc_elements_once;
|
mblock->info.total_count += mblock->alloc_elements_once;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -142,9 +343,11 @@ void fast_mblock_destroy(struct fast_mblock_man *mblock)
|
||||||
}
|
}
|
||||||
mblock->malloc_chain_head = NULL;
|
mblock->malloc_chain_head = NULL;
|
||||||
mblock->free_chain_head = NULL;
|
mblock->free_chain_head = NULL;
|
||||||
mblock->total_count = 0;
|
mblock->info.used_count = 0;
|
||||||
|
mblock->info.total_count = 0;
|
||||||
|
|
||||||
if (mblock->need_lock) pthread_mutex_destroy(&(mblock->lock));
|
if (mblock->need_lock) pthread_mutex_destroy(&(mblock->lock));
|
||||||
|
delete_from_mblock_list(mblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
||||||
|
|
@ -165,6 +368,7 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
||||||
{
|
{
|
||||||
pNode = mblock->free_chain_head;
|
pNode = mblock->free_chain_head;
|
||||||
mblock->free_chain_head = pNode->next;
|
mblock->free_chain_head = pNode->next;
|
||||||
|
mblock->info.used_count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -182,6 +386,7 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
||||||
{
|
{
|
||||||
pNode = mblock->free_chain_head;
|
pNode = mblock->free_chain_head;
|
||||||
mblock->free_chain_head = pNode->next;
|
mblock->free_chain_head = pNode->next;
|
||||||
|
mblock->info.used_count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -216,6 +421,7 @@ int fast_mblock_free(struct fast_mblock_man *mblock, \
|
||||||
|
|
||||||
pNode->next = mblock->free_chain_head;
|
pNode->next = mblock->free_chain_head;
|
||||||
mblock->free_chain_head = pNode;
|
mblock->free_chain_head = pNode;
|
||||||
|
mblock->info.used_count--;
|
||||||
|
|
||||||
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
|
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
#include "common_define.h"
|
#include "common_define.h"
|
||||||
#include "chain.h"
|
#include "chain.h"
|
||||||
|
|
||||||
|
#define FAST_MBLOCK_NAME_SIZE 64
|
||||||
|
|
||||||
/* free node chain */
|
/* free node chain */
|
||||||
struct fast_mblock_node
|
struct fast_mblock_node
|
||||||
{
|
{
|
||||||
|
|
@ -39,17 +41,26 @@ struct fast_mblock_chain {
|
||||||
|
|
||||||
typedef int (*fast_mblock_alloc_init_func)(void *element);
|
typedef int (*fast_mblock_alloc_init_func)(void *element);
|
||||||
|
|
||||||
|
struct fast_mblock_info
|
||||||
|
{
|
||||||
|
char name[FAST_MBLOCK_NAME_SIZE];
|
||||||
|
int element_size; //element size
|
||||||
|
int total_count; //total element count
|
||||||
|
int used_count; //used element count
|
||||||
|
};
|
||||||
|
|
||||||
struct fast_mblock_man
|
struct fast_mblock_man
|
||||||
{
|
{
|
||||||
|
struct fast_mblock_info info;
|
||||||
|
int alloc_elements_once; //alloc elements once
|
||||||
struct fast_mblock_node *free_chain_head; //free node chain
|
struct fast_mblock_node *free_chain_head; //free node chain
|
||||||
struct fast_mblock_chain delay_free_chain; //delay free node chain
|
struct fast_mblock_chain delay_free_chain; //delay free node chain
|
||||||
struct fast_mblock_malloc *malloc_chain_head; //malloc chain to be freed
|
struct fast_mblock_malloc *malloc_chain_head; //malloc chain to be freed
|
||||||
fast_mblock_alloc_init_func alloc_init_func;
|
fast_mblock_alloc_init_func alloc_init_func;
|
||||||
int element_size; //element size
|
bool need_lock; //if need mutex lock
|
||||||
int alloc_elements_once; //alloc elements once
|
|
||||||
int total_count; //total element count
|
|
||||||
bool need_lock;
|
|
||||||
pthread_mutex_t lock; //the lock for read / write free node chain
|
pthread_mutex_t lock; //the lock for read / write free node chain
|
||||||
|
struct fast_mblock_man *prev; //for manager
|
||||||
|
struct fast_mblock_man *next; //for manager
|
||||||
};
|
};
|
||||||
|
|
||||||
#define fast_mblock_to_node_ptr(data_ptr) \
|
#define fast_mblock_to_node_ptr(data_ptr) \
|
||||||
|
|
@ -61,19 +72,25 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define fast_mblock_init(mblock, element_size, alloc_elements_once) \
|
#define fast_mblock_init(mblock, element_size, alloc_elements_once) \
|
||||||
fast_mblock_init_ex(mblock, element_size, alloc_elements_once, NULL, true)
|
fast_mblock_init_ex2(mblock, NULL, element_size, alloc_elements_once, NULL, true)
|
||||||
|
|
||||||
|
#define fast_mblock_init_ex(mblock, element_size, alloc_elements_once, init_func, need_lock) \
|
||||||
|
fast_mblock_init_ex2(mblock, NULL, element_size, alloc_elements_once, init_func, need_lock)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
mblock init
|
mblock init
|
||||||
parameters:
|
parameters:
|
||||||
|
name: the mblock name
|
||||||
mblock: the mblock pointer
|
mblock: the mblock pointer
|
||||||
element_size: element size, such as sizeof(struct xxx)
|
element_size: element size, such as sizeof(struct xxx)
|
||||||
alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
|
alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
|
||||||
|
init_func: the init function
|
||||||
|
need_lock: if need lock
|
||||||
return error no, 0 for success, != 0 fail
|
return error no, 0 for success, != 0 fail
|
||||||
*/
|
*/
|
||||||
int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size,
|
int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
|
||||||
const int alloc_elements_once, fast_mblock_alloc_init_func init_func,
|
const int element_size, const int alloc_elements_once,
|
||||||
const bool need_lock);
|
fast_mblock_alloc_init_func init_func, const bool need_lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
mblock destroy
|
mblock destroy
|
||||||
|
|
@ -173,6 +190,32 @@ int fast_mblock_delay_free_count(struct fast_mblock_man *mblock);
|
||||||
|
|
||||||
#define fast_mblock_total_count(mblock) (mblock)->total_count
|
#define fast_mblock_total_count(mblock) (mblock)->total_count
|
||||||
|
|
||||||
|
/**
|
||||||
|
init mblock manager
|
||||||
|
parameters:
|
||||||
|
return error no, 0 for success, != 0 fail
|
||||||
|
*/
|
||||||
|
int fast_mblock_manager_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
get mblock stat
|
||||||
|
parameters:
|
||||||
|
stats: return mblock stats
|
||||||
|
size: max size of stats
|
||||||
|
count: return mblock stat count
|
||||||
|
return error no, 0 for success, != 0 fail
|
||||||
|
*/
|
||||||
|
int fast_mblock_manager_stat(struct fast_mblock_info *stats,
|
||||||
|
const int size, int *count);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
print mblock manager stat
|
||||||
|
parameters:
|
||||||
|
return error no, 0 for success, != 0 fail
|
||||||
|
*/
|
||||||
|
int fast_mblock_manager_stat_print();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue