源码:
 #ifndef _LINUX_HLIST_H
 #define _LINUX_HLIST_H

 /*
  * Double linked lists with a single pointer list head.
  * Mostly useful for hash tables where the two pointer list head is
  * too wasteful.
  * You lose the ability to access the tail in O(1).
  */

 struct hlist_head {
     struct hlist_node *first;
 };

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

 #ifndef offsetof
 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 #endif

 #ifndef container_of
 /**
  * container_of - cast a member of a structure out to the containing structure
  * @ptr:    the pointer to the member.
  * @type:    the type of the container struct this is embedded in.
  * @member:    the name of the member within the struct.
  *
  */
 #define container_of(ptr, type, member) ({            \
     )->member) * __mptr = (ptr);    \
     (type *)((char *)__mptr - offsetof(type, member)); })
 #endif

 #define HLIST_HEAD_INIT { .first = NULL }
 #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
 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);
     INIT_HLIST_NODE(n);
 }

 static inline void hlist_del_init(struct hlist_node *n)
 {
     if (!hlist_unhashed(n)) {
         __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;
 }

 /* after that we'll appear to be on some hlist and hlist_del will work */
 static inline void hlist_add_fake(struct hlist_node *n)
 {
     n->pprev = &n->next;
 }

 /*
  * Move a list from one list head to another. Fixup the pprev
  * reference of the first entry if it exists.
  */
 static inline void hlist_move_list(struct hlist_head *old,
                    struct hlist_head *new)
 {
     new->first = old->first;
     if (new->first)
         new->first->pprev = &new->first;
     old->first = NULL;
 }

 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)

 #define hlist_for_each(pos, head) \
     for (pos = (head)->first; pos ; pos = pos->next)

 #define hlist_for_each_safe(pos, n, head) \
     ; }); \
          pos = n)

 /**
  * hlist_for_each_entry    - iterate over list of given type
  * @tpos:    the type * to use as a loop cursor.
  * @pos:    the &struct hlist_node to use as a loop cursor.
  * @head:    the head for your list.
  * @member:    the name of the hlist_node within the struct.
  */
 #define hlist_for_each_entry(tpos, pos, head, member)             \
     for (pos = (head)->first;                     \
          pos &&                             \
         ({ tpos = hlist_entry(pos, ;}); \
          pos = pos->next)

 /**
  * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
  * @tpos:    the type * to use as a loop cursor.
  * @pos:    the &struct hlist_node to use as a loop cursor.
  * @member:    the name of the hlist_node within the struct.
  */
 #define hlist_for_each_entry_continue(tpos, pos, member)         \
     for (pos = (pos)->next;                         \
          pos &&                             \
         ({ tpos = hlist_entry(pos, ;}); \
          pos = pos->next)

 /**
  * hlist_for_each_entry_from - iterate over a hlist continuing from current point
  * @tpos:    the type * to use as a loop cursor.
  * @pos:    the &struct hlist_node to use as a loop cursor.
  * @member:    the name of the hlist_node within the struct.
  */
 #define hlist_for_each_entry_from(tpos, pos, member)             \
     for (; pos &&                             \
         ({ tpos = hlist_entry(pos, ;}); \
          pos = pos->next)

 /**
  * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  * @tpos:    the type * to use as a loop cursor.
  * @pos:    the &struct hlist_node to use as a loop cursor.
  * @n:        another &struct hlist_node to use as temporary storage
  * @head:    the head for your list.
  * @member:    the name of the hlist_node within the struct.
  */
 #define hlist_for_each_entry_safe(tpos, pos, n, head, member)          \
     for (pos = (head)->first;                     \
          pos && ({ n = pos->next; ; }) &&                  \
         ({ tpos = hlist_entry(pos, ;}); \
          pos = n)

 #endif

DEMO
 #include <stdio.h>
 #include <stdlib.h>
 #include "hlist.h" // 包含头文件

 typedef struct HASH_DEMO_ST
 {
     int key;
     int value;
     struct hlist_node node; // 必须包含
 }HASH_DEMO_ST;

 #define HASH_HEAD_SIZE 10

 struct hlist_head hashHead[HASH_HEAD_SIZE];

 int hash_key(int key)
 {
     return key % HASH_HEAD_SIZE;
 }

 int main()
 {
     ;

     // 创建hash头,并初始化
     ; i < HASH_HEAD_SIZE; i++)
     {
         INIT_HLIST_HEAD(&(hashHead[i]));
     }

     // 添加节点
     ; i < ; i++)
     {
         HASH_DEMO_ST *new = (HASH_DEMO_ST *)malloc(sizeof(HASH_DEMO_ST));
         INIT_HLIST_NODE(&(new->node)); // 初始化节点
         new->key = i;
         new->value = i;

         hlist_add_head(&(new->node), &hashHead[hash_key(new->key)]);
     }

     HASH_DEMO_ST *tpos = NULL;
     struct hlist_node *pos = NULL;
     struct hlist_node *n = NULL;

     ; i < HASH_HEAD_SIZE; i++)
     {
         if (hlist_empty(&hashHead[i]))
         {
             continue;
         }

         hlist_for_each_entry_safe(tpos, pos, n, &hashHead[i], node)
         {
             printf("key:%d, value:%d\n", tpos->key, tpos->value);

             hlist_del(pos);
             free(tpos);
             tpos = NULL;
         }
     }

     ;
 }

linux内核hash list的更多相关文章

  1. linux内核netfilter连接跟踪的hash算法

    linux内核netfilter连接跟踪的hash算法 linux内核中的netfilter是一款强大的基于状态的防火墙,具有连接跟踪(conntrack)的实现.conntrack是netfilte ...

  2. 深度剖析linux内核万能--双向链表,Hash链表模版

    我们都知道,链表是数据结构中用得最广泛的一种数据结构,对于数据结构,有顺序存储,数组就是一种.有链式存储,链表算一种.当然还有索引式的,散列式的,各种风格的说法,叫法层出不穷,但是万变不离其中,只要知 ...

  3. 第4天--linux内核学习

    驱动使用方式1.编译到内核中 * make uImage进入到系统后mknod /dev/led c 500 0 创建设备节点 2.编译为模块 M make module进入到系统后 mknod /d ...

  4. 读《linux内核完全注释》的FAQ

    以下只是个人看了<linux内核完全注释>的一点理解,如果有错误,欢迎指正! 1 eip中保存的地址是逻辑地址.线性地址还是物理地址? 这个应该要分情况.eip保存的是下一条要执行的指令地 ...

  5. Linux 内核中的 Device Mapper 机制

    本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...

  6. 《Linux内核设计与实现》CHAPTER13阅读梳理

    <Linux内核设计与实现>第13章阅读总结 [edited by 5216lwr] 一.虚拟文件系统概述 1.虚拟文件系统 (也称作虚拟文件交换或VF)作为内核子系统,为用户空间程序提供 ...

  7. 《Linux及安全》期中总结&《Linux内核分析》期终总结

    [5216 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK NINE ...

  8. Linux内核--网络栈实现分析(二)--数据包的传递过程(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7492423 更多请看专栏,地址 ...

  9. Linux内核设计第三周——构造一个简单的Linux系统

    Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核 ...

随机推荐

  1. C# websocket Server 加密 76号协议

    服务器端源码: 76号协议增加了加密字段 sec-websocket-key1 sec-websocket-key2 以及最后8个字节 服务器必须在握手信息之后发送回解密信息才能握手成功. 解密方式 ...

  2. Is it possible to configure PostgreSQL to automatically close idle connections?

    1.use pgbouncer As new connections/transactions/statements arrive, the pool will increase in size up ...

  3. c# webBrowser控件与js的交互

    转自:http://blog.csdn.net/sd2131512/article/details/7467564 [System.Runtime.InteropServices.ComVisible ...

  4. 关于mybatis组合查询的分析

    mybatis 查询思路 第一种思路: 1:先查询,编写查询语句: 2:查询出结果后,将ResultMap 进行拆分, 组合成想要的模型: 这种思路是将联合查询语句组合成一个ResultMap; &l ...

  5. Web前端开发笔试&面试_03

    WL: 1.如何显示.隐藏一个dom对象? 2.如何将一个网页中的内容水平置中?写出重要的html标签和css. (css:#content{align:center;float:left;}html ...

  6. unity, Additive Animtion注意事项

    以下摘自官方文档:(http://docs.unity3d.com/Manual/AnimationScripting.html) Additive animations allow you to o ...

  7. Undefined symbols for architecture i386: "MyGetOpenALAudioData(__CFURL const*, int*, int*, int*)"

    今天把apple developer上的例子程序oalTouch中的MyOpenALSupport.h和MyOpenALSupport.c添加到自己的工程中,并在另一个文件xxx.cpp里调用,结果出 ...

  8. FileReader 基本介绍

    转自:http://blog.csdn.net/zk437092645/article/details/8745647 用来把文件读入内存,并且读取文件中的数据.FileReader接口提供了一个异步 ...

  9. rm命令

    rm是一个危险的命令,使用的时候要特别当心,尤其对于新手,否则整个系统就会毁在这个命令(比如在/(根目录)下执行rm * -rf).所以,我们在执行rm之前最好先确认一下在哪个目录,到底要删除什么东西 ...

  10. js 删除DropDownList的选项

    function del_DropDownList_Option() {            var   ddlXZ=  document.getElementById("name&quo ...