亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12345下一頁
最近訪問板塊 發(fā)新帖
查看: 46800 | 回復: 44
打印 上一主題 下一主題

發(fā)個簡單(易用)的內存池 [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2010-01-11 22:30 |只看該作者 |倒序瀏覽
本帖最后由 duanjigang 于 2010-06-01 10:45 編輯

cme_mem_20100601.tar.gz (5.92 KB, 下載次數: 473) cme_mem_20100201.tar.gz (2 KB, 下載次數: 1337)
修改歷史:
2010-02-01:
首先是把節(jié)點中的list和ptr改成 head 和tail了,為了方便理解,老炮給的意見
另外是,在節(jié)點中添加了一個raw_data指針,跟data在初始化時同時指向數據內存地址,這樣做的目的是防止
用戶在退出時忘記了free每一個node,如果采用以前的方式,整個內存池也就忘記Free了,雖然能夠在退出時提示開發(fā)者,
修改后,能夠在提示開發(fā)者的基礎上釋放未被釋放的節(jié)點。
2010-06-01;
修改內容:其一,初始化N個節(jié)點時,為了保留棧的地址,須預留一個節(jié)點,因此最多只能申請到N-1個,做了修改,我們在實際開辟時申請N+1個,這樣對用戶就透明了。其二:new_mem_node時。需要把當前棧頂的節(jié)點的data置空,當時寫錯了,搞成了棧底節(jié)點的data置空,雖然不影響功能,但邏輯錯誤,做了修改。



######################################################################
簡單技術含量不高還敢說,易用就看各位的反響了 ,期待更好的改進建議。
自己根據實際工作需要寫的,主要是為了省事,稍微提高點效率,省下了N多數組的聲明和調用。
把多個類型的內存節(jié)點集合到一起統(tǒng)一管理,初始化時統(tǒng)一初始化,調用如下:
  1. init_mem_list (TYPE_S1, sizeof(s1_t), 100);
  2. init_mem_list (TYPE_S2, sizeof(s2_t), 200);
復制代碼
退出時統(tǒng)一釋放,調用如下:
  1. clean_mem_list();
復制代碼
運行過程中調用
調用封裝的new和free函數
  1. extern u_int8_t * new_mem_node(u_int8_t type);
  2. extern void free_mem_node( u_int8_t * addr);
復制代碼
個人感覺還是比較方便的,效率相對還比較高,首先根據類型哈希到對應的鏈表上,然后每個鏈表就是一個棧,彈棧或者壓棧就是new和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");



附件是例子完整代碼以及這個小小內存池的實現代碼,大家多多提意見改進。
#######################################
附件看不到,貼下mem_pool.c中的實現代碼
//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

目前沒有在運行過程中做動態(tài)的reallocate,也就是說new失敗時,就需要淘汰已有節(jié)點,主動free了

整個的存儲圖示意圖如下:
[ 本帖最后由 duanjigang 于 2010-1-13 10:55 編輯 ]

mem_list.PNG (8.85 KB, 下載次數: 282)

mem_list.PNG

論壇徽章:
0
2 [報告]
發(fā)表于 2010-01-11 22:40 |只看該作者
free做了個統(tǒng)一接口,因為類型存在了數據的前一個位置

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
3 [報告]
發(fā)表于 2010-01-11 22:42 |只看該作者
多謝段兄的好文啊。現在好像看不了附件

論壇徽章:
0
4 [報告]
發(fā)表于 2010-01-11 23:18 |只看該作者
原帖由 Godbach 于 2010-1-11 22:42 發(fā)表
多謝段兄的好文啊,F在好像看不了附件

附件正在審核,奇怪了,再來一次看看

cme_mem.tar.gz

6.5 KB, 下載次數: 404

論壇徽章:
0
5 [報告]
發(fā)表于 2010-01-11 23:23 |只看該作者
最近嚴打呢好像

論壇徽章:
0
6 [報告]
發(fā)表于 2010-01-11 23:33 |只看該作者
我看到的附件都是審核中  謝謝分享
不過我記得好像sourceforge有個不錯的內存池的^_^

論壇徽章:
0
7 [報告]
發(fā)表于 2010-01-12 00:04 |只看該作者
最近附件有點問題,好像是這周末能恢復。

論壇徽章:
0
8 [報告]
發(fā)表于 2010-01-12 09:44 |只看該作者
附件中的實現文件貼出來了

論壇徽章:
0
9 [報告]
發(fā)表于 2010-01-12 09:49 |只看該作者
借這個貼子問一下
段兄為何使用 spin_lock 而不是 spin_lock_bh,什么情況下應該加 _bh 什么時候應該不加呢?

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
10 [報告]
發(fā)表于 2010-01-12 10:07 |只看該作者
原帖由 platinum 于 2010-1-12 09:49 發(fā)表
借這個貼子問一下
段兄為何使用 spin_lock 而不是 spin_lock_bh,什么情況下應該加 _bh 什么時候應該不加呢?


呵呵,白金兄這個問題還沒有解決啊。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯網協(xié)會會員  聯系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP