数据结构(4) - 内核链表
这里的内核链表指Linux中实现的一种特殊的双向链表,区别于传统的双向链表包含数据,内核链表结构本身不包含数据,类比于卡车和货物,内核链表是卡车,数据是货物,两者之间联系通过container_of()函数进行映射,内核链表作为一个独立的成员包含在包含数据的结构体中,对数据的操作都是操作结构体中的内核链表对象,此时我们是可以知道内核链表成员对象的地址,然后通过container_of()把结构体的地址逆推出来,我们就可以拿到数据了,Linux内核链表不仅可以用在Linux平台,通过简单的修改(修改GCC编译器专有特性为通用特性即可),也可用于其它平台。
我用Linux 5.x版本的代码移植了一份内核链表的算法文件,特意改了一个在非GCC编译特性的container_of(),如下:
1 /** 2 * container_of - cast a member of a structure out to the containing structure 3 * @ptr: the pointer to the member. 4 * @type: the type of the container struct this is embedded in. 5 * @member: the name of the member within the struct. 6 * 7 */ 8 #ifdef _NOGCC 9 #define container_of(ptr, type, member) \ 10 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 11 #else 12 #define container_of(ptr, type, member) ({ \ 13 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 14 (type *)( (char *)__mptr - offsetof(type,member) );}) 15 #endif
完整的Linux 5.x版本内核链表算法文件如下:
list.h (以linux_5.x/include/linux/list.h为基础,添加其依赖制作).
1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_LIST_H 3 #define _LINUX_LIST_H 4 5 #include <stdbool.h> 6 7 /* 8 * Architectures might want to move the poison pointer offset 9 * into some well-recognized area such as 0xdead000000000000, 10 * that is also not mappable by user-space exploits: 11 */ 12 #define POISON_POINTER_DELTA 0 13 14 /* 15 * These are non-NULL pointers that will result in page faults 16 * under normal circumstances, used to verify that nobody uses 17 * non-initialized list entries. 18 */ 19 #define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA) 20 #define LIST_POISON2 ((void *) 0x122 + POISON_POINTER_DELTA) 21 22 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 23 24 /** 25 * container_of - cast a member of a structure out to the containing structure 26 * @ptr: the pointer to the member. 27 * @type: the type of the container struct this is embedded in. 28 * @member: the name of the member within the struct. 29 * 30 */ 31 #ifdef _NOGCC 32 #define container_of(ptr, type, member) \ 33 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 34 #else 35 #define container_of(ptr, type, member) ({ \ 36 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 37 (type *)( (char *)__mptr - offsetof(type,member) );}) 38 #endif 39 40 #define WRITE_ONCE(var, val) \ 41 (*((volatile typeof(val) *)(&(var))) = (val)) 42 43 #define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) 44 45 /* 46 * Simple doubly linked list implementation. 47 * 48 * Some of the internal functions ("__xxx") are useful when 49 * manipulating whole lists rather than single entries, as 50 * sometimes we already know the next/prev entries and we can 51 * generate better code by using them directly rather than 52 * using the generic single-entry routines. 53 */ 54 55 #define LIST_HEAD_INIT(name) { &(name), &(name) } 56 57 #define LIST_HEAD(name) \ 58 struct list_head name = LIST_HEAD_INIT(name) 59 60 61 struct list_head { 62 struct list_head *next, *prev; 63 }; 64 65 struct hlist_head { 66 struct hlist_node *first; 67 }; 68 69 struct hlist_node { 70 struct hlist_node *next, **pprev; 71 }; 72 73 74 /** 75 * INIT_LIST_HEAD - Initialize a list_head structure 76 * @list: list_head structure to be initialized. 77 * 78 * Initializes the list_head to point to itself. If it is a list header, 79 * the result is an empty list. 80 */ 81 static inline void INIT_LIST_HEAD(struct list_head *list) 82 { 83 WRITE_ONCE(list->next, list); 84 list->prev = list; 85 } 86 87 #ifdef CONFIG_DEBUG_LIST 88 extern bool __list_add_valid(struct list_head *new, 89 struct list_head *prev, 90 struct list_head *next); 91 extern bool __list_del_entry_valid(struct list_head *entry); 92 #else 93 static inline bool __list_add_valid(struct list_head *new, 94 struct list_head *prev, 95 struct list_head *next) 96 { 97 return true; 98 } 99 static inline bool __list_del_entry_valid(struct list_head *entry) 100 { 101 return true; 102 } 103 #endif 104 105 /* 106 * Insert a new entry between two known consecutive entries. 107 * 108 * This is only for internal list manipulation where we know 109 * the prev/next entries already! 110 */ 111 static inline void __list_add(struct list_head *new, 112 struct list_head *prev, 113 struct list_head *next) 114 { 115 if (!__list_add_valid(new, prev, next)) 116 return; 117 118 next->prev = new; 119 new->next = next; 120 new->prev = prev; 121 WRITE_ONCE(prev->next, new); 122 } 123 124 /** 125 * list_add - add a new entry 126 * @new: new entry to be added 127 * @head: list head to add it after 128 * 129 * Insert a new entry after the specified head. 130 * This is good for implementing stacks. 131 */ 132 static inline void list_add(struct list_head *new, struct list_head *head) 133 { 134 __list_add(new, head, head->next); 135 } 136 137 138 /** 139 * list_add_tail - add a new entry 140 * @new: new entry to be added 141 * @head: list head to add it before 142 * 143 * Insert a new entry before the specified head. 144 * This is useful for implementing queues. 145 */ 146 static inline void list_add_tail(struct list_head *new, struct list_head *head) 147 { 148 __list_add(new, head->prev, head); 149 } 150 151 /* 152 * Delete a list entry by making the prev/next entries 153 * point to each other. 154 * 155 * This is only for internal list manipulation where we know 156 * the prev/next entries already! 157 */ 158 static inline void __list_del(struct list_head * prev, struct list_head * next) 159 { 160 next->prev = prev; 161 WRITE_ONCE(prev->next, next); 162 } 163 164 /* 165 * Delete a list entry and clear the 'prev' pointer. 166 * 167 * This is a special-purpose list clearing method used in the networking code 168 * for lists allocated as per-cpu, where we don't want to incur the extra 169 * WRITE_ONCE() overhead of a regular list_del_init(). The code that uses this 170 * needs to check the node 'prev' pointer instead of calling list_empty(). 171 */ 172 static inline void __list_del_clearprev(struct list_head *entry) 173 { 174 __list_del(entry->prev, entry->next); 175 entry->prev = NULL; 176 } 177 178 static inline void __list_del_entry(struct list_head *entry) 179 { 180 if (!__list_del_entry_valid(entry)) 181 return; 182 183 __list_del(entry->prev, entry->next); 184 } 185 186 /** 187 * list_del - deletes entry from list. 188 * @entry: the element to delete from the list. 189 * Note: list_empty() on entry does not return true after this, the entry is 190 * in an undefined state. 191 */ 192 static inline void list_del(struct list_head *entry) 193 { 194 __list_del_entry(entry); 195 entry->next = LIST_POISON1; 196 entry->prev = LIST_POISON2; 197 } 198 199 /** 200 * list_replace - replace old entry by new one 201 * @old : the element to be replaced 202 * @new : the new element to insert 203 * 204 * If @old was empty, it will be overwritten. 205 */ 206 static inline void list_replace(struct list_head *old, 207 struct list_head *new) 208 { 209 new->next = old->next; 210 new->next->prev = new; 211 new->prev = old->prev; 212 new->prev->next = new; 213 } 214 215 /** 216 * list_replace_init - replace old entry by new one and initialize the old one 217 * @old : the element to be replaced 218 * @new : the new element to insert 219 * 220 * If @old was empty, it will be overwritten. 221 */ 222 static inline void list_replace_init(struct list_head *old, 223 struct list_head *new) 224 { 225 list_replace(old, new); 226 INIT_LIST_HEAD(old); 227 } 228 229 /** 230 * list_swap - replace entry1 with entry2 and re-add entry1 at entry2's position 231 * @entry1: the location to place entry2 232 * @entry2: the location to place entry1 233 */ 234 static inline void list_swap(struct list_head *entry1, 235 struct list_head *entry2) 236 { 237 struct list_head *pos = entry2->prev; 238 239 list_del(entry2); 240 list_replace(entry1, entry2); 241 if (pos == entry1) 242 pos = entry2; 243 list_add(entry1, pos); 244 } 245 246 /** 247 * list_del_init - deletes entry from list and reinitialize it. 248 * @entry: the element to delete from the list. 249 */ 250 static inline void list_del_init(struct list_head *entry) 251 { 252 __list_del_entry(entry); 253 INIT_LIST_HEAD(entry); 254 } 255 256 /** 257 * list_move - delete from one list and add as another's head 258 * @list: the entry to move 259 * @head: the head that will precede our entry 260 */ 261 static inline void list_move(struct list_head *list, struct list_head *head) 262 { 263 __list_del_entry(list); 264 list_add(list, head); 265 } 266 267 /** 268 * list_move_tail - delete from one list and add as another's tail 269 * @list: the entry to move 270 * @head: the head that will follow our entry 271 */ 272 static inline void list_move_tail(struct list_head *list, 273 struct list_head *head) 274 { 275 __list_del_entry(list); 276 list_add_tail(list, head); 277 } 278 279 /** 280 * list_bulk_move_tail - move a subsection of a list to its tail 281 * @head: the head that will follow our entry 282 * @first: first entry to move 283 * @last: last entry to move, can be the same as first 284 * 285 * Move all entries between @first and including @last before @head. 286 * All three entries must belong to the same linked list. 287 */ 288 static inline void list_bulk_move_tail(struct list_head *head, 289 struct list_head *first, 290 struct list_head *last) 291 { 292 first->prev->next = last->next; 293 last->next->prev = first->prev; 294 295 head->prev->next = first; 296 first->prev = head->prev; 297 298 last->next = head; 299 head->prev = last; 300 } 301 302 /** 303 * list_is_first -- tests whether @list is the first entry in list @head 304 * @list: the entry to test 305 * @head: the head of the list 306 */ 307 static inline int list_is_first(const struct list_head *list, 308 const struct list_head *head) 309 { 310 return list->prev == head; 311 } 312 313 /** 314 * list_is_last - tests whether @list is the last entry in list @head 315 * @list: the entry to test 316 * @head: the head of the list 317 */ 318 static inline int list_is_last(const struct list_head *list, 319 const struct list_head *head) 320 { 321 return list->next == head; 322 } 323 324 /** 325 * list_empty - tests whether a list is empty 326 * @head: the list to test. 327 */ 328 static inline int list_empty(const struct list_head *head) 329 { 330 return READ_ONCE(head->next) == head; 331 } 332 333 /** 334 * list_rotate_left - rotate the list to the left 335 * @head: the head of the list 336 */ 337 static inline void list_rotate_left(struct list_head *head) 338 { 339 struct list_head *first; 340 341 if (!list_empty(head)) { 342 first = head->next; 343 list_move_tail(first, head); 344 } 345 } 346 347 /** 348 * list_rotate_to_front() - Rotate list to specific item. 349 * @list: The desired new front of the list. 350 * @head: The head of the list. 351 * 352 * Rotates list so that @list becomes the new front of the list. 353 */ 354 static inline void list_rotate_to_front(struct list_head *list, 355 struct list_head *head) 356 { 357 /** 358 * Deletes the list head from the list denoted by @head and 359 * places it as the tail of @list, this effectively rotates the 360 * list so that @list is at the front. 361 */ 362 list_move_tail(head, list); 363 } 364 365 /** 366 * list_is_singular - tests whether a list has just one entry. 367 * @head: the list to test. 368 */ 369 static inline int list_is_singular(const struct list_head *head) 370 { 371 return !list_empty(head) && (head->next == head->prev); 372 } 373 374 static inline void __list_cut_position(struct list_head *list, 375 struct list_head *head, struct list_head *entry) 376 { 377 struct list_head *new_first = entry->next; 378 list->next = head->next; 379 list->next->prev = list; 380 list->prev = entry; 381 entry->next = list; 382 head->next = new_first; 383 new_first->prev = head; 384 } 385 386 /** 387 * list_cut_position - cut a list into two 388 * @list: a new list to add all removed entries 389 * @head: a list with entries 390 * @entry: an entry within head, could be the head itself 391 * and if so we won't cut the list 392 * 393 * This helper moves the initial part of @head, up to and 394 * including @entry, from @head to @list. You should 395 * pass on @entry an element you know is on @head. @list 396 * should be an empty list or a list you do not care about 397 * losing its data. 398 * 399 */ 400 static inline void list_cut_position(struct list_head *list, 401 struct list_head *head, struct list_head *entry) 402 { 403 if (list_empty(head)) 404 return; 405 if (list_is_singular(head) && 406 (head->next != entry && head != entry)) 407 return; 408 if (entry == head) 409 INIT_LIST_HEAD(list); 410 else 411 __list_cut_position(list, head, entry); 412 } 413 414 /** 415 * list_cut_before - cut a list into two, before given entry 416 * @list: a new list to add all removed entries 417 * @head: a list with entries 418 * @entry: an entry within head, could be the head itself 419 * 420 * This helper moves the initial part of @head, up to but 421 * excluding @entry, from @head to @list. You should pass 422 * in @entry an element you know is on @head. @list should 423 * be an empty list or a list you do not care about losing 424 * its data. 425 * If @entry == @head, all entries on @head are moved to 426 * @list. 427 */ 428 static inline void list_cut_before(struct list_head *list, 429 struct list_head *head, 430 struct list_head *entry) 431 { 432 if (head->next == entry) { 433 INIT_LIST_HEAD(list); 434 return; 435 } 436 list->next = head->next; 437 list->next->prev = list; 438 list->prev = entry->prev; 439 list->prev->next = list; 440 head->next = entry; 441 entry->prev = head; 442 } 443 444 static inline void __list_splice(const struct list_head *list, 445 struct list_head *prev, 446 struct list_head *next) 447 { 448 struct list_head *first = list->next; 449 struct list_head *last = list->prev; 450 451 first->prev = prev; 452 prev->next = first; 453 454 last->next = next; 455 next->prev = last; 456 } 457 458 /** 459 * list_splice - join two lists, this is designed for stacks 460 * @list: the new list to add. 461 * @head: the place to add it in the first list. 462 */ 463 static inline void list_splice(const struct list_head *list, 464 struct list_head *head) 465 { 466 if (!list_empty(list)) 467 __list_splice(list, head, head->next); 468 } 469 470 /** 471 * list_splice_tail - join two lists, each list being a queue 472 * @list: the new list to add. 473 * @head: the place to add it in the first list. 474 */ 475 static inline void list_splice_tail(struct list_head *list, 476 struct list_head *head) 477 { 478 if (!list_empty(list)) 479 __list_splice(list, head->prev, head); 480 } 481 482 /** 483 * list_splice_init - join two lists and reinitialise the emptied list. 484 * @list: the new list to add. 485 * @head: the place to add it in the first list. 486 * 487 * The list at @list is reinitialised 488 */ 489 static inline void list_splice_init(struct list_head *list, 490 struct list_head *head) 491 { 492 if (!list_empty(list)) { 493 __list_splice(list, head, head->next); 494 INIT_LIST_HEAD(list); 495 } 496 } 497 498 /** 499 * list_splice_tail_init - join two lists and reinitialise the emptied list 500 * @list: the new list to add. 501 * @head: the place to add it in the first list. 502 * 503 * Each of the lists is a queue. 504 * The list at @list is reinitialised 505 */ 506 static inline void list_splice_tail_init(struct list_head *list, 507 struct list_head *head) 508 { 509 if (!list_empty(list)) { 510 __list_splice(list, head->prev, head); 511 INIT_LIST_HEAD(list); 512 } 513 } 514 515 /** 516 * list_entry - get the struct for this entry 517 * @ptr: the &struct list_head pointer. 518 * @type: the type of the struct this is embedded in. 519 * @member: the name of the list_head within the struct. 520 */ 521 #define list_entry(ptr, type, member) \ 522 container_of(ptr, type, member) 523 524 /** 525 * list_first_entry - get the first element from a list 526 * @ptr: the list head to take the element from. 527 * @type: the type of the struct this is embedded in. 528 * @member: the name of the list_head within the struct. 529 * 530 * Note, that list is expected to be not empty. 531 */ 532 #define list_first_entry(ptr, type, member) \ 533 list_entry((ptr)->next, type, member) 534 535 /** 536 * list_last_entry - get the last element from a list 537 * @ptr: the list head to take the element from. 538 * @type: the type of the struct this is embedded in. 539 * @member: the name of the list_head within the struct. 540 * 541 * Note, that list is expected to be not empty. 542 */ 543 #define list_last_entry(ptr, type, member) \ 544 list_entry((ptr)->prev, type, member) 545 546 /** 547 * list_first_entry_or_null - get the first element from a list 548 * @ptr: the list head to take the element from. 549 * @type: the type of the struct this is embedded in. 550 * @member: the name of the list_head within the struct. 551 * 552 * Note that if the list is empty, it returns NULL. 553 */ 554 #define list_first_entry_or_null(ptr, type, member) ({ \ 555 struct list_head *head__ = (ptr); \ 556 struct list_head *pos__ = READ_ONCE(head__->next); \ 557 pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ 558 }) 559 560 /** 561 * list_next_entry - get the next element in list 562 * @pos: the type * to cursor 563 * @member: the name of the list_head within the struct. 564 */ 565 #define list_next_entry(pos, member) \ 566 list_entry((pos)->member.next, typeof(*(pos)), member) 567 568 /** 569 * list_prev_entry - get the prev element in list 570 * @pos: the type * to cursor 571 * @member: the name of the list_head within the struct. 572 */ 573 #define list_prev_entry(pos, member) \ 574 list_entry((pos)->member.prev, typeof(*(pos)), member) 575 576 /** 577 * list_for_each - iterate over a list 578 * @pos: the &struct list_head to use as a loop cursor. 579 * @head: the head for your list. 580 */ 581 #define list_for_each(pos, head) \ 582 for (pos = (head)->next; pos != (head); pos = pos->next) 583 584 /** 585 * list_for_each_continue - continue iteration over a list 586 * @pos: the &struct list_head to use as a loop cursor. 587 * @head: the head for your list. 588 * 589 * Continue to iterate over a list, continuing after the current position. 590 */ 591 #define list_for_each_continue(pos, head) \ 592 for (pos = pos->next; pos != (head); pos = pos->next) 593 594 /** 595 * list_for_each_prev - iterate over a list backwards 596 * @pos: the &struct list_head to use as a loop cursor. 597 * @head: the head for your list. 598 */ 599 #define list_for_each_prev(pos, head) \ 600 for (pos = (head)->prev; pos != (head); pos = pos->prev) 601 602 /** 603 * list_for_each_safe - iterate over a list safe against removal of list entry 604 * @pos: the &struct list_head to use as a loop cursor. 605 * @n: another &struct list_head to use as temporary storage 606 * @head: the head for your list. 607 */ 608 #define list_for_each_safe(pos, n, head) \ 609 for (pos = (head)->next, n = pos->next; pos != (head); \ 610 pos = n, n = pos->next) 611 612 /** 613 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry 614 * @pos: the &struct list_head to use as a loop cursor. 615 * @n: another &struct list_head to use as temporary storage 616 * @head: the head for your list. 617 */ 618 #define list_for_each_prev_safe(pos, n, head) \ 619 for (pos = (head)->prev, n = pos->prev; \ 620 pos != (head); \ 621 pos = n, n = pos->prev) 622 623 /** 624 * list_for_each_entry - iterate over list of given type 625 * @pos: the type * to use as a loop cursor. 626 * @head: the head for your list. 627 * @member: the name of the list_head within the struct. 628 */ 629 #define list_for_each_entry(pos, head, member) \ 630 for (pos = list_first_entry(head, typeof(*pos), member); \ 631 &pos->member != (head); \ 632 pos = list_next_entry(pos, member)) 633 634 /** 635 * list_for_each_entry_reverse - iterate backwards over list of given type. 636 * @pos: the type * to use as a loop cursor. 637 * @head: the head for your list. 638 * @member: the name of the list_head within the struct. 639 */ 640 #define list_for_each_entry_reverse(pos, head, member) \ 641 for (pos = list_last_entry(head, typeof(*pos), member); \ 642 &pos->member != (head); \ 643 pos = list_prev_entry(pos, member)) 644 645 /** 646 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() 647 * @pos: the type * to use as a start point 648 * @head: the head of the list 649 * @member: the name of the list_head within the struct. 650 * 651 * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). 652 */ 653 #define list_prepare_entry(pos, head, member) \ 654 ((pos) ? : list_entry(head, typeof(*pos), member)) 655 656 /** 657 * list_for_each_entry_continue - continue iteration over list of given type 658 * @pos: the type * to use as a loop cursor. 659 * @head: the head for your list. 660 * @member: the name of the list_head within the struct. 661 * 662 * Continue to iterate over list of given type, continuing after 663 * the current position. 664 */ 665 #define list_for_each_entry_continue(pos, head, member) \ 666 for (pos = list_next_entry(pos, member); \ 667 &pos->member != (head); \ 668 pos = list_next_entry(pos, member)) 669 670 /** 671 * list_for_each_entry_continue_reverse - iterate backwards from the given point 672 * @pos: the type * to use as a loop cursor. 673 * @head: the head for your list. 674 * @member: the name of the list_head within the struct. 675 * 676 * Start to iterate over list of given type backwards, continuing after 677 * the current position. 678 */ 679 #define list_for_each_entry_continue_reverse(pos, head, member) \ 680 for (pos = list_prev_entry(pos, member); \ 681 &pos->member != (head); \ 682 pos = list_prev_entry(pos, member)) 683 684 /** 685 * list_for_each_entry_from - iterate over list of given type from the current point 686 * @pos: the type * to use as a loop cursor. 687 * @head: the head for your list. 688 * @member: the name of the list_head within the struct. 689 * 690 * Iterate over list of given type, continuing from current position. 691 */ 692 #define list_for_each_entry_from(pos, head, member) \ 693 for (; &pos->member != (head); \ 694 pos = list_next_entry(pos, member)) 695 696 /** 697 * list_for_each_entry_from_reverse - iterate backwards over list of given type 698 * from the current point 699 * @pos: the type * to use as a loop cursor. 700 * @head: the head for your list. 701 * @member: the name of the list_head within the struct. 702 * 703 * Iterate backwards over list of given type, continuing from current position. 704 */ 705 #define list_for_each_entry_from_reverse(pos, head, member) \ 706 for (; &pos->member != (head); \ 707 pos = list_prev_entry(pos, member)) 708 709 /** 710 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 711 * @pos: the type * to use as a loop cursor. 712 * @n: another type * to use as temporary storage 713 * @head: the head for your list. 714 * @member: the name of the list_head within the struct. 715 */ 716 #define list_for_each_entry_safe(pos, n, head, member) \ 717 for (pos = list_first_entry(head, typeof(*pos), member), \ 718 n = list_next_entry(pos, member); \ 719 &pos->member != (head); \ 720 pos = n, n = list_next_entry(n, member)) 721 722 /** 723 * list_for_each_entry_safe_continue - continue list iteration safe against removal 724 * @pos: the type * to use as a loop cursor. 725 * @n: another type * to use as temporary storage 726 * @head: the head for your list. 727 * @member: the name of the list_head within the struct. 728 * 729 * Iterate over list of given type, continuing after current point, 730 * safe against removal of list entry. 731 */ 732 #define list_for_each_entry_safe_continue(pos, n, head, member) \ 733 for (pos = list_next_entry(pos, member), \ 734 n = list_next_entry(pos, member); \ 735 &pos->member != (head); \ 736 pos = n, n = list_next_entry(n, member)) 737 738 /** 739 * list_for_each_entry_safe_from - iterate over list from current point safe against removal 740 * @pos: the type * to use as a loop cursor. 741 * @n: another type * to use as temporary storage 742 * @head: the head for your list. 743 * @member: the name of the list_head within the struct. 744 * 745 * Iterate over list of given type from current point, safe against 746 * removal of list entry. 747 */ 748 #define list_for_each_entry_safe_from(pos, n, head, member) \ 749 for (n = list_next_entry(pos, member); \ 750 &pos->member != (head); \ 751 pos = n, n = list_next_entry(n, member)) 752 753 /** 754 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal 755 * @pos: the type * to use as a loop cursor. 756 * @n: another type * to use as temporary storage 757 * @head: the head for your list. 758 * @member: the name of the list_head within the struct. 759 * 760 * Iterate backwards over list of given type, safe against removal 761 * of list entry. 762 */ 763 #define list_for_each_entry_safe_reverse(pos, n, head, member) \ 764 for (pos = list_last_entry(head, typeof(*pos), member), \ 765 n = list_prev_entry(pos, member); \ 766 &pos->member != (head); \ 767 pos = n, n = list_prev_entry(n, member)) 768 769 /** 770 * list_safe_reset_next - reset a stale list_for_each_entry_safe loop 771 * @pos: the loop cursor used in the list_for_each_entry_safe loop 772 * @n: temporary storage used in list_for_each_entry_safe 773 * @member: the name of the list_head within the struct. 774 * 775 * list_safe_reset_next is not safe to use in general if the list may be 776 * modified concurrently (eg. the lock is dropped in the loop body). An 777 * exception to this is if the cursor element (pos) is pinned in the list, 778 * and list_safe_reset_next is called after re-taking the lock and before 779 * completing the current iteration of the loop body. 780 */ 781 #define list_safe_reset_next(pos, n, member) \ 782 n = list_next_entry(pos, member) 783 784 /* 785 * Double linked lists with a single pointer list head. 786 * Mostly useful for hash tables where the two pointer list head is 787 * too wasteful. 788 * You lose the ability to access the tail in O(1). 789 */ 790 791 #define HLIST_HEAD_INIT { .first = NULL } 792 #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } 793 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 794 static inline void INIT_HLIST_NODE(struct hlist_node *h) 795 { 796 h->next = NULL; 797 h->pprev = NULL; 798 } 799 800 /** 801 * hlist_unhashed - Has node been removed from list and reinitialized? 802 * @h: Node to be checked 803 * 804 * Not that not all removal functions will leave a node in unhashed 805 * state. For example, hlist_nulls_del_init_rcu() does leave the 806 * node in unhashed state, but hlist_nulls_del() does not. 807 */ 808 static inline int hlist_unhashed(const struct hlist_node *h) 809 { 810 return !h->pprev; 811 } 812 813 /** 814 * hlist_unhashed_lockless - Version of hlist_unhashed for lockless use 815 * @h: Node to be checked 816 * 817 * This variant of hlist_unhashed() must be used in lockless contexts 818 * to avoid potential load-tearing. The READ_ONCE() is paired with the 819 * various WRITE_ONCE() in hlist helpers that are defined below. 820 */ 821 static inline int hlist_unhashed_lockless(const struct hlist_node *h) 822 { 823 return !READ_ONCE(h->pprev); 824 } 825 826 /** 827 * hlist_empty - Is the specified hlist_head structure an empty hlist? 828 * @h: Structure to check. 829 */ 830 static inline int hlist_empty(const struct hlist_head *h) 831 { 832 return !READ_ONCE(h->first); 833 } 834 835 static inline void __hlist_del(struct hlist_node *n) 836 { 837 struct hlist_node *next = n->next; 838 struct hlist_node **pprev = n->pprev; 839 840 WRITE_ONCE(*pprev, next); 841 if (next) 842 WRITE_ONCE(next->pprev, pprev); 843 } 844 845 /** 846 * hlist_del - Delete the specified hlist_node from its list 847 * @n: Node to delete. 848 * 849 * Note that this function leaves the node in hashed state. Use 850 * hlist_del_init() or similar instead to unhash @n. 851 */ 852 static inline void hlist_del(struct hlist_node *n) 853 { 854 __hlist_del(n); 855 n->next = LIST_POISON1; 856 n->pprev = LIST_POISON2; 857 } 858 859 /** 860 * hlist_del_init - Delete the specified hlist_node from its list and initialize 861 * @n: Node to delete. 862 * 863 * Note that this function leaves the node in unhashed state. 864 */ 865 static inline void hlist_del_init(struct hlist_node *n) 866 { 867 if (!hlist_unhashed(n)) { 868 __hlist_del(n); 869 INIT_HLIST_NODE(n); 870 } 871 } 872 873 /** 874 * hlist_add_head - add a new entry at the beginning of the hlist 875 * @n: new entry to be added 876 * @h: hlist head to add it after 877 * 878 * Insert a new entry after the specified head. 879 * This is good for implementing stacks. 880 */ 881 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 882 { 883 struct hlist_node *first = h->first; 884 WRITE_ONCE(n->next, first); 885 if (first) 886 WRITE_ONCE(first->pprev, &n->next); 887 WRITE_ONCE(h->first, n); 888 WRITE_ONCE(n->pprev, &h->first); 889 } 890 891 /** 892 * hlist_add_before - add a new entry before the one specified 893 * @n: new entry to be added 894 * @next: hlist node to add it before, which must be non-NULL 895 */ 896 static inline void hlist_add_before(struct hlist_node *n, 897 struct hlist_node *next) 898 { 899 WRITE_ONCE(n->pprev, next->pprev); 900 WRITE_ONCE(n->next, next); 901 WRITE_ONCE(next->pprev, &n->next); 902 WRITE_ONCE(*(n->pprev), n); 903 } 904 905 /** 906 * hlist_add_behing - add a new entry after the one specified 907 * @n: new entry to be added 908 * @prev: hlist node to add it after, which must be non-NULL 909 */ 910 static inline void hlist_add_behind(struct hlist_node *n, 911 struct hlist_node *prev) 912 { 913 WRITE_ONCE(n->next, prev->next); 914 WRITE_ONCE(prev->next, n); 915 WRITE_ONCE(n->pprev, &prev->next); 916 917 if (n->next) 918 WRITE_ONCE(n->next->pprev, &n->next); 919 } 920 921 /** 922 * hlist_add_fake - create a fake hlist consisting of a single headless node 923 * @n: Node to make a fake list out of 924 * 925 * This makes @n appear to be its own predecessor on a headless hlist. 926 * The point of this is to allow things like hlist_del() to work correctly 927 * in cases where there is no list. 928 */ 929 static inline void hlist_add_fake(struct hlist_node *n) 930 { 931 n->pprev = &n->next; 932 } 933 934 /** 935 * hlist_fake: Is this node a fake hlist? 936 * @h: Node to check for being a self-referential fake hlist. 937 */ 938 static inline bool hlist_fake(struct hlist_node *h) 939 { 940 return h->pprev == &h->next; 941 } 942 943 /** 944 * hlist_is_singular_node - is node the only element of the specified hlist? 945 * @n: Node to check for singularity. 946 * @h: Header for potentially singular list. 947 * 948 * Check whether the node is the only node of the head without 949 * accessing head, thus avoiding unnecessary cache misses. 950 */ 951 static inline bool 952 hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) 953 { 954 return !n->next && n->pprev == &h->first; 955 } 956 957 /** 958 * hlist_move_list - Move an hlist 959 * @old: hlist_head for old list. 960 * @new: hlist_head for new list. 961 * 962 * Move a list from one list head to another. Fixup the pprev 963 * reference of the first entry if it exists. 964 */ 965 static inline void hlist_move_list(struct hlist_head *old, 966 struct hlist_head *new) 967 { 968 new->first = old->first; 969 if (new->first) 970 new->first->pprev = &new->first; 971 old->first = NULL; 972 } 973 974 #define hlist_entry(ptr, type, member) container_of(ptr,type,member) 975 976 #define hlist_for_each(pos, head) \ 977 for (pos = (head)->first; pos ; pos = pos->next) 978 979 #define hlist_for_each_safe(pos, n, head) \ 980 for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ 981 pos = n) 982 983 #define hlist_entry_safe(ptr, type, member) \ 984 ({ typeof(ptr) ____ptr = (ptr); \ 985 ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ 986 }) 987 988 /** 989 * hlist_for_each_entry - iterate over list of given type 990 * @pos: the type * to use as a loop cursor. 991 * @head: the head for your list. 992 * @member: the name of the hlist_node within the struct. 993 */ 994 #define hlist_for_each_entry(pos, head, member) \ 995 for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \ 996 pos; \ 997 pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 998 999 /** 1000 * hlist_for_each_entry_continue - iterate over a hlist continuing after current point 1001 * @pos: the type * to use as a loop cursor. 1002 * @member: the name of the hlist_node within the struct. 1003 */ 1004 #define hlist_for_each_entry_continue(pos, member) \ 1005 for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ 1006 pos; \ 1007 pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 1008 1009 /** 1010 * hlist_for_each_entry_from - iterate over a hlist continuing from current point 1011 * @pos: the type * to use as a loop cursor. 1012 * @member: the name of the hlist_node within the struct. 1013 */ 1014 #define hlist_for_each_entry_from(pos, member) \ 1015 for (; pos; \ 1016 pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 1017 1018 /** 1019 * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry 1020 * @pos: the type * to use as a loop cursor. 1021 * @n: a &struct hlist_node to use as temporary storage 1022 * @head: the head for your list. 1023 * @member: the name of the hlist_node within the struct. 1024 */ 1025 #define hlist_for_each_entry_safe(pos, n, head, member) \ 1026 for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \ 1027 pos && ({ n = pos->member.next; 1; }); \ 1028 pos = hlist_entry_safe(n, typeof(*pos), member)) 1029 1030 #endif
main.c
1 /** 2 * C data structure kernel linked list example. 3 * 4 * License - MIT. 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 #include "list.h" 11 12 13 #define MAX_TEST_NUM 10 14 15 16 typedef struct _TESTDATA { 17 int data; 18 struct list_head list; 19 } TESTDATA, *LPTESTDATA; 20 21 22 /** 23 * test_show - Display data. 24 */ 25 int test_show(LPTESTDATA lphead) 26 { 27 LPTESTDATA tmp = NULL; 28 29 list_for_each_entry(tmp, &lphead->list, list) 30 printf("%d ", tmp->data); 31 32 printf("\n"); 33 34 return 0; 35 } 36 37 38 /** 39 * test_create - Create kernel linked list. 40 */ 41 int test_create(LPTESTDATA lphead) 42 { 43 LPTESTDATA node; 44 int buf[MAX_TEST_NUM] = {92, 26, 35, 82, 57, 46, 50, 3, 22, 81}; 45 46 for (int i = 0; i < MAX_TEST_NUM; i++) { 47 node = (LPTESTDATA) malloc(sizeof(TESTDATA)); 48 49 if (NULL == node) { 50 printf("Error in create.\n"); 51 return -1; 52 } 53 54 node->data = buf[i]; 55 56 list_add_tail(&node->list, &lphead->list); 57 } 58 59 return 0; 60 } 61 62 63 /** 64 * test_init - Initialize kernel linked list. 65 */ 66 int test_init(LPTESTDATA *lphead) 67 { 68 *lphead = (LPTESTDATA) malloc(sizeof(TESTDATA)); 69 70 if (NULL == *lphead) { 71 printf("Error in init.\n"); 72 return -1; 73 } 74 75 INIT_LIST_HEAD(&(*lphead)->list); 76 77 return 0; 78 } 79 80 81 /** 82 * test_clear - Clear kernel linked list data. 83 */ 84 int test_clear(LPTESTDATA lphead) 85 { 86 LPTESTDATA pos = NULL, n = NULL; 87 88 list_for_each_entry_safe(pos, n, &lphead->list, list) { 89 list_del(&pos->list); 90 91 free(pos); 92 } 93 94 free(lphead); 95 96 pos = NULL; 97 n = NULL; 98 lphead = NULL; 99 100 return 0; 101 } 102 103 104 /** 105 * Main function. 106 */ 107 int main(void) 108 { 109 LPTESTDATA lphead; 110 111 test_init(&lphead); 112 113 test_create(lphead); 114 115 test_show(lphead); 116 117 test_clear(lphead); 118 119 return 0; 120 }
Makefile
1 # Makefile 2 CC = gcc 3 CFLAGS = -Wall -g -O0 4 5 SRC = main.c 6 7 OBJ = kerlist-test 8 9 $(OBJ) : $(SRC) 10 $(CC) $(CFLAGS) -o $@ $^ 11 12 clean: 13 $(RM) $(OBJ) *.o *.*.sw?
详细请参考Github: [Link] [https://github.com/Phoebus-Ma/C-Helper/tree/main/Class-1/List.C].