link list
struct list_element {void *data;struct list_element *next;}
double linklist
struct list_element {void *data;struct list_element *prev;struct list_element *next;}
list_header
struct list_head{struct list_head *next;struct list_head *prev;}
struct fox {unsigned long tail_length;unsigned long weight;bool is_fantastic;struct list_head list;}
container_of
use the macro container_of, we can easily find the parent struct containing any given member variable. the offset of a given variable into a structure is fixed by the ABI at compile time.
#define container_of(ptr, type, member) ({ \const typeof( ((type *)0)->member) * __mptr = (ptr); \(type *)((char *)__mptr - offsetof(type, member));})
#defnine list_entry(ptr, type, member) \container_of(ptr, type, member)
例子
struct container {int some_other_data;int this_data;}struct container *my_container;int *my_ptr = &my_container->this_data;my_container = container_of(my_ptr, struct container, this_data);my_ptr: 表示指向this_data的指针struct container: 表示包含this_data的结构体this_data: 表示my_ptr在struct container中的字段名
define a linked list
struct fox *red_fox;red_fox = kmalloc(sizeof(*red_fox), GFP_KERNEL);red_fox->tail_length = 40;red_fox->weight = 6;red_fox->is_fantastic = false;INIT_LIST_HEAD(&red_fox->list);// orstruct fox red_fox = {.tail_length = 40,.weight = 6,.list = LIST_HEAD_INIT(red_fox. list),};
iterator
struct list_head *p;struct fox *f;list_for_each(p, &fox_list) {f = list_entry(p, struct fox, list);}
list_for_each_entry(pos, head, member);
here, pos is a pointer to the object containing the list_head nodes.
struct fox *f;list_for_each_entry(f, &fox_list, list) {// for each iteration f points to the next fox structure}
in real example, from inotify, the kernel’s filesystem notification system:
static struct inotify_watch *inode_find_handle(struct inode *inode,struct inotify_handle *ih){struct inotify_watch *watch;list_for_each_entry(watch, &inode->inotify_watches, i_list) {if (watch->ih == ih) {return watch;}}return NULL;}
this function iterates over all the entries in the inode->inotify_watches list, each entry is of type struct inotify_watch and the list_head in that structure is named i_list.
list_for_each_entry_safe
list_for_each_entry_safe(pos, next, head, member)
The next pointer is used by the list_for_each_entry_safe() macro to store the next entry in the list, we can use this macro to remove the element while iterator the list
Queue
kfifo
Creating queue
int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);
This function creates and initializes a kfifo with a queue of size bytes. The kernel uses the gfp mask gfp_mask to allocate the queue. upon success, it return 0, otherwise it return negtive error code.
struct kfifo fifo;
int ret;
ret = kfifo_alloc(&fifo, PAGE_SIZE, GFP_KERNEL);
if (ret)
return ret;
enqueue
unsigned int i;
for (i = 0; i < 32; i++)
kfifo_in(fifo, &i, sizeof(i));
Map
struct idr id_huh; // define idr
idr_init(&id_huh); // initialize idr
