Linux 内核链表移植

    我参考网上的文章修改了移植后的 Linux 内核的双向链表和 HASH 链表, 使之适用于 Linux 和 Windows 平台. 可以在用户态下使用. 任何后果, 本人概不负责!

    下面是全部代码:

    1. /**
    2. * dhlist.h
    3. * - deque list and hash list from Linux Kernel
    4. *
    5. * from Linux Kernel
    6. * for Windows and Linux
    7. *
    8. * modified by cheungmine
    9. * 2013-4
    10. */
    11. #ifndef _DH_LIST_H
    12. #define _DH_LIST_H
    13. #ifdef typeof
    14. static inline void prefetch(const void* x) { ; }
    15. static inline void prefetchw(const void* x) { ; }
    16. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    17. #define container_of(ptr, type, member) ( { \
    18. const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    19. (type *)( (char *)__mptr - offsetof(type,member) ); } )
    20. #else
    21. static inline int prefetch(const void* x) { ; return 1; }
    22. static inline int prefetchw(const void* x) { ; return 1; }
    23. #ifndef offsetof
    24. #define offsetof(type, field) ((LONG)(LONG_PTR)&((type *)0)->field)
    25. #endif
    26. #ifndef container_of
    27. #define container_of(address, type, field) \
    28. ((type *)((char *)(address) - offsetof(type, field)))
    29. #endif
    30. #endif
    31. #ifndef LIST_POISON1
    32. #define LIST_POISON1 ((void *) 0x00100100)
    33. #endif
    34. #ifndef LIST_POISON2
    35. #define LIST_POISON2 ((void *) 0x00200200)
    36. #endif
    37. struct list_head
    38. {
    39. struct list_head* next, * prev;
    40. };
    41. #define LIST_HEAD_INIT(name) { &(name), &(name) }
    42. #define LIST_HEAD(name) \
    43. struct list_head name = LIST_HEAD_INIT(name)
    44. #define INIT_LIST_HEAD(ptr) do { \
    45. (ptr)->next = (ptr); (ptr)->prev = (ptr); \
    46. } while (0)
    47. /*
    48. * Insert a new entry between two known consecutive entries.
    49. *
    50. * This is only for internal list manipulation where we know
    51. * the prev/next entries already!
    52. */
    53. static inline void __list_add(struct list_head* _new,
    54. struct list_head* prev,
    55. struct list_head* next)
    56. {
    57. next->prev = _new;
    58. _new->next = next;
    59. _new->prev = prev;
    60. prev->next = _new;
    61. }
    62. /**
    63. * list_add - add a new entry
    64. * @new: new entry to be added
    65. * @head: list head to add it after
    66. *
    67. * Insert a new entry after the specified head.
    68. * This is good for implementing stacks.
    69. */
    70. static inline void list_add(struct list_head* _new, struct list_head* head)
    71. {
    72. __list_add(_new, head, head->next);
    73. }
    74. /**
    75. * list_add_tail - add a new entry
    76. * @new: new entry to be added
    77. * @head: list head to add it before
    78. *
    79. * Insert a new entry before the specified head.
    80. * This is useful for implementing queues.
    81. */
    82. static inline void list_add_tail(struct list_head* _new, struct list_head* head)
    83. {
    84. __list_add(_new, head->prev, head);
    85. }
    86. static inline void __list_del(struct list_head* prev, struct list_head* next)
    87. {
    88. next->prev = prev;
    89. prev->next = next;
    90. }
    91. static inline void list_del(struct list_head* entry)
    92. {
    93. __list_del(entry->prev, entry->next);
    94. entry->next = (struct list_head*)LIST_POISON1;
    95. entry->prev = (struct list_head*)LIST_POISON2;
    96. }
    97. static inline void list_del_init(struct list_head* entry)
    98. {
    99. __list_del(entry->prev, entry->next);
    100. INIT_LIST_HEAD(entry);
    101. }
    102. static inline void list_move(struct list_head* list, struct list_head* head)
    103. {
    104. __list_del(list->prev, list->next);
    105. list_add(list, head);
    106. }
    107. static inline void list_move_tail(struct list_head* list, struct list_head* head)
    108. {
    109. __list_del(list->prev, list->next);
    110. list_add_tail(list, head);
    111. }
    112. static inline int list_empty(const struct list_head* head)
    113. {
    114. return head->next == head;
    115. }
    116. static inline int list_empty_careful(const struct list_head* head)
    117. {
    118. struct list_head* next = head->next;
    119. return (next == head) && (next == head->prev);
    120. }
    121. static inline void __list_splice(struct list_head* list, struct list_head* head)
    122. {
    123. struct list_head* first = list->next;
    124. struct list_head* last = list->prev;
    125. struct list_head* at = head->next;
    126. first->prev = head;
    127. head->next = first;
    128. last->next = at;
    129. at->prev = last;
    130. }
    131. /**
    132. * list_splice - join two lists
    133. * @list: the new list to add.
    134. * @head: the place to add it in the first list.
    135. */
    136. static inline void list_splice(struct list_head* list, struct list_head* head)
    137. {
    138. if (!list_empty(list)) {
    139. __list_splice(list, head);
    140. }
    141. }
    142. /**
    143. * list_splice_init - join two lists and reinitialise the emptied list.
    144. * @list: the new list to add.
    145. * @head: the place to add it in the first list.
    146. *
    147. * The list at @list is reinitialised
    148. */
    149. static inline void list_splice_init(struct list_head* list, struct list_head* head)
    150. {
    151. if (!list_empty(list)) {
    152. __list_splice(list, head);
    153. INIT_LIST_HEAD(list);
    154. }
    155. }
    156. #define list_entry(ptr, type, member) \
    157. container_of(ptr, type, member)
    158. #define list_for_each(pos, head) \
    159. for (pos = (head)->next; prefetch(pos->next), pos != (head); \
    160. pos = pos->next)
    161. #define __list_for_each(pos, head) \
    162. for (pos = (head)->next; pos != (head); pos = pos->next)
    163. #define list_for_each_prev(pos, head) \
    164. for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
    165. pos = pos->prev)
    166. #define list_for_each_safe(pos, n, head) \
    167. for (pos = (head)->next, n = pos->next; pos != (head); \
    168. pos = n, n = pos->next)
    169. #ifdef typeof
    170. #define list_for_each_entry(pos, head, member) \
    171. for (pos = list_entry((head)->next, typeof(*pos), member); \
    172. prefetch(pos->member.next), &pos->member != (head); \
    173. pos = list_entry(pos->member.next, typeof(*pos), member))
    174. #define list_for_each_entry_reverse(pos, head, member) \
    175. for (pos = list_entry((head)->prev, typeof(*pos), member); \
    176. prefetch(pos->member.prev), &pos->member != (head); \
    177. pos = list_entry(pos->member.prev, typeof(*pos), member))
    178. #define list_prepare_entry(pos, head, member) \
    179. ((pos) ? : list_entry(head, typeof(*pos), member))
    180. #define list_for_each_entry_continue(pos, head, member) \
    181. for (pos = list_entry(pos->member.next, typeof(*pos), member); \
    182. prefetch(pos->member.next), &pos->member != (head); \
    183. pos = list_entry(pos->member.next, typeof(*pos), member))
    184. #define list_for_each_entry_safe(pos, n, head, member) \
    185. for (pos = list_entry((head)->next, typeof(*pos), member), \
    186. n = list_entry(pos->member.next, typeof(*pos), member); \
    187. &pos->member != (head); \
    188. pos = n, n = list_entry(n->member.next, typeof(*n), member))
    189. #else
    190. #define list_for_each_entry(pos, typeof_pos, head, member) \
    191. for (pos = list_entry((head)->next, typeof_pos, member); \
    192. prefetch(pos->member.next), &pos->member != (head); \
    193. pos = list_entry(pos->member.next, typeof_pos, member))
    194. #define list_for_each_entry_reverse(pos, typeof_pos, head, member) \
    195. for (pos = list_entry((head)->prev, typeof_pos, member); \
    196. prefetch(pos->member.prev), &pos->member != (head); \
    197. pos = list_entry(pos->member.prev, typeof_pos, member))
    198. #define list_prepare_entry(pos, typeof_pos, head, member) \
    199. ((pos) ? : list_entry(head, typeof_pos, member))
    200. #define list_for_each_entry_continue(pos, typeof_pos, head, member) \
    201. for (pos = list_entry(pos->member.next, typeof_pos, member); \
    202. prefetch(pos->member.next), &pos->member != (head); \
    203. pos = list_entry(pos->member.next, typeof_pos, member))
    204. #define list_for_each_entry_safe(pos, typeof_pos, n, typeof_n, head, member) \
    205. for (pos = list_entry((head)->next, typeof_pos, member), \
    206. n = list_entry(pos->member.next, typeof_pos, member); \
    207. &pos->member != (head); \
    208. pos = n, n = list_entry(n->member.next, typeof_n, member))
    209. #endif
    210. /**
    211. * HASH LIST
    212. */
    213. struct hlist_head {
    214. struct hlist_node* first;
    215. };
    216. struct hlist_node {
    217. struct hlist_node* next, ** pprev;
    218. };
    219. #define HLIST_HEAD_INIT { .first = NULL }
    220. #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
    221. #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
    222. #define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
    223. static inline int hlist_unhashed(const struct hlist_node* h)
    224. {
    225. return !h->pprev;
    226. }
    227. static inline int hlist_empty(const struct hlist_head* h)
    228. {
    229. return !h->first;
    230. }
    231. static inline void __hlist_del(struct hlist_node* n)
    232. {
    233. struct hlist_node* next = n->next;
    234. struct hlist_node** pprev = n->pprev;
    235. *pprev = next;
    236. if (next) {
    237. next->pprev = pprev;
    238. }
    239. }
    240. static inline void hlist_del(struct hlist_node* n)
    241. {
    242. __hlist_del(n);
    243. n->next = (struct hlist_node*)LIST_POISON1;
    244. n->pprev = (struct hlist_node**)LIST_POISON2;
    245. }
    246. static inline void hlist_del_init(struct hlist_node* n)
    247. {
    248. if (n->pprev) {
    249. __hlist_del(n);
    250. INIT_HLIST_NODE(n);
    251. }
    252. }
    253. static inline void hlist_add_head(struct hlist_node* n, struct hlist_head* h)
    254. {
    255. struct hlist_node* first = h->first;
    256. n->next = first;
    257. if (first) {
    258. first->pprev = &n->next;
    259. }
    260. h->first = n;
    261. n->pprev = &h->first;
    262. }
    263. /* next must be != NULL */
    264. static inline void hlist_add_before(struct hlist_node* n, struct hlist_node* next)
    265. {
    266. n->pprev = next->pprev;
    267. n->next = next;
    268. next->pprev = &n->next;
    269. *(n->pprev) = n;
    270. }
    271. static inline void hlist_add_after(struct hlist_node* n, struct hlist_node* next)
    272. {
    273. next->next = n->next;
    274. n->next = next;
    275. next->pprev = &n->next;
    276. if (next->next) {
    277. next->next->pprev = &next->next;
    278. }
    279. }
    280. #define hlist_entry(ptr, type, member) \
    281. container_of(ptr,type,member)
    282. #ifdef typeof
    283. #define hlist_for_each(pos, head) \
    284. for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
    285. pos = pos->next)
    286. #define hlist_for_each_safe(pos, n, head) \
    287. for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
    288. pos = n)
    289. #define hlist_for_each_entry(tpos, pos, head, member) \
    290. for (pos = (head)->first; \
    291. pos && ({ prefetch(pos->next); 1;}) && \
    292. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    293. pos = pos->next)
    294. #define hlist_for_each_entry_continue(tpos, pos, member) \
    295. for (pos = (pos)->next; \
    296. pos && ({ prefetch(pos->next); 1;}) && \
    297. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    298. pos = pos->next)
    299. #define hlist_for_each_entry_from(tpos, pos, member) \
    300. for (; pos && ({ prefetch(pos->next); 1;}) && \
    301. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    302. pos = pos->next)
    303. #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
    304. for (pos = (head)->first; \
    305. pos && ({ n = pos->next; 1; }) && \
    306. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
    307. pos = n)
    308. #else
    309. #define hlist_for_each(pos, head) \
    310. for (pos = (head)->first; pos && prefetch(pos->next); pos = pos->next)
    311. #define hlist_for_each_safe(pos, n, head) \
    312. for (pos = (head)->first; pos && ((n=pos->next) == n); pos = n)
    313. #define hlist_for_each_entry(tpos, typeof_tpos, pos, head, member) \
    314. for (pos = (head)->first; \
    315. pos && prefetch(pos->next) && \
    316. ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \
    317. pos = pos->next)
    318. #define hlist_for_each_entry_continue(tpos, typeof_tpos, pos, member) \
    319. for (pos = (pos)->next; \
    320. pos && prefetch(pos->next) && \
    321. ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \
    322. pos = pos->next)
    323. #define hlist_for_each_entry_from(tpos, typeof_tpos, pos, member) \
    324. for (; pos && prefetch(pos->next) && \
    325. ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \
    326. pos = pos->next)
    327. #define hlist_for_each_entry_safe(tpos, typeof_tpos, pos, n, head, member) \
    328. for (pos = (head)->first; \
    329. pos && ((n = pos->next) == n) && \
    330. ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \
    331. pos = n)
    332. #endif
    333. #endif /* _DH_LIST_H */

    测试程序 (Windows, C++):

    1. /**
    2. * test dhlist
    3. * cheungmine
    4. */
    5. //#define _CRTDBG_MAP_ALLOC
    6. #include <stdlib.h>
    7. #include <crtdbg.h>
    8. #include <assert.h>
    9. #include <stdio.h>
    10. #include <string.h>
    11. #include <memory.h>
    12. #include <windows.h>
    13. #include "dhlist.h"
    14. struct ST {
    15. unsigned char ch;
    16. int this_data;
    17. struct list_head i_list;
    18. int more_data;
    19. struct hlist_node i_hash;
    20. char str_data[32];
    21. int end_data;
    22. } *st;
    23. #define HASHSIZE 0xff
    24. #define LISTSIZE 4096
    25. struct list_head list1;
    26. struct hlist_head hlist[HASHSIZE + 1];
    27. unsigned int gethash(int c)
    28. {
    29. return (c & HASHSIZE);
    30. }
    31. int main()
    32. {
    33. int i;
    34. unsigned int hash;
    35. struct list_head* list, * node;
    36. struct hlist_node* hp;
    37. struct hlist_node* hn;
    38. INIT_LIST_HEAD(&list1);
    39. for (hash = 0; hash <= HASHSIZE; hash++) {
    40. INIT_HLIST_HEAD(&hlist[hash]);
    41. }
    42. for (i = 0; i < LISTSIZE; i++) {
    43. struct ST* p = (struct ST*)malloc(sizeof(*p));
    44. if (!p) {
    45. printf("malloc failed.\n");
    46. break;
    47. }
    48. p->ch = 'a' + i;
    49. sprintf_s(p->str_data, 32, "data:%d", i);
    50. // 串入长串
    51. list_add(&p->i_list, &list1);
    52. // 串入HASH短串
    53. hash = gethash(p->ch);
    54. printf("ALLOC %x %d %p %u\n", p->ch, i, p, hash);
    55. if (hash > HASHSIZE) {
    56. printf("**********ERROR**********\n");
    57. }
    58. else {
    59. hlist_add_head(&p->i_hash, &hlist[hash]);
    60. }
    61. }
    62. // 通过长铁丝遍历
    63. i = 0;
    64. list_for_each(list, &list1) {
    65. struct ST* p = list_entry(list, struct ST, i_list);
    66. printf("%p value %d = %d\n", p, i, (int)p->ch);
    67. i++;
    68. }
    69. printf("total %d \n", i);
    70. printf("通过hash串查找内容'C'的箱子\n");
    71. hash = gethash('c');
    72. hlist_for_each(hp, &hlist[hash]) {
    73. struct ST* p = hlist_entry(hp, struct ST, i_hash);
    74. printf("hlist: %c\n", p->ch);
    75. }
    76. printf("通过hash串查找内容'C'的箱子并删除之\n");
    77. hlist_for_each_safe(hp, hn, &hlist[hash]) {
    78. struct ST* p = hlist_entry(hp, struct ST, i_hash);
    79. printf("hlist_del: %c; %s\n", p->ch, p->str_data);
    80. hlist_del(hp);
    81. }
    82. printf("通过hash串查找内容'C'的箱子\n");
    83. hlist_for_each(hp, &hlist[hash]) {
    84. struct ST* p = hlist_entry(hp, struct ST, i_hash);
    85. printf("hlist: %c\n", p->ch);
    86. }
    87. printf("删除全部节点箱子\n");
    88. list_for_each_safe(list, node, &list1) {
    89. struct ST* p = list_entry(list, struct ST, i_list);
    90. list_del(list);
    91. free(p);
    92. }
    93. // 检测内存泄露
    94. _CrtDumpMemoryLeaks();
    95. return 0;
    96. }

    参考文章:

    http://www.chinaunix.net/old_jh/23/941100.html

    http://linux.chinaunix.net/techdoc/system/2007/12/28/975345.shtml

    原文:https://blog.csdn.net/iteye_11790/article/details/82489188?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-82489188-blog-79281920.pc_relevant_multi_platform_whitelistv1&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-82489188-blog-79281920.pc_relevant_multi_platform_whitelistv1&utm_relevant_index=1