linux hlist sample


test_hlist.c

--------------------------------------------------------------------------------------
#include <stdio.h>
#include <stddef.h>
#include <malloc.h>
#include <memory.h>

#include "hlist.h"

LIST_HEAD(proto_list);

struct proto {
    char name[32];
};

struct net_device {
    char name[16];
    struct hlist_node    name_hlist;
};

struct net {
    struct list_head    list;        /* list of network namespaces */
    struct hlist_head     *dev_name_head;
};

void show_netdev(struct proto* proto) 
{
    printf("name=%s\n", proto->name);
}

struct net init_inet;
int main(int argc, char* argv[])
{
    struct net *net = &init_inet;
    int i;
    struct hlist_head *head;
    struct hlist_node *p, *n;
    struct net_device *dev, *tdev;

    
    net->dev_name_head = malloc(sizeof(struct hlist_head )*256);
    memset(net->dev_name_head, 0, sizeof(struct hlist_head)* 256);

    head = &net->dev_name_head[0];

    for (i=0; i<10; i++) {
        dev = malloc(sizeof(struct net_device));

        memset(dev, 0, sizeof(struct net_device));
        sprintf(dev->name, "eth%d", i);

        hlist_add_head(&dev->name_hlist, head);
    }

    hlist_for_each_entry(dev, struct net_device,  p, head, name_hlist) {
        printf("name=%s\n", dev->name);
    }

    //删除
    hlist_for_each_entry_safe(dev, struct net_device, p, n, head, name_hlist) {
        hlist_del(p);
        free(dev);
    }

    printf("printf after deleteing.\n");
    hlist_for_each_entry(dev, struct net_device,  p, head, name_hlist)     {
        printf("name=%s\n", dev->name);
    }

    free(net->dev_name_head);
    return 0;
}

--------------------------------------------------------------------------------------------------------------------------

hlist.h

----------------------------------------------------------------------------------------------------------------------------------



#ifndef __HLIST_H__
#define __HLIST_H__

/* GCC 通过内置函数 __builtin_prefetch 支持数据的手工预抓取 */
#ifndef ARCH_HAS_PREFETCH
#ifndef _WIN32 
#define prefetch(x) __builtin_prefetch(x)
#else
#define prefetch(x) (x)
#endif
#endif

#ifdef _WIN32
#ifndef INLINE
#define INLINE __inline
#define inline __inline
#endif
#endif

#ifdef CONFIG_ILLEGAL_POINTER_VALUE
#define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)
#else
#define POISON_POINTER_DELTA 0
#endif

#ifndef LIST_POISON1
#define LIST_POISON1  ((void *) (0x00100100 + POISON_POINTER_DELTA))
#define LIST_POISON2  ((void *) (0x00200200 + POISON_POINTER_DELTA))
#endif


//list
struct list_head {
    struct list_head *next, *prev;
};

struct hlist_head {
    struct hlist_node *first;
};

struct hlist_node {
    struct hlist_node *next, **pprev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

#ifndef container_of
#define container_of(ptr, type, member) ((type *)( (char *)ptr - offsetof(type,member) ))
#endif

#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
#define hlist_for_each_entry(tpos, type, pos, head, member)             \
    for (pos = (head)->first;                     \
         pos && (prefetch(pos->next), 1) &&             \
        (tpos = hlist_entry(pos, type, member), 1); \
         pos = pos->next)

#define hlist_for_each_entry_safe(tpos, type, pos, n, head, member) \
    for (pos = (head)->first; \
         pos && (n = pos->next, 1) &&                  \
        (tpos = hlist_entry(pos, type, member), 1); \
         pos = n)

#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)

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;
}


                    static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
    h->next = NULL;
    h->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 = LIST_POISON1;
    n->pprev = LIST_POISON2;
}

static inline void hlist_del_init(struct hlist_node *n)
{
    if (!hlist_unhashed(n)) {
        __hlist_del(n);
        INIT_HLIST_NODE(n);
    }
}


#endif


posted @ 2013-05-07 17:08  mull  阅读(567)  评论(0编辑  收藏  举报