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("\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文件是自己魔改的结果,使用更全面。代码很是简单,不多做说明。

linux内核数据结构之链表-再实现

上一篇:C++第07课 继承


下一篇:JavaWeb_JSP