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;
}