理解内核链表的小程序

klist.h

#ifndef _KLIST_H_
#define _KLIST_H_

struct list_head {
    struct list_head *next, *prev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

#define container_of(ptr, type, member) ({  \
    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - ((size_t) &((type *)0)->member) );})      

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

#define list_first_entry(ptr, type, member) \
    list_entry((ptr)->next, type, member)    

#define list_next_entry(pos, member) \
    list_entry((pos)->member.next, typeof(*(pos)), member)    

#define list_for_each_entry(pos, head, member)              \
    for (pos = list_first_entry(head, typeof(*pos), member);    \
         &pos->member != (head);                    \
         pos = list_next_entry(pos, member))

void list_add(struct list_head *new, struct list_head *head);

#endif
 
klist.c
 
#include <stdbool.h>
#include "klist.h"

static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

bool __list_add_valid(struct list_head *new, struct list_head *prev,
              struct list_head *next)
{
    if((next->prev != prev) || (prev->next != next) || (new == prev || new == next))
        return false;
    return true;
}

static inline void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    if (!__list_add_valid(new, prev, next))
        return;
 
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}
 
test.c
 
#include <stdio.h>
#include "klist.h"

struct  my_task_list {
    int val ;
    struct list_head mylist;
};

int main(int argc, char const *argv[])
{
    LIST_HEAD(header_task);

    struct my_task_list my_first_task = { 
        .val = 1,
        .mylist = LIST_HEAD_INIT(my_first_task.mylist)
    };

    struct my_task_list my_second_task = { 
        .val = 2,
        .mylist = LIST_HEAD_INIT(my_second_task.mylist)
    };

    list_add(&my_first_task.mylist,  &header_task);
    list_add(&my_second_task.mylist, &header_task);

    struct my_task_list *pos;
    list_for_each_entry(pos, &header_task, mylist) {   
        printf("%d\n", pos->val);                
    } 

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/vonyoven/p/12171423.html
今日推荐