源码:
 #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. CSS和JS实现单行、多行文本溢出显示省略号(该js方法有问题不对)

    如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度width属来兼容部分浏览. 实现方法: overflow: hidden; te ...

  2. CSS设计模式之三权分立模式篇

    分类: Html/CSS | 转载请注明: 出自 海玉的博客 本文地址: http://www.hicss.net/separation-of-powers-model-in-css-design-p ...

  3. 023. Asp.net参数化查询预防Sql注入攻击

    /// <summary> /// 参数化查询预防SQL注入式攻击 /// </summary> public int checkLogin(string loginName, ...

  4. openpgp和gnupg

    http://www.openpgp.org/about_openpgp/history.shtml https://www.gnupg.org/ History OpenPGP is a non-p ...

  5. Dom之标签增删操作

    dom操作:THML新增子标签 a标签(appendChild) <!DOCTYPE html><html lang="en"><head> & ...

  6. 微信支付(0923更新)商户支付密钥key的生成与设置

    微信支付(0923更新)商户支付密钥key的生成与设置 说明:新版微信支付,用户必须授权登录才能支付.需要商家自己设置商户号支付密钥. 设置商户号支付密钥方法如下: 1. 申请通过审核后,打开微信发来 ...

  7. mysqldump: Got error: 1556: You can't use locks with log tables. when using LOCK TABLES

    mysqldump: Got error: 1556: You can't use locks with log tables. when using LOCK TABLES 我是把一些mysqldu ...

  8. exp命令ORACLCE10G导出ORACLE11G的数据1455错误

    异常:1455 解决: 命令:exp youruser/password@192.xxx.x.xx:1521/orcl owner=youruser file=c:\export.dmp trigge ...

  9. My second "last working day"

    时间真快,转眼硕士毕业已经快8年了. 今天是我的第二个last working day.也是我即将结束在外企工作的节点. 说来,毕业的时候,找工作,在确定了最后要去的单位之前,手头已经拿过了10家单位 ...

  10. .NET去掉HTML标记

    using System.Text.RegularExpressions; /// <summary> /// 去除HTML标记 /// </summary> /// < ...