linux 核心 隊列 kfifo

來源:互聯網
上載者:User

在模組裡嘗試自己實現了個隊列, 在多進程(核心裡應該叫做多線程吧)操作時會出問題。

也曾嘗試解決遇到的問題,但由於自己核心開發功夫上籤,最終還是失敗了 ....

後來還是採取了核心的實現 kfifo(include/linux/kfifo.h), kfifo在 linux 標準核心>=2.6.10 添加, 這裡標準核心是因為 RHEL4.8 的核心版本是2.6.9(小於2.6.10)但是也有此資料結構,然後標準核心(www.kernel.org) <2.6.10 就沒有此資料結構了

寫了個簡單的實現如下:

#include <linux/init.h>#include <linux/module.h>#include <linux/kfifo.h>#include <linux/err.h>#define STR_LEN 64#define KFF_LEN 512*256struct kfifo *my_kfifo = NULL;spinlock_t my_fifo_lock;static int my_put(int num){    int i;    char buff[STR_LEN];    for(i=0; i<num; i++)    {        sprintf(buff,"My data: %d ...", i);        if(kfifo_put(my_kfifo, buff, STR_LEN) <= 0)        {            printk("<2>""%s failed\n", buff);        }    }    return num;}static int my_get(void){    char buff[STR_LEN];    while(kfifo_len(my_kfifo) > 0)  // the number of bytes available in the FIFO ? 好像不對吧    {        if(kfifo_get(my_kfifo, buff, STR_LEN) <= 0)        {            printk("<2>""kfifo_get failed\n");        }        printk("<2>""%s\n", buff);    }    return 0;}static int __init my_init(void){    printk("<2>""Init kfifo\n");    spin_lock_init(&my_fifo_lock);    my_kfifo = kfifo_alloc(KFF_LEN, GFP_KERNEL, &my_fifo_lock); // 128k    if(IS_ERR(my_kfifo))    {        printk("<2>""kfifo_alloc failed\n");        return -1;    }    my_put(10);    my_get();    return 0;}static void __exit my_exit(void){    kfifo_free(my_kfifo);    printk("<2>""Exit kfifo\n");}module_init(my_init);module_exit(my_exit);MODULE_LICENSE("GPL");

Makefile:

ifneq ($(KERNELRELEASE),)    obj-m := kfifo.oelsePWD ?= $(shell pwd)KVERSION := $(shell uname -r)all:    make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean:    make -C /lib/modules/$(KVERSION)/build M=$(PWD) cleanendif

kfifo_alloc(...) 第一個參數限制了隊列最大為 512*256  (128k)

因為 kfifo_alloc 使用了 kmalloc 分配記憶體, 而 kfree 不能分配 > 128K 的記憶體空間

下文採用另一種方法分配了 > 128k 記憶體的 kfifo

static int __init my_init(void){    printk("<2>""Init kfifo\n");    spin_lock_init(&my_fifo_lock);    ptr = (char*)vmalloc(KFF_LEN*128); //分配了16M記憶體    if(IS_ERR(ptr))    {        printk("<2>""vmalloc failed\n");        return -1;    }    my_kfifo = kfifo_init(ptr, KFF_LEN*128, GFP_KERNEL, &my_fifo_lock); // 初始化16M的隊列    if(IS_ERR(my_kfifo))    {        printk("<2>""kfifo_alloc failed\n");        return -1;    }    my_put(32768);    my_get();    return 0;}static void __exit my_exit(void){    kfree(my_kfifo);    vfree(ptr);    printk("<2>""Exit kfifo\n");}

關於 kfifo_len

/** * __kfifo_len - returns the number of bytes available in the FIFO, no locking version * @fifo: the fifo to be used. */static inline unsigned int __kfifo_len(struct kfifo *fifo){    return fifo->in - fifo->out;}/** * kfifo_len - returns the number of bytes available in the FIFO * @fifo: the fifo to be used. */static inline unsigned int kfifo_len(struct kfifo *fifo){    unsigned long flags;    unsigned int ret;    spin_lock_irqsave(fifo->lock, flags);    ret = __kfifo_len(fifo);    spin_unlock_irqrestore(fifo->lock, flags);    return ret;}

源碼中kfifo_len() 的說明是:

kfifo_len - returns the number of bytes available in the FIFO

意思好像是說返回FIFO可用的位元組數, 其實呢個人覺得返回的是FIFO中的資料長度

隨著出隊操作,此值在不斷減小,直至 0

這麼說此處的 available 應該是 available data

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.