源码:
 #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. pgbouncer配置

    DESCRIPTION pgbouncer is a PostgreSQL connection pooler. Any target application can be connected to  ...

  2. Oracle数据库—— PL/SQL进阶编程

    一.涉及内容 1.掌握PL/SQL程序块的结构 2.理解并熟练掌握各种变量的应用. 二.具体操作 1.创建一个表messages,该表只有一个字段results 类型是number(2),编写一个块, ...

  3. bing统计【转自CSDN博客】

    文章来源:http://blog.csdn.net/aa512690069/article/details/17918799 其原文是微软一个小题目:http://hero.csdn.net/Ques ...

  4. 去掉linux 系统vi中出现^M字符的方法

    转http://www.cnblogs.com/xudong-bupt/p/3584625.html ^M符号是windows系统下的換行符,在windows下的文本通过bin模式ftp上传到了unx ...

  5. TKinter之文本域与多窗口

    用tkinter做出一个文本框出来,用于写字 代码很简单: #!/usr/bin/env python # _*_ coding:utf-8 _*_ from Tkinter import * roo ...

  6. mysql5.7.9 源码安装 (转)

    1,安装所有包 yum -y install gcc-c++ ncurses-devel cmake make perl gcc autoconf automake zlib libxml libgc ...

  7. Linux启动过程详解 (转)

    启动第一步--加载BIOS当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬盘 ...

  8. Java compiler level does not match the version of the installed Java project facet.问题

    从同事那里拷贝过来的web项目,导入到eclipse中,出现Java compiler level does not match the version of the installed Java p ...

  9. 转:java日志组件介绍(common-logging,log4j,slf4j,logback )

    原网址:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging common-logging是 ...

  10. SSL使用windows证书库中证书实现双向认证

    前一段时间对OpenSSL库中的SSL通讯稍微琢磨了一下,在百度文库中找了个示例程序,然后在机器上跑,哇塞,运行成功!那时那个惊喜啊,SSL蛮简单的嘛.前几天,老板要我整一个SSL通讯,要使用wind ...