####使用自己裁剪的list.h头文件实现的linux内核链表
代码:list1.h
1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_LIST_H 3 #define _LINUX_LIST_H 4 5 //#include <linux/types.h> 6 struct list_head { 7 struct list_head *next, *prev; 8 }; 9 10 struct hlist_head { 11 struct hlist_node *first; 12 }; 13 14 struct hlist_node { 15 struct hlist_node *next, **pprev; 16 }; 17 18 //#include <linux/poison.h> 19 /* 20 * Architectures might want to move the poison pointer offset 21 * into some well-recognized area such as 0xdead000000000000, 22 * that is also not mappable by user-space exploits: 23 */ 24 #ifdef CONFIG_ILLEGAL_POINTER_VALUE 25 # define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL) 26 #else 27 # define POISON_POINTER_DELTA (0) 28 #endif 29 30 /* 31 * These are non-NULL pointers that will result in page faults 32 * under normal circumstances, used to verify that nobody uses 33 * non-initialized list entries. 34 */ 35 #define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) 36 #define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) 37 38 39 //#include <linux/const.h> 40 41 //#include <linux/stddef.h> 42 //#include <linux/stddef.h> 43 #undef offsetof 44 #ifdef __compiler_offsetof 45 #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER) 46 #else 47 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 48 #endif 49 50 #define __compiletime_error(message) __attribute__((__error__(message))) 51 52 #ifdef __OPTIMIZE__ 53 # define __compiletime_assert(condition, msg, prefix, suffix) 54 do { 55 extern void prefix ## suffix(void) __compiletime_error(msg); 56 if (!(condition)) 57 prefix ## suffix(); 58 } while (0) 59 #else 60 # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) 61 #endif 62 63 #define _compiletime_assert(condition, msg, prefix, suffix) 64 __compiletime_assert(condition, msg, prefix, suffix) 65 66 /*#ifndef smp_store_release 67 #define smp_store_release(p, v) __smp_store_release(p, v) 68 #endif 69 70 #ifndef smp_load_acquire 71 #define smp_load_acquire(p) __smp_load_acquire(p) 72 #endif*/ 73 74 static inline void barrier(void) 75 { 76 asm volatile("" : : : "memory"); 77 } 78 79 #define compiletime_assert_atomic_type(t) 80 compiletime_assert(__native_word(t), 81 "Need native word sized stores/loads for atomicity.") 82 83 84 #ifndef smp_store_release 85 #define smp_store_release(p, v) 86 do { 87 compiletime_assert_atomic_type(*p); 88 barrier(); 89 WRITE_ONCE(*p, v); 90 } while (0) 91 #endif 92 93 #ifndef smp_load_acquire 94 #define smp_load_acquire(p) 95 ({ 96 __unqual_scalar_typeof(*p) ___p1 = READ_ONCE(*p); 97 compiletime_assert_atomic_type(*p); 98 barrier(); 99 (typeof(*p))___p1; 100 }) 101 #endif 102 103 /** 104 * compiletime_assert - break build and emit msg if condition is false 105 * @condition: a compile-time constant condition to check 106 * @msg: a message to emit if condition is false 107 * 108 * In tradition of POSIX assert, this macro will break the build if the 109 * supplied condition is *false*, emitting the supplied error message if the 110 * compiler has support to do so. 111 */ 112 #define compiletime_assert(condition, msg) 113 _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) 114 115 116 /* 117 * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving 118 * non-scalar types unchanged. 119 */ 120 /* 121 * Prefer C11 _Generic for better compile-times and simpler code. Note: ‘char‘ 122 * is not type-compatible with ‘signed char‘, and we define a separate case. 123 */ 124 #define __scalar_type_to_expr_cases(type) 125 unsigned type: (unsigned type)0, 126 signed type: (signed type)0 127 128 #define __unqual_scalar_typeof(x) typeof( 129 _Generic((x), 130 char: (char)0, 131 __scalar_type_to_expr_cases(char), 132 __scalar_type_to_expr_cases(short), 133 __scalar_type_to_expr_cases(int), 134 __scalar_type_to_expr_cases(long), 135 __scalar_type_to_expr_cases(long long), 136 default: (x))) 137 138 /* Is this type a native word size -- useful for atomic operations */ 139 #define __native_word(t) 140 (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || 141 sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) 142 143 //#include <linux/kernel.h> 144 145 #define compiletime_assert_rwonce_type(t) 146 compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), 147 "Unsupported access size for {READ,WRITE}_ONCE().") 148 149 /* 150 * Use __READ_ONCE() instead of READ_ONCE() if you do not require any 151 * atomicity. Note that this may result in tears! 152 */ 153 #ifndef __READ_ONCE 154 #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) 155 #endif 156 157 #define READ_ONCE(x) 158 ({ 159 compiletime_assert_rwonce_type(x); 160 __READ_ONCE(x); 161 }) 162 163 #define __WRITE_ONCE(x, val) 164 do { 165 *(volatile typeof(x) *)&(x) = (val); 166 } while (0) 167 168 #define WRITE_ONCE(x, val) 169 do { 170 compiletime_assert_rwonce_type(x); 171 __WRITE_ONCE(x, val); 172 } while (0) 173 174 175 176 177 /** 178 * container_of - cast a member of a structure out to the containing structure 179 * @ptr: the pointer to the member. 180 * @type: the type of the container struct this is embedded in. 181 * @member: the name of the member within the struct. 182 * 183 */ 184 #define container_of(ptr, type, member) ({ 185 const typeof( ((type *)0)->member ) *__mptr = (ptr); 186 (type *)( (char *)__mptr - offsetof(type,member) ); 187 }) 188 189 /* 190 * Simple doubly linked list implementation. 191 * 192 * Some of the internal functions ("__xxx") are useful when 193 * manipulating whole lists rather than single entries, as 194 * sometimes we already know the next/prev entries and we can 195 * generate better code by using them directly rather than 196 * using the generic single-entry routines. 197 */ 198 199 #define LIST_HEAD_INIT(name) { &(name), &(name) } 200 201 #define LIST_HEAD(name) 202 struct list_head name = LIST_HEAD_INIT(name) 203 204 /** 205 * INIT_LIST_HEAD - Initialize a list_head structure 206 * @list: list_head structure to be initialized. 207 * 208 * Initializes the list_head to point to itself. If it is a list header, 209 * the result is an empty list. 210 */ 211 static inline void INIT_LIST_HEAD(struct list_head *list) 212 { 213 WRITE_ONCE(list->next, list); 214 list->prev = list; 215 } 216 217 #ifdef CONFIG_DEBUG_LIST 218 extern bool __list_add_valid(struct list_head *new, 219 struct list_head *prev, 220 struct list_head *next); 221 extern bool __list_del_entry_valid(struct list_head *entry); 222 #else 223 static inline bool __list_add_valid(struct list_head *new, 224 struct list_head *prev, 225 struct list_head *next) 226 { 227 return true; 228 } 229 static inline bool __list_del_entry_valid(struct list_head *entry) 230 { 231 return true; 232 } 233 #endif 234 235 /* 236 * Insert a new entry between two known consecutive entries. 237 * 238 * This is only for internal list manipulation where we know 239 * the prev/next entries already! 240 */ 241 static inline void __list_add(struct list_head *new, 242 struct list_head *prev, 243 struct list_head *next) 244 { 245 if (!__list_add_valid(new, prev, next)) 246 return; 247 248 next->prev = new; 249 new->next = next; 250 new->prev = prev; 251 WRITE_ONCE(prev->next, new); 252 } 253 254 /** 255 * list_add - add a new entry 256 * @new: new entry to be added 257 * @head: list head to add it after 258 * 259 * Insert a new entry after the specified head. 260 * This is good for implementing stacks. 261 */ 262 static inline void list_add(struct list_head *new, struct list_head *head) 263 { 264 __list_add(new, head, head->next); 265 } 266 267 268 /** 269 * list_add_tail - add a new entry 270 * @new: new entry to be added 271 * @head: list head to add it before 272 * 273 * Insert a new entry before the specified head. 274 * This is useful for implementing queues. 275 */ 276 static inline void list_add_tail(struct list_head *new, struct list_head *head) 277 { 278 __list_add(new, head->prev, head); 279 } 280 281 /* 282 * Delete a list entry by making the prev/next entries 283 * point to each other. 284 * 285 * This is only for internal list manipulation where we know 286 * the prev/next entries already! 287 */ 288 static inline void __list_del(struct list_head * prev, struct list_head * next) 289 { 290 next->prev = prev; 291 WRITE_ONCE(prev->next, next); 292 } 293 294 /* 295 * Delete a list entry and clear the ‘prev‘ pointer. 296 * 297 * This is a special-purpose list clearing method used in the networking code 298 * for lists allocated as per-cpu, where we don‘t want to incur the extra 299 * WRITE_ONCE() overhead of a regular list_del_init(). The code that uses this 300 * needs to check the node ‘prev‘ pointer instead of calling list_empty(). 301 */ 302 static inline void __list_del_clearprev(struct list_head *entry) 303 { 304 __list_del(entry->prev, entry->next); 305 entry->prev = NULL; 306 } 307 308 static inline void __list_del_entry(struct list_head *entry) 309 { 310 if (!__list_del_entry_valid(entry)) 311 return; 312 313 __list_del(entry->prev, entry->next); 314 } 315 316 /** 317 * list_del - deletes entry from list. 318 * @entry: the element to delete from the list. 319 * Note: list_empty() on entry does not return true after this, the entry is 320 * in an undefined state. 321 */ 322 static inline void list_del(struct list_head *entry) 323 { 324 __list_del_entry(entry); 325 entry->next = LIST_POISON1; 326 entry->prev = LIST_POISON2; 327 } 328 329 /** 330 * list_replace - replace old entry by new one 331 * @old : the element to be replaced 332 * @new : the new element to insert 333 * 334 * If @old was empty, it will be overwritten. 335 */ 336 static inline void list_replace(struct list_head *old, 337 struct list_head *new) 338 { 339 new->next = old->next; 340 new->next->prev = new; 341 new->prev = old->prev; 342 new->prev->next = new; 343 } 344 345 /** 346 * list_replace_init - replace old entry by new one and initialize the old one 347 * @old : the element to be replaced 348 * @new : the new element to insert 349 * 350 * If @old was empty, it will be overwritten. 351 */ 352 static inline void list_replace_init(struct list_head *old, 353 struct list_head *new) 354 { 355 list_replace(old, new); 356 INIT_LIST_HEAD(old); 357 } 358 359 /** 360 * list_swap - replace entry1 with entry2 and re-add entry1 at entry2‘s position 361 * @entry1: the location to place entry2 362 * @entry2: the location to place entry1 363 */ 364 static inline void list_swap(struct list_head *entry1, 365 struct list_head *entry2) 366 { 367 struct list_head *pos = entry2->prev; 368 369 list_del(entry2); 370 list_replace(entry1, entry2); 371 if (pos == entry1) 372 pos = entry2; 373 list_add(entry1, pos); 374 } 375 376 /** 377 * list_del_init - deletes entry from list and reinitialize it. 378 * @entry: the element to delete from the list. 379 */ 380 static inline void list_del_init(struct list_head *entry) 381 { 382 __list_del_entry(entry); 383 INIT_LIST_HEAD(entry); 384 } 385 386 /** 387 * list_move - delete from one list and add as another‘s head 388 * @list: the entry to move 389 * @head: the head that will precede our entry 390 */ 391 static inline void list_move(struct list_head *list, struct list_head *head) 392 { 393 __list_del_entry(list); 394 list_add(list, head); 395 } 396 397 /** 398 * list_move_tail - delete from one list and add as another‘s tail 399 * @list: the entry to move 400 * @head: the head that will follow our entry 401 */ 402 static inline void list_move_tail(struct list_head *list, 403 struct list_head *head) 404 { 405 __list_del_entry(list); 406 list_add_tail(list, head); 407 } 408 409 /** 410 * list_bulk_move_tail - move a subsection of a list to its tail 411 * @head: the head that will follow our entry 412 * @first: first entry to move 413 * @last: last entry to move, can be the same as first 414 * 415 * Move all entries between @first and including @last before @head. 416 * All three entries must belong to the same linked list. 417 */ 418 static inline void list_bulk_move_tail(struct list_head *head, 419 struct list_head *first, 420 struct list_head *last) 421 { 422 first->prev->next = last->next; 423 last->next->prev = first->prev; 424 425 head->prev->next = first; 426 first->prev = head->prev; 427 428 last->next = head; 429 head->prev = last; 430 } 431 432 /** 433 * list_is_first -- tests whether @list is the first entry in list @head 434 * @list: the entry to test 435 * @head: the head of the list 436 */ 437 static inline int list_is_first(const struct list_head *list, 438 const struct list_head *head) 439 { 440 return list->prev == head; 441 } 442 443 /** 444 * list_is_last - tests whether @list is the last entry in list @head 445 * @list: the entry to test 446 * @head: the head of the list 447 */ 448 static inline int list_is_last(const struct list_head *list, 449 const struct list_head *head) 450 { 451 return list->next == head; 452 } 453 454 /** 455 * list_empty - tests whether a list is empty 456 * @head: the list to test. 457 */ 458 static inline int list_empty(const struct list_head *head) 459 { 460 return READ_ONCE(head->next) == head; 461 } 462 463 /** 464 * list_del_init_careful - deletes entry from list and reinitialize it. 465 * @entry: the element to delete from the list. 466 * 467 * This is the same as list_del_init(), except designed to be used 468 * together with list_empty_careful() in a way to guarantee ordering 469 * of other memory operations. 470 * 471 * Any memory operations done before a list_del_init_careful() are 472 * guaranteed to be visible after a list_empty_careful() test. 473 */ 474 static inline void list_del_init_careful(struct list_head *entry) 475 { 476 __list_del_entry(entry); 477 entry->prev = entry; 478 smp_store_release(&entry->next, entry); 479 } 480 481 /** 482 * list_empty_careful - tests whether a list is empty and not being modified 483 * @head: the list to test 484 * 485 * Description: 486 * tests whether a list is empty _and_ checks that no other CPU might be 487 * in the process of modifying either member (next or prev) 488 * 489 * NOTE: using list_empty_careful() without synchronization 490 * can only be safe if the only activity that can happen 491 * to the list entry is list_del_init(). Eg. it cannot be used 492 * if another CPU could re-list_add() it. 493 */ 494 static inline int list_empty_careful(const struct list_head *head) 495 { 496 struct list_head *next = smp_load_acquire(&head->next); 497 return (next == head) && (next == head->prev); 498 } 499 500 /** 501 * list_rotate_left - rotate the list to the left 502 * @head: the head of the list 503 */ 504 static inline void list_rotate_left(struct list_head *head) 505 { 506 struct list_head *first; 507 508 if (!list_empty(head)) { 509 first = head->next; 510 list_move_tail(first, head); 511 } 512 } 513 514 /** 515 * list_rotate_to_front() - Rotate list to specific item. 516 * @list: The desired new front of the list. 517 * @head: The head of the list. 518 * 519 * Rotates list so that @list becomes the new front of the list. 520 */ 521 static inline void list_rotate_to_front(struct list_head *list, 522 struct list_head *head) 523 { 524 /* 525 * Deletes the list head from the list denoted by @head and 526 * places it as the tail of @list, this effectively rotates the 527 * list so that @list is at the front. 528 */ 529 list_move_tail(head, list); 530 } 531 532 /** 533 * list_is_singular - tests whether a list has just one entry. 534 * @head: the list to test. 535 */ 536 static inline int list_is_singular(const struct list_head *head) 537 { 538 return !list_empty(head) && (head->next == head->prev); 539 } 540 541 static inline void __list_cut_position(struct list_head *list, 542 struct list_head *head, struct list_head *entry) 543 { 544 struct list_head *new_first = entry->next; 545 list->next = head->next; 546 list->next->prev = list; 547 list->prev = entry; 548 entry->next = list; 549 head->next = new_first; 550 new_first->prev = head; 551 } 552 553 /** 554 * list_cut_position - cut a list into two 555 * @list: a new list to add all removed entries 556 * @head: a list with entries 557 * @entry: an entry within head, could be the head itself 558 * and if so we won‘t cut the list 559 * 560 * This helper moves the initial part of @head, up to and 561 * including @entry, from @head to @list. You should 562 * pass on @entry an element you know is on @head. @list 563 * should be an empty list or a list you do not care about 564 * losing its data. 565 * 566 */ 567 static inline void list_cut_position(struct list_head *list, 568 struct list_head *head, struct list_head *entry) 569 { 570 if (list_empty(head)) 571 return; 572 if (list_is_singular(head) && 573 (head->next != entry && head != entry)) 574 return; 575 if (entry == head) 576 INIT_LIST_HEAD(list); 577 else 578 __list_cut_position(list, head, entry); 579 } 580 581 /** 582 * list_cut_before - cut a list into two, before given entry 583 * @list: a new list to add all removed entries 584 * @head: a list with entries 585 * @entry: an entry within head, could be the head itself 586 * 587 * This helper moves the initial part of @head, up to but 588 * excluding @entry, from @head to @list. You should pass 589 * in @entry an element you know is on @head. @list should 590 * be an empty list or a list you do not care about losing 591 * its data. 592 * If @entry == @head, all entries on @head are moved to 593 * @list. 594 */ 595 static inline void list_cut_before(struct list_head *list, 596 struct list_head *head, 597 struct list_head *entry) 598 { 599 if (head->next == entry) { 600 INIT_LIST_HEAD(list); 601 return; 602 } 603 list->next = head->next; 604 list->next->prev = list; 605 list->prev = entry->prev; 606 list->prev->next = list; 607 head->next = entry; 608 entry->prev = head; 609 } 610 611 static inline void __list_splice(const struct list_head *list, 612 struct list_head *prev, 613 struct list_head *next) 614 { 615 struct list_head *first = list->next; 616 struct list_head *last = list->prev; 617 618 first->prev = prev; 619 prev->next = first; 620 621 last->next = next; 622 next->prev = last; 623 } 624 625 /** 626 * list_splice - join two lists, this is designed for stacks 627 * @list: the new list to add. 628 * @head: the place to add it in the first list. 629 */ 630 static inline void list_splice(const struct list_head *list, 631 struct list_head *head) 632 { 633 if (!list_empty(list)) 634 __list_splice(list, head, head->next); 635 } 636 637 /** 638 * list_splice_tail - join two lists, each list being a queue 639 * @list: the new list to add. 640 * @head: the place to add it in the first list. 641 */ 642 static inline void list_splice_tail(struct list_head *list, 643 struct list_head *head) 644 { 645 if (!list_empty(list)) 646 __list_splice(list, head->prev, head); 647 } 648 649 /** 650 * list_splice_init - join two lists and reinitialise the emptied list. 651 * @list: the new list to add. 652 * @head: the place to add it in the first list. 653 * 654 * The list at @list is reinitialised 655 */ 656 static inline void list_splice_init(struct list_head *list, 657 struct list_head *head) 658 { 659 if (!list_empty(list)) { 660 __list_splice(list, head, head->next); 661 INIT_LIST_HEAD(list); 662 } 663 } 664 665 /** 666 * list_splice_tail_init - join two lists and reinitialise the emptied list 667 * @list: the new list to add. 668 * @head: the place to add it in the first list. 669 * 670 * Each of the lists is a queue. 671 * The list at @list is reinitialised 672 */ 673 static inline void list_splice_tail_init(struct list_head *list, 674 struct list_head *head) 675 { 676 if (!list_empty(list)) { 677 __list_splice(list, head->prev, head); 678 INIT_LIST_HEAD(list); 679 } 680 } 681 682 /** 683 * list_entry - get the struct for this entry 684 * @ptr: the &struct list_head pointer. 685 * @type: the type of the struct this is embedded in. 686 * @member: the name of the list_head within the struct. 687 */ 688 #define list_entry(ptr, type, member) 689 container_of(ptr, type, member) 690 691 /** 692 * list_first_entry - get the first element from a list 693 * @ptr: the list head to take the element from. 694 * @type: the type of the struct this is embedded in. 695 * @member: the name of the list_head within the struct. 696 * 697 * Note, that list is expected to be not empty. 698 */ 699 #define list_first_entry(ptr, type, member) 700 list_entry((ptr)->next, type, member) 701 702 /** 703 * list_last_entry - get the last element from a list 704 * @ptr: the list head to take the element from. 705 * @type: the type of the struct this is embedded in. 706 * @member: the name of the list_head within the struct. 707 * 708 * Note, that list is expected to be not empty. 709 */ 710 #define list_last_entry(ptr, type, member) 711 list_entry((ptr)->prev, type, member) 712 713 /** 714 * list_first_entry_or_null - get the first element from a list 715 * @ptr: the list head to take the element from. 716 * @type: the type of the struct this is embedded in. 717 * @member: the name of the list_head within the struct. 718 * 719 * Note that if the list is empty, it returns NULL. 720 */ 721 #define list_first_entry_or_null(ptr, type, member) ({ 722 struct list_head *head__ = (ptr); 723 struct list_head *pos__ = READ_ONCE(head__->next); 724 pos__ != head__ ? list_entry(pos__, type, member) : NULL; 725 }) 726 727 /** 728 * list_next_entry - get the next element in list 729 * @pos: the type * to cursor 730 * @member: the name of the list_head within the struct. 731 */ 732 #define list_next_entry(pos, member) 733 list_entry((pos)->member.next, typeof(*(pos)), member) 734 735 /** 736 * list_prev_entry - get the prev element in list 737 * @pos: the type * to cursor 738 * @member: the name of the list_head within the struct. 739 */ 740 #define list_prev_entry(pos, member) 741 list_entry((pos)->member.prev, typeof(*(pos)), member) 742 743 /** 744 * list_for_each - iterate over a list 745 * @pos: the &struct list_head to use as a loop cursor. 746 * @head: the head for your list. 747 */ 748 #define list_for_each(pos, head) 749 for (pos = (head)->next; pos != (head); pos = pos->next) 750 751 /** 752 * list_for_each_continue - continue iteration over a list 753 * @pos: the &struct list_head to use as a loop cursor. 754 * @head: the head for your list. 755 * 756 * Continue to iterate over a list, continuing after the current position. 757 */ 758 #define list_for_each_continue(pos, head) 759 for (pos = pos->next; pos != (head); pos = pos->next) 760 761 /** 762 * list_for_each_prev - iterate over a list backwards 763 * @pos: the &struct list_head to use as a loop cursor. 764 * @head: the head for your list. 765 */ 766 #define list_for_each_prev(pos, head) 767 for (pos = (head)->prev; pos != (head); pos = pos->prev) 768 769 /** 770 * list_for_each_safe - iterate over a list safe against removal of list entry 771 * @pos: the &struct list_head to use as a loop cursor. 772 * @n: another &struct list_head to use as temporary storage 773 * @head: the head for your list. 774 */ 775 #define list_for_each_safe(pos, n, head) 776 for (pos = (head)->next, n = pos->next; pos != (head); 777 pos = n, n = pos->next) 778 779 /** 780 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry 781 * @pos: the &struct list_head to use as a loop cursor. 782 * @n: another &struct list_head to use as temporary storage 783 * @head: the head for your list. 784 */ 785 #define list_for_each_prev_safe(pos, n, head) 786 for (pos = (head)->prev, n = pos->prev; 787 pos != (head); 788 pos = n, n = pos->prev) 789 790 /** 791 * list_entry_is_head - test if the entry points to the head of the list 792 * @pos: the type * to cursor 793 * @head: the head for your list. 794 * @member: the name of the list_head within the struct. 795 */ 796 #define list_entry_is_head(pos, head, member) 797 (&pos->member == (head)) 798 799 /** 800 * list_for_each_entry - iterate over list of given type 801 * @pos: the type * to use as a loop cursor. 802 * @head: the head for your list. 803 * @member: the name of the list_head within the struct. 804 */ 805 #define list_for_each_entry(pos, head, member) 806 for (pos = list_first_entry(head, typeof(*pos), member); 807 !list_entry_is_head(pos, head, member); 808 pos = list_next_entry(pos, member)) 809 810 /** 811 * list_for_each_entry_reverse - iterate backwards over list of given type. 812 * @pos: the type * to use as a loop cursor. 813 * @head: the head for your list. 814 * @member: the name of the list_head within the struct. 815 */ 816 #define list_for_each_entry_reverse(pos, head, member) 817 for (pos = list_last_entry(head, typeof(*pos), member); 818 !list_entry_is_head(pos, head, member); 819 pos = list_prev_entry(pos, member)) 820 821 /** 822 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() 823 * @pos: the type * to use as a start point 824 * @head: the head of the list 825 * @member: the name of the list_head within the struct. 826 * 827 * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). 828 */ 829 #define list_prepare_entry(pos, head, member) 830 ((pos) ? : list_entry(head, typeof(*pos), member)) 831 832 /** 833 * list_for_each_entry_continue - continue iteration over list of given type 834 * @pos: the type * to use as a loop cursor. 835 * @head: the head for your list. 836 * @member: the name of the list_head within the struct. 837 * 838 * Continue to iterate over list of given type, continuing after 839 * the current position. 840 */ 841 #define list_for_each_entry_continue(pos, head, member) 842 for (pos = list_next_entry(pos, member); 843 !list_entry_is_head(pos, head, member); 844 pos = list_next_entry(pos, member)) 845 846 /** 847 * list_for_each_entry_continue_reverse - iterate backwards from the given point 848 * @pos: the type * to use as a loop cursor. 849 * @head: the head for your list. 850 * @member: the name of the list_head within the struct. 851 * 852 * Start to iterate over list of given type backwards, continuing after 853 * the current position. 854 */ 855 #define list_for_each_entry_continue_reverse(pos, head, member) 856 for (pos = list_prev_entry(pos, member); 857 !list_entry_is_head(pos, head, member); 858 pos = list_prev_entry(pos, member)) 859 860 /** 861 * list_for_each_entry_from - iterate over list of given type from the current point 862 * @pos: the type * to use as a loop cursor. 863 * @head: the head for your list. 864 * @member: the name of the list_head within the struct. 865 * 866 * Iterate over list of given type, continuing from current position. 867 */ 868 #define list_for_each_entry_from(pos, head, member) 869 for (; !list_entry_is_head(pos, head, member); 870 pos = list_next_entry(pos, member)) 871 872 /** 873 * list_for_each_entry_from_reverse - iterate backwards over list of given type 874 * from the current point 875 * @pos: the type * to use as a loop cursor. 876 * @head: the head for your list. 877 * @member: the name of the list_head within the struct. 878 * 879 * Iterate backwards over list of given type, continuing from current position. 880 */ 881 #define list_for_each_entry_from_reverse(pos, head, member) 882 for (; !list_entry_is_head(pos, head, member); 883 pos = list_prev_entry(pos, member)) 884 885 /** 886 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 887 * @pos: the type * to use as a loop cursor. 888 * @n: another type * to use as temporary storage 889 * @head: the head for your list. 890 * @member: the name of the list_head within the struct. 891 */ 892 #define list_for_each_entry_safe(pos, n, head, member) 893 for (pos = list_first_entry(head, typeof(*pos), member), 894 n = list_next_entry(pos, member); 895 !list_entry_is_head(pos, head, member); 896 pos = n, n = list_next_entry(n, member)) 897 898 /** 899 * list_for_each_entry_safe_continue - continue list iteration safe against removal 900 * @pos: the type * to use as a loop cursor. 901 * @n: another type * to use as temporary storage 902 * @head: the head for your list. 903 * @member: the name of the list_head within the struct. 904 * 905 * Iterate over list of given type, continuing after current point, 906 * safe against removal of list entry. 907 */ 908 #define list_for_each_entry_safe_continue(pos, n, head, member) 909 for (pos = list_next_entry(pos, member), 910 n = list_next_entry(pos, member); 911 !list_entry_is_head(pos, head, member); 912 pos = n, n = list_next_entry(n, member)) 913 914 /** 915 * list_for_each_entry_safe_from - iterate over list from current point safe against removal 916 * @pos: the type * to use as a loop cursor. 917 * @n: another type * to use as temporary storage 918 * @head: the head for your list. 919 * @member: the name of the list_head within the struct. 920 * 921 * Iterate over list of given type from current point, safe against 922 * removal of list entry. 923 */ 924 #define list_for_each_entry_safe_from(pos, n, head, member) 925 for (n = list_next_entry(pos, member); 926 !list_entry_is_head(pos, head, member); 927 pos = n, n = list_next_entry(n, member)) 928 929 /** 930 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal 931 * @pos: the type * to use as a loop cursor. 932 * @n: another type * to use as temporary storage 933 * @head: the head for your list. 934 * @member: the name of the list_head within the struct. 935 * 936 * Iterate backwards over list of given type, safe against removal 937 * of list entry. 938 */ 939 #define list_for_each_entry_safe_reverse(pos, n, head, member) 940 for (pos = list_last_entry(head, typeof(*pos), member), 941 n = list_prev_entry(pos, member); 942 !list_entry_is_head(pos, head, member); 943 pos = n, n = list_prev_entry(n, member)) 944 945 946 /* 947 * Double linked lists with a single pointer list head. 948 * Mostly useful for hash tables where the two pointer list head is 949 * too wasteful. 950 * You lose the ability to access the tail in O(1). 951 */ 952 953 #define HLIST_HEAD_INIT { .first = NULL } 954 #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } 955 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 956 static inline void INIT_HLIST_NODE(struct hlist_node *h) 957 { 958 h->next = NULL; 959 h->pprev = NULL; 960 } 961 962 #endif
这个是基于manjaro 2021年8月20升级的,linux内核是linux-5.10.59修改的,不同的内核实现并不完全一样
测试函数testLi2.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdbool.h> 4 #include <string.h> 5 #include "list1.h" 6 7 #define MaxSize 10 8 9 typedef struct _doc{ 10 int id; 11 bool sex; 12 char name[MaxSize]; 13 char typed[MaxSize]; 14 15 struct list_head list; 16 } Doctor; 17 18 void creatNumStudent(Doctor *mylist){ 19 int num = 0; 20 printf("please input you want create the number, not zero: "); 21 scanf("%d", &num); 22 23 for(int i=num; i!=0; --i){ 24 Doctor *tmp= (Doctor *)malloc(sizeof(Doctor)); 25 printf("enter id sex and name and typed:"); 26 scanf("%d %d %s %s", &tmp->id, &tmp->sex, &tmp->name, &tmp->typed); 27 list_add(&(tmp->list), &(mylist->list)); 28 } 29 printf("\n"); 30 31 return; 32 } 33 34 void outputInfo(bool sex, Doctor *tmp){ 35 char str[MaxSize]; 36 37 if(sex){ 38 strcpy(str, "female"); 39 }else{ 40 strcpy(str, "male"); 41 } 42 43 printf("id= %d sex= %s name= %s typed= %s\n", tmp->id, str, tmp->name, tmp->typed); 44 45 return; 46 } 47 48 int main(int argc, char **argv){ 49 50 Doctor *tmp; 51 struct list_head *pos, *q; 52 //unsigned int i; 53 54 Doctor mylist; 55 INIT_LIST_HEAD(&mylist.list); 56 57 creatNumStudent(&mylist); 58 59 printf("traversing the list using list_for_each_entry()\n"); 60 list_for_each_entry(tmp, &mylist.list, list){ 61 outputInfo(tmp->sex, tmp); 62 } 63 printf("\n"); 64 65 printf("deleting the list using list_for_each_safe()\n"); 66 list_for_each_safe(pos, q, &mylist.list){ 67 tmp= list_entry(pos, Doctor, list); 68 69 outputInfo(tmp->sex, tmp); 70 71 list_del(pos); 72 free(tmp); 73 } 74 75 return 0; 76 }
测试结果为:
please input you want create the number, not zero: 3 enter id sex and name and typed:101 0 zhangsan tooth enter id sex and name and typed:102 1 lisi eye enter id sex and name and typed:103 0 wangwu nose traversing the list using list_for_each_entry() id= 103 sex= male name= wangwu typed= nose id= 102 sex= female name= lisi typed= eye id= 101 sex= male name= zhangsan typed= tooth deleting the list using list_for_each_safe() id= 103 sex= male name= wangwu typed= nose id= 102 sex= female name= lisi typed= eye id= 101 sex= male name= zhangsan typed= tooth
和原来唯一的区别就是list1.h文件是自己魔改的结果,使用更全面。代码很是简单,不多做说明。