// test_task_struct.c #include #include // for offsetof #define container_of(ptr, type, member) ({ \ const typeof(((type*)0)->member)* __mptr = (ptr); \ (type*)((char*)__mptr - offsetof(type, member)); }) // Minimal doubly linked list struct list_head { struct list_head *next, *prev; }; static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } static inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) // A small struct like the Linux kernel's task_struct struct task_struct { int pid; const char *comm; struct list_head tasks; // linkage for global task list } __attribute__((slr)); int main(void) { struct list_head task_list; INIT_LIST_HEAD(&task_list); struct task_struct t1 = { .pid = 1, .comm = "init" }; struct task_struct t2 = { .pid = 2, .comm = "kthreadd" }; struct task_struct t3 = { .pid = 3, .comm = "worker" }; INIT_LIST_HEAD(&t1.tasks); INIT_LIST_HEAD(&t2.tasks); INIT_LIST_HEAD(&t3.tasks); list_add_tail(&t1.tasks, &task_list); list_add_tail(&t2.tasks, &task_list); list_add_tail(&t3.tasks, &task_list); printf("Task list:\n"); struct list_head *pos; list_for_each(pos, &task_list) { struct task_struct *task = list_entry(pos, struct task_struct, tasks); printf(" pid=%d, comm=%s\n", task->pid, task->comm); } return 0; }