- 論壇徽章:
- 0
|
本帖最后由 duanjigang 于 2010-06-01 10:45 編輯
cme_mem_20100601.tar.gz
(5.92 KB, 下載次數(shù): 473)
2010-06-01 10:39 上傳
點(diǎn)擊文件名下載附件
cme_mem_20100201.tar.gz
(2 KB, 下載次數(shù): 1337)
2010-02-01 18:11 上傳
點(diǎn)擊文件名下載附件
修改歷史:
2010-02-01:
首先是把節(jié)點(diǎn)中的list和ptr改成 head 和tail了,為了方便理解,老炮給的意見
另外是,在節(jié)點(diǎn)中添加了一個raw_data指針,跟data在初始化時(shí)同時(shí)指向數(shù)據(jù)內(nèi)存地址,這樣做的目的是防止
用戶在退出時(shí)忘記了free每一個node,如果采用以前的方式,整個內(nèi)存池也就忘記Free了,雖然能夠在退出時(shí)提示開發(fā)者,
修改后,能夠在提示開發(fā)者的基礎(chǔ)上釋放未被釋放的節(jié)點(diǎn)。
2010-06-01;
修改內(nèi)容:其一,初始化N個節(jié)點(diǎn)時(shí),為了保留棧的地址,須預(yù)留一個節(jié)點(diǎn),因此最多只能申請到N-1個,做了修改,我們在實(shí)際開辟時(shí)申請N+1個,這樣對用戶就透明了。其二:new_mem_node時(shí)。需要把當(dāng)前棧頂?shù)墓?jié)點(diǎn)的data置空,當(dāng)時(shí)寫錯了,搞成了棧底節(jié)點(diǎn)的data置空,雖然不影響功能,但邏輯錯誤,做了修改。
######################################################################
簡單技術(shù)含量不高還敢說,易用就看各位的反響了 ,期待更好的改進(jìn)建議。
自己根據(jù)實(shí)際工作需要寫的,主要是為了省事,稍微提高點(diǎn)效率,省下了N多數(shù)組的聲明和調(diào)用。
把多個類型的內(nèi)存節(jié)點(diǎn)集合到一起統(tǒng)一管理,初始化時(shí)統(tǒng)一初始化,調(diào)用如下:- init_mem_list (TYPE_S1, sizeof(s1_t), 100);
- init_mem_list (TYPE_S2, sizeof(s2_t), 200);
復(fù)制代碼 退出時(shí)統(tǒng)一釋放,調(diào)用如下:運(yùn)行過程中調(diào)用
調(diào)用封裝的new和free函數(shù)- extern u_int8_t * new_mem_node(u_int8_t type);
- extern void free_mem_node( u_int8_t * addr);
復(fù)制代碼 個人感覺還是比較方便的,效率相對還比較高,首先根據(jù)類型哈希到對應(yīng)的鏈表上,然后每個鏈表就是一個棧,彈;蛘邏簵>褪莕ew和Free操作。
一個簡單的使用例子如下:
//cme_hook.c
#include <linux/module.h>
#include <linux/kernel.h>
#include "head.h"
#include "mem_pool.c"
typedef struct
{
u_int16_t key1;
u_int32_t key2;
}s1_t;
typedef struct
{
u_int8_t key1;
u_int16_t key2;
}s2_t;
const u_int8_t TYPE_S1 = 1;
const u_int8_t TYPE_S2 = 2;
s1_t* s1_list[20];
s2_t* s2_list[50];
int init(void)
{
int i = 0;
init_mem_list (TYPE_S1, sizeof(s1_t), 100);
init_mem_list (TYPE_S2, sizeof(s2_t), 200);
for (i = 0; i < 20; i++)
{
s1_list[i] = (s1_t*)new_mem_node(TYPE_S1);
s1_list[i]->key1 = 2*i;
s1_list[i]->key2 = 2*i+1;
}
for (i = 0; i < 50; i++)
{
s2_list[i] = (s2_t*)new_mem_node(TYPE_S2);
s2_list[i]->key1 = 3*i;
s2_list[i]->key2 = 3*i+1;
}
for (i = 0; i < 20; i++)
{
printk("s1_list[%d]=<%u, %u>\n", i, s1_list[i]->key1, s1_list[i]->key2);
}
for (i = 0; i < 50; i++)
{
printk("s2_list[%d]=<%u, %u>\n", i, s2_list[i]->key1, s2_list[i]->key2);
}
printk("cme hook registering.......\n");
return 0;
}
void finish(void)
{
int i = 0;
for (i = 0; i < 20; i++) free_mem_node(((u_int8_t*)s1_list[i]));
for (i = 0; i < 50; i++) free_mem_node(((u_int8_t*)s2_list[i]));
clean_mem_list();
printk("removing cme hook.......\n");
}
module_init(init)
module_exit(finish)
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
|
附件是例子完整代碼以及這個小小內(nèi)存池的實(shí)現(xiàn)代碼,大家多多提意見改進(jìn)。
#######################################
附件看不到,貼下mem_pool.c中的實(shí)現(xiàn)代碼
//mem_pool.c
#include <linux/module.h>
#include <linux/kernel.h>
#include "head.h"
int print_msg = 0;
#define MAX_MEM_LIST 256
typedef struct _node
{
u_int8_t * data;
struct _node * next;
struct _node * pre;
}mem_node_t;
typedef struct
{
mem_node_t * list;
mem_node_t * ptr;
spinlock_t lock;
u_int8_t type;
u_int8_t valid;
}mem_list_t;
static mem_list_t mem_list[MAX_MEM_LIST];
static int init_all_mem_list(void)
{
int i = 0;
for (i = 0; i < MAX_MEM_LIST; i++)
{
mem_list[i].list = NULL;
mem_list[i].ptr = NULL;
mem_list[i].type = 0;
mem_list[i].valid = 0;
}
return 1;
}
static int mem_list_init = 0;
u_int8_t * new_mem_node(u_int8_t type)
{
u_int8_t * prt = NULL;
mem_node_t * plist = mem_list[type].list;
if(!plist) return NULL;
spin_lock(&mem_list[type].lock);
if(mem_list[type].ptr != mem_list[type].list)
{
prt = (u_int8_t*)(mem_list[type].ptr->data + 1);
if(print_msg) printk("alloc one node:%p\n", prt);
plist->data = NULL;
mem_list[type].ptr = mem_list[type].ptr->pre;
}else
{
if(print_msg) printk("no node for alloc\n");
}
spin_unlock(&mem_list[type].lock);
return prt;
}
void free_mem_node( u_int8_t * addr)
{
u_int8_t type = *(addr - 1);
mem_list_t * plist = &mem_list[type];
spin_lock(&plist->lock);
if(plist->ptr->next && addr)
{
if(print_msg) printk("free one mem node %p of type:%u\n", addr, type);
plist->ptr = plist->ptr->next;
plist->ptr->data = (u_int8_t*)(addr-1);
}else
{
if(print_msg) printk("free node error\n");
}
spin_unlock(&plist->lock);
}
int init_mem_list ( u_int8_t type, int size, int length)
{
int i = 0;
mem_list_t * plist = &mem_list[i];
if (!mem_list_init)
{
init_all_mem_list();
mem_list_init = 1;
}
if ((type == 0)||(size <= 0) || (length <= 0)) return 0;
plist = &mem_list[type];
if(plist->valid) return 1;
plist->valid = 1;
spin_lock_init(&plist->lock);
plist->type = type;
for ( i = 0; i < length; i++ )
{
u_int8_t * ptype = 0;
mem_node_t * p = (mem_node_t*)malloc(sizeof(mem_node_t));
if(!p)goto err;
p->data = malloc(size + sizeof(u_int8_t));
if(!p->data)
{
free(p);
goto err;
}
ptype = p->data;
*ptype = type;
//p->type = type;
p->next = NULL;
p->pre = NULL;
if(!plist->list)
{
plist->list = p;
plist->ptr = p;
continue;
}
p->next = plist->list->next;
plist->list->next = p;
p->pre = plist->list;
if(p->next) p->next->pre = p;
}
while(plist->ptr->next) plist->ptr = plist->ptr->next;
plist->valid = 1;
if(print_msg) printk("init %d nodes of type %u success\n", length, type);
return 1;
err:
while(plist->list)
{
mem_node_t * p = plist->list;
plist->list = plist->list->next;
if(p)
{
if(p->data) free(p->data);
free(p);
}
}
mem_list[type].valid = 0;
mem_list[type].type = 0;
mem_list[type].list = NULL;
mem_list[type].ptr = NULL;
return 0;
}
void clean_mem_list(void)
{
int num = 0;
int left = -1;
int i = 0;
u_int8_t type;
for (i = 0; i < MAX_MEM_LIST; i++)
{
mem_list_t * plist = &mem_list[i];
if ( !plist->valid ) continue;
plist->valid = 0;
type = plist->type;
num = 0;
while(plist->list)
{
mem_node_t * p = plist->list;
if(p == plist->ptr) left = 0;
plist->list = plist->list->next;
if(p)
{
num++;
if(left >= 0) left++;
if(p->data) free(p->data);
free(p);
}
}
if(print_msg)
printk("free %d mem node(s) of type %u success, %d node(s) being used now\n",
num, type, left - 1);
}
}
|
頭文件head.h
#ifndef _HEAD_H_
#define _HEAD_H_
#ifdef __KERNEL__
#define malloc(a) kmalloc(a,GFP_ATOMIC)
#define free(a) kfree(a)
#endif
extern u_int8_t * new_mem_node(u_int8_t type);
extern void free_mem_node( u_int8_t * addr);
extern int init_mem_list ( u_int8_t type, int size, int length);
extern void clean_mem_list(void);
#endif
|
目前沒有在運(yùn)行過程中做動態(tài)的reallocate,也就是說new失敗時(shí),就需要淘汰已有節(jié)點(diǎn),主動free了
整個的存儲圖示意圖如下:
[ 本帖最后由 duanjigang 于 2010-1-13 10:55 編輯 ] |
|