zoukankan      html  css  js  c++  java
  • linux内核数据结构之链表-再实现

    ####使用自己裁剪的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("
    ");
    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
    ", 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()
    ");
    60     list_for_each_entry(tmp, &mylist.list, list){
    61         outputInfo(tmp->sex, tmp);
    62     }
    63     printf("
    ");
    64 
    65     printf("deleting the list using list_for_each_safe()
    ");
    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文件是自己魔改的结果,使用更全面。代码很是简单,不多做说明。

    人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。
  • 相关阅读:
    会话技术——Cookie
    Servlet——Request和Response
    #Servlet——Web之间跳转和信息共享、三大作用域对象
    8个技巧教你区分LED灯具优劣
    建筑景观LED照明设计要考虑哪些?
    荧光材料物理特性对白光LED光输出冷热比的影响
    金刚战神D系列户外全彩D5.92
    2020爱你爱你,海佳集团祝您新年快乐!
    复制文本
    超市会员系统
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/15170719.html
Copyright © 2011-2022 走看看