《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
4.5 KiB

  1. #ifndef __LIBS_LIST_H__
  2. #define __LIBS_LIST_H__
  3. #ifndef __ASSEMBLER__
  4. #include <defs.h>
  5. /* *
  6. * Simple doubly linked list implementation.
  7. *
  8. * Some of the internal functions ("__xxx") are useful when manipulating
  9. * whole lists rather than single entries, as sometimes we already know
  10. * the next/prev entries and we can generate better code by using them
  11. * directly rather than using the generic single-entry routines.
  12. * */
  13. struct list_entry {
  14. struct list_entry *prev, *next;
  15. };
  16. typedef struct list_entry list_entry_t;
  17. static inline void list_init(list_entry_t *elm) __attribute__((always_inline));
  18. static inline void list_add(list_entry_t *listelm, list_entry_t *elm) __attribute__((always_inline));
  19. static inline void list_add_before(list_entry_t *listelm, list_entry_t *elm) __attribute__((always_inline));
  20. static inline void list_add_after(list_entry_t *listelm, list_entry_t *elm) __attribute__((always_inline));
  21. static inline void list_del(list_entry_t *listelm) __attribute__((always_inline));
  22. static inline void list_del_init(list_entry_t *listelm) __attribute__((always_inline));
  23. static inline bool list_empty(list_entry_t *list) __attribute__((always_inline));
  24. static inline list_entry_t *list_next(list_entry_t *listelm) __attribute__((always_inline));
  25. static inline list_entry_t *list_prev(list_entry_t *listelm) __attribute__((always_inline));
  26. static inline void __list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) __attribute__((always_inline));
  27. static inline void __list_del(list_entry_t *prev, list_entry_t *next) __attribute__((always_inline));
  28. /* *
  29. * list_init - initialize a new entry
  30. * @elm: new entry to be initialized
  31. * */
  32. static inline void
  33. list_init(list_entry_t *elm) {
  34. elm->prev = elm->next = elm;
  35. }
  36. /* *
  37. * list_add - add a new entry
  38. * @listelm: list head to add after
  39. * @elm: new entry to be added
  40. *
  41. * Insert the new element @elm *after* the element @listelm which
  42. * is already in the list.
  43. * */
  44. static inline void
  45. list_add(list_entry_t *listelm, list_entry_t *elm) {
  46. list_add_after(listelm, elm);
  47. }
  48. /* *
  49. * list_add_before - add a new entry
  50. * @listelm: list head to add before
  51. * @elm: new entry to be added
  52. *
  53. * Insert the new element @elm *before* the element @listelm which
  54. * is already in the list.
  55. * */
  56. static inline void
  57. list_add_before(list_entry_t *listelm, list_entry_t *elm) {
  58. __list_add(elm, listelm->prev, listelm);
  59. }
  60. /* *
  61. * list_add_after - add a new entry
  62. * @listelm: list head to add after
  63. * @elm: new entry to be added
  64. *
  65. * Insert the new element @elm *after* the element @listelm which
  66. * is already in the list.
  67. * */
  68. static inline void
  69. list_add_after(list_entry_t *listelm, list_entry_t *elm) {
  70. __list_add(elm, listelm, listelm->next);
  71. }
  72. /* *
  73. * list_del - deletes entry from list
  74. * @listelm: the element to delete from the list
  75. *
  76. * Note: list_empty() on @listelm does not return true after this, the entry is
  77. * in an undefined state.
  78. * */
  79. static inline void
  80. list_del(list_entry_t *listelm) {
  81. __list_del(listelm->prev, listelm->next);
  82. }
  83. /* *
  84. * list_del_init - deletes entry from list and reinitialize it.
  85. * @listelm: the element to delete from the list.
  86. *
  87. * Note: list_empty() on @listelm returns true after this.
  88. * */
  89. static inline void
  90. list_del_init(list_entry_t *listelm) {
  91. list_del(listelm);
  92. list_init(listelm);
  93. }
  94. /* *
  95. * list_empty - tests whether a list is empty
  96. * @list: the list to test.
  97. * */
  98. static inline bool
  99. list_empty(list_entry_t *list) {
  100. return list->next == list;
  101. }
  102. /* *
  103. * list_next - get the next entry
  104. * @listelm: the list head
  105. **/
  106. static inline list_entry_t *
  107. list_next(list_entry_t *listelm) {
  108. return listelm->next;
  109. }
  110. /* *
  111. * list_prev - get the previous entry
  112. * @listelm: the list head
  113. **/
  114. static inline list_entry_t *
  115. list_prev(list_entry_t *listelm) {
  116. return listelm->prev;
  117. }
  118. /* *
  119. * Insert a new entry between two known consecutive entries.
  120. *
  121. * This is only for internal list manipulation where we know
  122. * the prev/next entries already!
  123. * */
  124. static inline void
  125. __list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) {
  126. prev->next = next->prev = elm;
  127. elm->next = next;
  128. elm->prev = prev;
  129. }
  130. /* *
  131. * Delete a list entry by making the prev/next entries point to each other.
  132. *
  133. * This is only for internal list manipulation where we know
  134. * the prev/next entries already!
  135. * */
  136. static inline void
  137. __list_del(list_entry_t *prev, list_entry_t *next) {
  138. prev->next = next;
  139. next->prev = prev;
  140. }
  141. #endif /* !__ASSEMBLER__ */
  142. #endif /* !__LIBS_LIST_H__ */