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