Linux Kernel linked list Transplantation

Source: Internet
Author: User
Tags prefetch

Linux Kernel linked list Transplantation

I have modified the two-way linked list and hash linked list of the transplanted Linux kernel by referring to the online article, so that it applies to Linux and Windows platforms. It can be used in user mode. I am not responsible for any consequences!

The following is all the code:

/** * dhlist.h *  - deque list and hash list from Linux Kernel * * from Linux Kernel * for Windows and Linux *  * modified by cheungmine * 2013-4 */#ifndef _DH_LIST_H#define _DH_LIST_H#ifdef typeofstatic inline void prefetch(const void *x) {;}static inline void prefetchw(const void *x) {;}#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#define container_of(ptr, type, member) ( { \    const typeof( ((type *)0)->member ) *__mptr = (ptr); \    (type *)( (char *)__mptr - offsetof(type,member) ); } )#elsestatic inline int prefetch(const void *x) {;return 1;}static inline int prefetchw(const void *x) {;return 1;}#define offsetof(type, field)    ((LONG)(LONG_PTR)&((type *)0)->field)#define container_of(address, type, field) \    ((type *)((char *)(address) - offsetof(type, field)))#endif#ifndef LIST_POISON1#define LIST_POISON1 ((void *) 0x00100100)#endif#ifndef LIST_POISON2#define LIST_POISON2 ((void *) 0x00200200)#endifstruct list_head{    struct list_head *next, *prev;};#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \    struct list_head name = LIST_HEAD_INIT(name)#define INIT_LIST_HEAD(ptr) do { \        (ptr)->next = (ptr); (ptr)->prev = (ptr); \    } while (0)/* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */static inline void __list_add(struct list_head *_new,                              struct list_head *prev,                              struct list_head *next){    next->prev = _new;    _new->next = next;    _new->prev = prev;    prev->next = _new;}/** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */static inline void list_add(struct list_head *_new, struct list_head *head){    __list_add(_new, head, head->next);}/** * list_add_tail - add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */static inline void list_add_tail(struct list_head *_new, struct list_head *head){    __list_add(_new, head->prev, head);}static inline void __list_del(struct list_head * prev, struct list_head * next){    next->prev = prev;    prev->next = next;}static inline void list_del(struct list_head *entry){    __list_del(entry->prev, entry->next);    entry->next = (list_head*) LIST_POISON1;    entry->prev = (list_head*) LIST_POISON2;}static inline void list_del_init(struct list_head *entry){    __list_del(entry->prev, entry->next);    INIT_LIST_HEAD(entry);}static inline void list_move(struct list_head *list, struct list_head *head){    __list_del(list->prev, list->next);    list_add(list, head);}static inline void list_move_tail(struct list_head *list, struct list_head *head){    __list_del(list->prev, list->next);    list_add_tail(list, head);}static inline int list_empty(const struct list_head *head){    return head->next == head;}static inline int list_empty_careful(const struct list_head *head){    struct list_head *next = head->next;    return (next == head) && (next == head->prev);}static inline void __list_splice(struct list_head *list, struct list_head *head){    struct list_head *first = list->next;    struct list_head *last = list->prev;    struct list_head *at = head->next;    first->prev = head;    head->next = first;    last->next = at;    at->prev = last;}/** * list_splice - join two lists * @list: the new list to add. * @head: the place to add it in the first list. */static inline void list_splice(struct list_head *list, struct list_head *head){    if (!list_empty(list)) {        __list_splice(list, head);    }}/** * list_splice_init - join two lists and reinitialise the emptied list. * @list: the new list to add. * @head: the place to add it in the first list. * * The list at @list is reinitialised */static inline void list_splice_init(struct list_head *list, struct list_head *head){    if (!list_empty(list)) {        __list_splice(list, head);        INIT_LIST_HEAD(list);    }}#define list_entry(ptr, type, member) \    container_of(ptr, type, member)#define list_for_each(pos, head) \    for (pos = (head)->next; prefetch(pos->next), pos != (head); \         pos = pos->next)#define __list_for_each(pos, head) \    for (pos = (head)->next; pos != (head); pos = pos->next)#define list_for_each_prev(pos, head) \    for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \         pos = pos->prev)#define list_for_each_safe(pos, n, head) \    for (pos = (head)->next, n = pos->next; pos != (head); \         pos = n, n = pos->next)#ifdef typeof#define list_for_each_entry(pos, head, member) \    for (pos = list_entry((head)->next, typeof(*pos), member); \         prefetch(pos->member.next), &pos->member != (head); \         pos = list_entry(pos->member.next, typeof(*pos), member))#define list_for_each_entry_reverse(pos, head, member) \    for (pos = list_entry((head)->prev, typeof(*pos), member); \         prefetch(pos->member.prev), &pos->member != (head); \         pos = list_entry(pos->member.prev, typeof(*pos), member))#define list_prepare_entry(pos, head, member) \        ((pos) ? : list_entry(head, typeof(*pos), member))#define list_for_each_entry_continue(pos, head, member) \    for (pos = list_entry(pos->member.next, typeof(*pos), member); \         prefetch(pos->member.next), &pos->member != (head); \         pos = list_entry(pos->member.next, typeof(*pos), member))#define list_for_each_entry_safe(pos, n, head, member) \    for (pos = list_entry((head)->next, typeof(*pos), member), \           n = list_entry(pos->member.next, typeof(*pos), member); \         &pos->member != (head); \         pos = n, n = list_entry(n->member.next, typeof(*n), member))#else#define list_for_each_entry(pos, typeof_pos, head, member) \    for (pos = list_entry((head)->next, typeof_pos, member); \         prefetch(pos->member.next), &pos->member != (head); \         pos = list_entry(pos->member.next, typeof_pos, member))#define list_for_each_entry_reverse(pos, typeof_pos, head, member) \    for (pos = list_entry((head)->prev, typeof_pos, member); \         prefetch(pos->member.prev), &pos->member != (head); \         pos = list_entry(pos->member.prev, typeof_pos, member))#define list_prepare_entry(pos, typeof_pos, head, member) \        ((pos) ? : list_entry(head, typeof_pos, member))#define list_for_each_entry_continue(pos, typeof_pos, head, member) \    for (pos = list_entry(pos->member.next, typeof_pos, member); \         prefetch(pos->member.next), &pos->member != (head); \         pos = list_entry(pos->member.next, typeof_pos, member))#define list_for_each_entry_safe(pos, typeof_pos, n, typeof_n, head, member) \    for (pos = list_entry((head)->next, typeof_pos, member), \           n = list_entry(pos->member.next, typeof_pos, member); \         &pos->member != (head); \         pos = n, n = list_entry(n->member.next, typeof_n, member))#endif/** * HASH LIST */struct hlist_head {    struct hlist_node *first;};struct hlist_node {    struct hlist_node *next, **pprev;};#define HLIST_HEAD_INIT { .first = NULL }#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)static inline int hlist_unhashed(const struct hlist_node *h){    return !h->pprev;}static inline int hlist_empty(const struct hlist_head *h){    return !h->first;}static inline void __hlist_del(struct hlist_node *n){    struct hlist_node *next = n->next;    struct hlist_node **pprev = n->pprev;    *pprev = next;    if (next) {        next->pprev = pprev;    }}static inline void hlist_del(struct hlist_node *n){    __hlist_del(n);    n->next = (hlist_node*) LIST_POISON1;    n->pprev = (hlist_node**) LIST_POISON2;}static inline void hlist_del_init(struct hlist_node *n){    if (n->pprev) {        __hlist_del(n);        INIT_HLIST_NODE(n);    }}static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h){    struct hlist_node *first = h->first;    n->next = first;    if (first) {        first->pprev = &n->next;    }    h->first = n;    n->pprev = &h->first;}/* next must be != NULL */static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next){    n->pprev = next->pprev;    n->next = next;    next->pprev = &n->next;    *(n->pprev) = n;}static inline void hlist_add_after(struct hlist_node *n, struct hlist_node *next){    next->next = n->next;    n->next = next;    next->pprev = &n->next;    if (next->next) {        next->next->pprev  = &next->next;    }}#define hlist_entry(ptr, type, member) \    container_of(ptr,type,member)#ifdef typeof#define hlist_for_each(pos, head) \    for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \         pos = pos->next)#define hlist_for_each_safe(pos, n, head) \    for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \         pos = n)#define hlist_for_each_entry(tpos, pos, head, member) \    for (pos = (head)->first; \         pos && ({ prefetch(pos->next); 1;}) && \            ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \         pos = pos->next)#define hlist_for_each_entry_continue(tpos, pos, member) \    for (pos = (pos)->next; \         pos && ({ prefetch(pos->next); 1;}) && \            ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \         pos = pos->next)#define hlist_for_each_entry_from(tpos, pos, member) \    for (; pos && ({ prefetch(pos->next); 1;}) && \            ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \         pos = pos->next)#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \    for (pos = (head)->first; \         pos && ({ n = pos->next; 1; }) && \            ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \         pos = n)#else#define hlist_for_each(pos, head) \    for (pos = (head)->first; pos && prefetch(pos->next); pos = pos->next)#define hlist_for_each_safe(pos, n, head) \    for (pos = (head)->first; pos && ((n=pos->next) == n); pos = n)#define hlist_for_each_entry(tpos, typeof_tpos, pos, head, member) \    for (pos = (head)->first; \         pos && prefetch(pos->next) && \           ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \         pos = pos->next)#define hlist_for_each_entry_continue(tpos, typeof_tpos, pos, member) \    for (pos = (pos)->next; \         pos && prefetch(pos->next) && \            ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \         pos = pos->next)#define hlist_for_each_entry_from(tpos, typeof_tpos, pos, member) \    for (; pos && prefetch(pos->next) && \            ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \         pos = pos->next)#define hlist_for_each_entry_safe(tpos, typeof_tpos, pos, n, head, member) \    for (pos = (head)->first; \         pos && ((n = pos->next) == n) && \            ((tpos = hlist_entry(pos, typeof_tpos, member)) == tpos); \         pos = n)#endif#endif /* _DH_LIST_H */

Test Program (Windows, C ++ ):

/*** Test dhlist * cheungmine */# DEFINE _ crtdbg_map_alloc # include <stdlib. h> # include <crtdbg. h> # include <assert. h> # include <stdio. h> # include <string. h> # include <memory. h> # include <windows. h> # include "dhlist. H "struct st {unsigned char ch; int this_data; struct list_head I _list; int more_data; struct hlist_node I _hash; char str_data [32]; int end_data;} * st; # define hashsize 0xff # define listsize 4096 Struct list_head list1; struct hlist_head hlist [hashsize + 1]; unsigned int gethash (INT c) {return (C & hashsize);} int main () {int I; unsigned int hash; struct list_head * List, * node; struct hlist_node * HP; struct hlist_node * HN; init_list_head (& list1); For (hash = 0; hash <= hashsize; hash ++) {init_hlist_head (& hlist [hash]) ;}for (I = 0; I <listsize; I ++) {struct st * P = (St *) malloc (sizeof (* p )); If (! P) {printf ("malloc failed. \ n "); break;} p-> CH = 'A' + I; sprintf (p-> str_data," data: % d ", I ); // string-in long string list_add (& P-> I _list, & list1); // string-in hash short string hash = gethash (p-> CH ); printf ("alloc % x % d % P % u \ n", p-> CH, I, P, hash); If (hash> hashsize) {printf ("*********** error ************ \ n ");} else {hlist_add_head (& P-> I _hash, & hlist [hash]) ;}// traverse I = 0 through long wire; list_for_each (list, & list1) {struct st * P = list_entry (list, struct St, I _list); printf ("% P value % d = % d \ n", P, I, (INT) p-> CH); I ++;} printf ("Total % d \ n", I ); printf ("Search for the 'C' Box \ n" through the hash string); hash = gethash ('C'); hlist_for_each (HP, & hlist [hash]) {struct st * P = hlist_entry (HP, struct St, I _hash); printf ("hlist: % C \ n", p-> CH );} printf ("Search for the 'C' box through the hash string and delete it \ n"); hlist_for_each_safe (HP, HN, & hlist [hash]) {struct st * P = hlist_entry (HP, struct St, I _hash); printf ("hlist_del: % C; % s \ n", p-> CH, p-> str_data); hlist_del (HP);} printf ("Search for 'C' boxes \ n"); hlist_for_each (HP, & hlist [hash]) {struct st * P = hlist_entry (HP, struct St, I _hash); printf ("hlist: % C \ n", p-> CH );} printf ("delete all node boxes \ n"); list_for_each_safe (list, node, & list1) {struct st * P = list_entry (list, struct St, I _list ); list_del (list); free (p);} // detects memory leaks _ crtdumpmemoryleaks (); Return 0 ;}

References:

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

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.