├── .gitignore ├── README.md └── list_example ├── CMakeLists.txt ├── README.md ├── hash.h ├── hashtable.h ├── hashtable_example.c ├── list.h └── list_example.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | *.su 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # linux_study -------------------------------------------------------------------------------- /list_example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_BUILD_TYPE Debug) 4 | 5 | message( CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} ) 6 | message( CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) 7 | message( CMAKE_C_COMPILER=${CMAKE_C_COMPILER} ) 8 | 9 | ############################# 10 | 11 | # program 1: list_example 12 | add_executable( list_example list_example.c) 13 | 14 | # program 2: hashtable_example 15 | add_executable( hashtable_example hashtable_example.c) 16 | 17 | -------------------------------------------------------------------------------- /list_example/README.md: -------------------------------------------------------------------------------- 1 | List and Hashtable Usage Examples 2 | ================================== 3 | 4 | These are simple examples show the usage of list and hashtable in the Linux kernel. 5 | 6 | 7 | How to build 8 | ------------ 9 | 10 | The examples adopt CMake as the build system. You can get it with the link: 11 | 12 | ### Build steps: 13 | 14 | $ mkdir build 15 | $ cd build 16 | $ cmake ../ 17 | $ make 18 | 19 | -------------------------------------------------------------------------------- /list_example/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_HASH_H 2 | #define _LINUX_HASH_H 3 | /* Fast hashing routine for ints, longs and pointers. 4 | (C) 2002 Nadia Yvette Chambers, IBM */ 5 | 6 | /* 7 | * Knuth recommends primes in approximately golden ratio to the maximum 8 | * integer representable by a machine word for multiplicative hashing. 9 | * Chuck Lever verified the effectiveness of this technique: 10 | * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf 11 | * 12 | * These primes are chosen to be bit-sparse, that is operations on 13 | * them can use shifts and additions instead of multiplications for 14 | * machines where multiplications are slow. 15 | */ 16 | 17 | // #include 18 | // #include 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | 22 | typedef signed char s8; 23 | typedef unsigned char u8; 24 | 25 | typedef signed short s16; 26 | typedef unsigned short u16; 27 | 28 | typedef signed int s32; 29 | typedef unsigned int u32; 30 | 31 | typedef signed long long s64; 32 | typedef unsigned long long u64; 33 | 34 | typedef _Bool bool; 35 | 36 | enum { 37 | false = 0, 38 | true = 1 39 | }; 40 | 41 | 42 | #define BITS_PER_LONG 32 43 | 44 | // #include 45 | #ifndef __always_inline 46 | #define __always_inline inline 47 | #endif 48 | 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | 52 | /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ 53 | #define GOLDEN_RATIO_PRIME_32 0x9e370001UL 54 | /* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ 55 | #define GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001UL 56 | 57 | #if BITS_PER_LONG == 32 58 | #define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_32 59 | #define hash_long(val, bits) hash_32(val, bits) 60 | #elif BITS_PER_LONG == 64 61 | #define hash_long(val, bits) hash_64(val, bits) 62 | #define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_64 63 | #else 64 | #error Wordsize not 32 or 64 65 | #endif 66 | 67 | static __always_inline u64 hash_64(u64 val, unsigned int bits) 68 | { 69 | u64 hash = val; 70 | 71 | #if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 72 | hash = hash * GOLDEN_RATIO_PRIME_64; 73 | #else 74 | /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ 75 | u64 n = hash; 76 | n <<= 18; 77 | hash -= n; 78 | n <<= 33; 79 | hash -= n; 80 | n <<= 3; 81 | hash += n; 82 | n <<= 3; 83 | hash -= n; 84 | n <<= 4; 85 | hash += n; 86 | n <<= 2; 87 | hash += n; 88 | #endif 89 | 90 | /* High bits are more random, so use them. */ 91 | return hash >> (64 - bits); 92 | } 93 | 94 | static inline u32 hash_32(u32 val, unsigned int bits) 95 | { 96 | /* On some cpus multiply is faster, on others gcc will do shifts */ 97 | u32 hash = val * GOLDEN_RATIO_PRIME_32; 98 | 99 | /* High bits are more random, so use them. */ 100 | return hash >> (32 - bits); 101 | } 102 | 103 | static inline unsigned long hash_ptr(const void *ptr, unsigned int bits) 104 | { 105 | return hash_long((unsigned long)ptr, bits); 106 | } 107 | 108 | static inline u32 hash32_ptr(const void *ptr) 109 | { 110 | unsigned long val = (unsigned long)ptr; 111 | 112 | #if BITS_PER_LONG == 64 113 | val ^= (val >> 32); 114 | #endif 115 | return (u32)val; 116 | } 117 | 118 | #endif /* _LINUX_HASH_H */ 119 | -------------------------------------------------------------------------------- /list_example/hashtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Statically sized hash table implementation 3 | * (C) 2012 Sasha Levin 4 | */ 5 | 6 | #ifndef _LINUX_HASHTABLE_H 7 | #define _LINUX_HASHTABLE_H 8 | 9 | // #include 10 | // #include 11 | // #include 12 | // #include 13 | // #include 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | 17 | #include "list.h" 18 | #include "hash.h" 19 | 20 | 21 | #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 22 | 23 | /** 24 | * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value 25 | * @n - parameter 26 | * 27 | * constant-capable log of base 2 calculation 28 | * - this can be used to initialise global variables from constant data, hence 29 | * the massive ternary operator construction 30 | * 31 | * selects the appropriately-sized optimised version depending on sizeof(n) 32 | */ 33 | #define ilog2(n) \ 34 | ( \ 35 | (n) & (1ULL << 63) ? 63 : \ 36 | (n) & (1ULL << 62) ? 62 : \ 37 | (n) & (1ULL << 61) ? 61 : \ 38 | (n) & (1ULL << 60) ? 60 : \ 39 | (n) & (1ULL << 59) ? 59 : \ 40 | (n) & (1ULL << 58) ? 58 : \ 41 | (n) & (1ULL << 57) ? 57 : \ 42 | (n) & (1ULL << 56) ? 56 : \ 43 | (n) & (1ULL << 55) ? 55 : \ 44 | (n) & (1ULL << 54) ? 54 : \ 45 | (n) & (1ULL << 53) ? 53 : \ 46 | (n) & (1ULL << 52) ? 52 : \ 47 | (n) & (1ULL << 51) ? 51 : \ 48 | (n) & (1ULL << 50) ? 50 : \ 49 | (n) & (1ULL << 49) ? 49 : \ 50 | (n) & (1ULL << 48) ? 48 : \ 51 | (n) & (1ULL << 47) ? 47 : \ 52 | (n) & (1ULL << 46) ? 46 : \ 53 | (n) & (1ULL << 45) ? 45 : \ 54 | (n) & (1ULL << 44) ? 44 : \ 55 | (n) & (1ULL << 43) ? 43 : \ 56 | (n) & (1ULL << 42) ? 42 : \ 57 | (n) & (1ULL << 41) ? 41 : \ 58 | (n) & (1ULL << 40) ? 40 : \ 59 | (n) & (1ULL << 39) ? 39 : \ 60 | (n) & (1ULL << 38) ? 38 : \ 61 | (n) & (1ULL << 37) ? 37 : \ 62 | (n) & (1ULL << 36) ? 36 : \ 63 | (n) & (1ULL << 35) ? 35 : \ 64 | (n) & (1ULL << 34) ? 34 : \ 65 | (n) & (1ULL << 33) ? 33 : \ 66 | (n) & (1ULL << 32) ? 32 : \ 67 | (n) & (1ULL << 31) ? 31 : \ 68 | (n) & (1ULL << 30) ? 30 : \ 69 | (n) & (1ULL << 29) ? 29 : \ 70 | (n) & (1ULL << 28) ? 28 : \ 71 | (n) & (1ULL << 27) ? 27 : \ 72 | (n) & (1ULL << 26) ? 26 : \ 73 | (n) & (1ULL << 25) ? 25 : \ 74 | (n) & (1ULL << 24) ? 24 : \ 75 | (n) & (1ULL << 23) ? 23 : \ 76 | (n) & (1ULL << 22) ? 22 : \ 77 | (n) & (1ULL << 21) ? 21 : \ 78 | (n) & (1ULL << 20) ? 20 : \ 79 | (n) & (1ULL << 19) ? 19 : \ 80 | (n) & (1ULL << 18) ? 18 : \ 81 | (n) & (1ULL << 17) ? 17 : \ 82 | (n) & (1ULL << 16) ? 16 : \ 83 | (n) & (1ULL << 15) ? 15 : \ 84 | (n) & (1ULL << 14) ? 14 : \ 85 | (n) & (1ULL << 13) ? 13 : \ 86 | (n) & (1ULL << 12) ? 12 : \ 87 | (n) & (1ULL << 11) ? 11 : \ 88 | (n) & (1ULL << 10) ? 10 : \ 89 | (n) & (1ULL << 9) ? 9 : \ 90 | (n) & (1ULL << 8) ? 8 : \ 91 | (n) & (1ULL << 7) ? 7 : \ 92 | (n) & (1ULL << 6) ? 6 : \ 93 | (n) & (1ULL << 5) ? 5 : \ 94 | (n) & (1ULL << 4) ? 4 : \ 95 | (n) & (1ULL << 3) ? 3 : \ 96 | (n) & (1ULL << 2) ? 2 : \ 97 | (n) & (1ULL << 1) ? 1 : 0 \ 98 | ) 99 | 100 | // // ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value 101 | // int ilog2(unsigned long v) 102 | // { 103 | // int l = 0; 104 | // while ((1UL << l) < v) 105 | // l++; 106 | // return l; 107 | // } 108 | 109 | //////////////////////////////////////////////////////////////////////////////// 110 | 111 | #define DEFINE_HASHTABLE(name, bits) \ 112 | struct hlist_head name[1 << (bits)] = \ 113 | { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } 114 | 115 | #define DECLARE_HASHTABLE(name, bits) \ 116 | struct hlist_head name[1 << (bits)] 117 | 118 | #define HASH_SIZE(name) (ARRAY_SIZE(name)) 119 | #define HASH_BITS(name) ilog2(HASH_SIZE(name)) 120 | 121 | /* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ 122 | #define hash_min(val, bits) \ 123 | (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) 124 | 125 | static inline void __hash_init(struct hlist_head *ht, unsigned int sz) 126 | { 127 | unsigned int i; 128 | 129 | for (i = 0; i < sz; i++) 130 | INIT_HLIST_HEAD(&ht[i]); 131 | } 132 | 133 | /** 134 | * hash_init - initialize a hash table 135 | * @hashtable: hashtable to be initialized 136 | * 137 | * Calculates the size of the hashtable from the given parameter, otherwise 138 | * same as hash_init_size. 139 | * 140 | * This has to be a macro since HASH_BITS() will not work on pointers since 141 | * it calculates the size during preprocessing. 142 | */ 143 | #define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) 144 | 145 | /** 146 | * hash_add - add an object to a hashtable 147 | * @hashtable: hashtable to add to 148 | * @node: the &struct hlist_node of the object to be added 149 | * @key: the key of the object to be added 150 | */ 151 | #define hash_add(hashtable, node, key) \ 152 | hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) 153 | 154 | /** 155 | * hash_add_rcu - add an object to a rcu enabled hashtable 156 | * @hashtable: hashtable to add to 157 | * @node: the &struct hlist_node of the object to be added 158 | * @key: the key of the object to be added 159 | */ 160 | #define hash_add_rcu(hashtable, node, key) \ 161 | hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) 162 | 163 | /** 164 | * hash_hashed - check whether an object is in any hashtable 165 | * @node: the &struct hlist_node of the object to be checked 166 | */ 167 | static inline bool hash_hashed(struct hlist_node *node) 168 | { 169 | return !hlist_unhashed(node); 170 | } 171 | 172 | static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz) 173 | { 174 | unsigned int i; 175 | 176 | for (i = 0; i < sz; i++) 177 | if (!hlist_empty(&ht[i])) 178 | return false; 179 | 180 | return true; 181 | } 182 | 183 | /** 184 | * hash_empty - check whether a hashtable is empty 185 | * @hashtable: hashtable to check 186 | * 187 | * This has to be a macro since HASH_BITS() will not work on pointers since 188 | * it calculates the size during preprocessing. 189 | */ 190 | #define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) 191 | 192 | /** 193 | * hash_del - remove an object from a hashtable 194 | * @node: &struct hlist_node of the object to remove 195 | */ 196 | static inline void hash_del(struct hlist_node *node) 197 | { 198 | hlist_del_init(node); 199 | } 200 | 201 | /** 202 | * hash_del_rcu - remove an object from a rcu enabled hashtable 203 | * @node: &struct hlist_node of the object to remove 204 | */ 205 | // static inline void hash_del_rcu(struct hlist_node *node) 206 | // { 207 | // hlist_del_init_rcu(node); 208 | // } 209 | 210 | /** 211 | * hash_for_each - iterate over a hashtable 212 | * @name: hashtable to iterate 213 | * @bkt: integer to use as bucket loop cursor 214 | * @obj: the type * to use as a loop cursor for each entry 215 | * @member: the name of the hlist_node within the struct 216 | */ 217 | #define hash_for_each(name, bkt, obj, member) \ 218 | for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ 219 | (bkt)++)\ 220 | hlist_for_each_entry(obj, &name[bkt], member) 221 | 222 | /** 223 | * hash_for_each_rcu - iterate over a rcu enabled hashtable 224 | * @name: hashtable to iterate 225 | * @bkt: integer to use as bucket loop cursor 226 | * @obj: the type * to use as a loop cursor for each entry 227 | * @member: the name of the hlist_node within the struct 228 | */ 229 | // #define hash_for_each_rcu(name, bkt, obj, member) \ 230 | // for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ 231 | // (bkt)++)\ 232 | // hlist_for_each_entry_rcu(obj, &name[bkt], member) 233 | 234 | /** 235 | * hash_for_each_safe - iterate over a hashtable safe against removal of 236 | * hash entry 237 | * @name: hashtable to iterate 238 | * @bkt: integer to use as bucket loop cursor 239 | * @tmp: a &struct used for temporary storage 240 | * @obj: the type * to use as a loop cursor for each entry 241 | * @member: the name of the hlist_node within the struct 242 | */ 243 | #define hash_for_each_safe(name, bkt, tmp, obj, member) \ 244 | for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ 245 | (bkt)++)\ 246 | hlist_for_each_entry_safe(obj, tmp, &name[bkt], member) 247 | 248 | /** 249 | * hash_for_each_possible - iterate over all possible objects hashing to the 250 | * same bucket 251 | * @name: hashtable to iterate 252 | * @obj: the type * to use as a loop cursor for each entry 253 | * @member: the name of the hlist_node within the struct 254 | * @key: the key of the objects to iterate over 255 | */ 256 | #define hash_for_each_possible(name, obj, member, key) \ 257 | hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member) 258 | 259 | /** 260 | * hash_for_each_possible_rcu - iterate over all possible objects hashing to the 261 | * same bucket in an rcu enabled hashtable 262 | * in a rcu enabled hashtable 263 | * @name: hashtable to iterate 264 | * @obj: the type * to use as a loop cursor for each entry 265 | * @member: the name of the hlist_node within the struct 266 | * @key: the key of the objects to iterate over 267 | */ 268 | // #define hash_for_each_possible_rcu(name, obj, member, key) \ 269 | // hlist_for_each_entry_rcu(obj, &name[hash_min(key, HASH_BITS(name))],\ 270 | // member) 271 | 272 | /** 273 | * hash_for_each_possible_rcu_notrace - iterate over all possible objects hashing 274 | * to the same bucket in an rcu enabled hashtable in a rcu enabled hashtable 275 | * @name: hashtable to iterate 276 | * @obj: the type * to use as a loop cursor for each entry 277 | * @member: the name of the hlist_node within the struct 278 | * @key: the key of the objects to iterate over 279 | * 280 | * This is the same as hash_for_each_possible_rcu() except that it does 281 | * not do any RCU debugging or tracing. 282 | */ 283 | // #define hash_for_each_possible_rcu_notrace(name, obj, member, key) \ 284 | // hlist_for_each_entry_rcu_notrace(obj, \ 285 | // &name[hash_min(key, HASH_BITS(name))], member) 286 | 287 | /** 288 | * hash_for_each_possible_safe - iterate over all possible objects hashing to the 289 | * same bucket safe against removals 290 | * @name: hashtable to iterate 291 | * @obj: the type * to use as a loop cursor for each entry 292 | * @tmp: a &struct used for temporary storage 293 | * @member: the name of the hlist_node within the struct 294 | * @key: the key of the objects to iterate over 295 | */ 296 | #define hash_for_each_possible_safe(name, obj, tmp, member, key) \ 297 | hlist_for_each_entry_safe(obj, tmp,\ 298 | &name[hash_min(key, HASH_BITS(name))], member) 299 | 300 | 301 | #endif 302 | -------------------------------------------------------------------------------- /list_example/hashtable_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "list.h" 3 | #include "hash.h" 4 | #include "hashtable.h" 5 | 6 | struct object 7 | { 8 | int id; 9 | char name[16]; 10 | 11 | struct hlist_node node; 12 | }; 13 | 14 | //------------------------------------------------------------------------------ 15 | void print_hash_values() 16 | { 17 | u8 bits = 3; 18 | int num_buckets = (1< struct hlist_head htable[8] = { [0 ... 7] = HLIST_HEAD_INIT }; 30 | 31 | struct object obj1 = { 32 | .id = 1, 33 | .name = "obj1", 34 | }; 35 | hash_add(htable, &obj1.node, obj1.id); 36 | 37 | struct object obj2 = { 38 | .id = 2, 39 | .name = "obj2", 40 | }; 41 | hash_add(htable, &obj2.node, obj2.id); 42 | 43 | struct object obj3 = { 44 | .id = 3, 45 | .name = "obj3", 46 | }; 47 | hash_add(htable, &obj3.node, obj3.id); 48 | 49 | struct object obj9 = { 50 | .id = 9, 51 | .name = "obj9", 52 | }; 53 | hash_add(htable, &obj9.node, obj9.id); 54 | 55 | 56 | // find 57 | int key = 1; 58 | struct object* obj; 59 | hash_for_each_possible(htable, obj, node, key) { 60 | if(obj->id == key) { 61 | printf("key=%d => %s\n", key, obj->name); 62 | } 63 | } 64 | } 65 | 66 | void hash_del_example() 67 | { 68 | // define a hash table with 2^3(=8) buckets 69 | DEFINE_HASHTABLE(htable, 3); 70 | // => struct hlist_head htable[8] = { [0 ... 7] = HLIST_HEAD_INIT }; 71 | 72 | struct object obj1 = { 73 | .id = 1, 74 | .name = "obj1", 75 | }; 76 | hash_add(htable, &obj1.node, obj1.id); 77 | 78 | struct object obj2 = { 79 | .id = 2, 80 | .name = "obj2", 81 | }; 82 | hash_add(htable, &obj2.node, obj2.id); 83 | 84 | struct object obj3 = { 85 | .id = 3, 86 | .name = "obj3", 87 | }; 88 | hash_add(htable, &obj3.node, obj3.id); 89 | 90 | struct object obj9 = { 91 | .id = 9, 92 | .name = "obj9", 93 | }; 94 | hash_add(htable, &obj9.node, obj9.id); 95 | 96 | 97 | // find and del 98 | int key = 1; 99 | struct object* obj; 100 | hash_for_each_possible(htable, obj, node, key) { 101 | if(obj->id == key) { 102 | hash_del(&obj->node); 103 | } 104 | } 105 | 106 | 107 | int bkt; 108 | struct object* cur; 109 | hash_for_each(htable, bkt, cur, node) { 110 | printf("bucket[%d]=> %s\n", bkt, cur->name); 111 | } 112 | } 113 | 114 | 115 | void hashtable_show_buckets() 116 | { 117 | // define a hash table with 2^3(=8) buckets 118 | DEFINE_HASHTABLE(htable, 3); 119 | // => struct hlist_head htable[8] = { [0 ... 7] = HLIST_HEAD_INIT }; 120 | 121 | struct object obj1 = { 122 | .id = 1, 123 | .name = "obj1", 124 | }; 125 | hash_add(htable, &obj1.node, obj1.id); 126 | 127 | struct object obj2 = { 128 | .id = 2, 129 | .name = "obj2", 130 | }; 131 | hash_add(htable, &obj2.node, obj2.id); 132 | 133 | struct object obj3 = { 134 | .id = 3, 135 | .name = "obj3", 136 | }; 137 | hash_add(htable, &obj3.node, obj3.id); 138 | 139 | struct object obj9 = { 140 | .id = 9, 141 | .name = "obj9", 142 | }; 143 | hash_add(htable, &obj9.node, obj9.id); 144 | 145 | 146 | // int bkt; 147 | // struct object* cur; 148 | // hash_for_each(htable, bkt, cur, node) { 149 | // printf("bucket[%d]=> %s\n", bkt, cur->name); 150 | // } 151 | 152 | // show hashtable buckets 153 | int i=0; 154 | for (i = 0; i < HASH_SIZE(htable); ++i) 155 | { 156 | if (!hlist_empty(&htable[i])) 157 | { 158 | printf("bucket[%d]=> ", i); 159 | 160 | struct object* obj; 161 | hlist_for_each_entry(obj, &htable[i], node) { 162 | printf("%s, ", obj->name); 163 | } 164 | printf("\n"); 165 | } 166 | } 167 | } 168 | 169 | // Every bucket in the hashtable is a linked list which will hold all objects 170 | // that are hashed to the same bucket. 171 | void hash_add_same_key_example() 172 | { 173 | // define a hash table with 2^3(=8) buckets 174 | DEFINE_HASHTABLE(htable, 3); 175 | // => struct hlist_head htable[8] = { [0 ... 7] = HLIST_HEAD_INIT }; 176 | 177 | struct object obj1 = { 178 | .id = 0, 179 | .name = "obj1", 180 | }; 181 | hash_add(htable, &obj1.node, obj1.id); 182 | 183 | struct object obj2 = { 184 | .id = 0, 185 | .name = "obj2", 186 | }; 187 | hash_add(htable, &obj2.node, obj2.id); 188 | 189 | struct object obj3 = { 190 | .id = 0, 191 | .name = "obj3", 192 | }; 193 | hash_add(htable, &obj3.node, obj3.id); 194 | 195 | int bkt; 196 | struct object* cur; 197 | hash_for_each(htable, bkt, cur, node) { 198 | printf("bucket[%d]=> %s\n", bkt, cur->name); 199 | } 200 | } 201 | 202 | 203 | 204 | //------------------------------------------------------------------------------ 205 | 206 | int main() 207 | { 208 | hashtable_show_buckets(); 209 | return 0; 210 | } 211 | 212 | -------------------------------------------------------------------------------- /list_example/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_LIST_H 2 | #define _LINUX_LIST_H 3 | 4 | // #include 5 | // #include 6 | // #include 7 | // #include 8 | // #include 9 | 10 | //////////////////////////////////////////////////////////////////////////////// 11 | 12 | // #include 13 | struct list_head { 14 | struct list_head *next, *prev; 15 | }; 16 | 17 | struct hlist_head { 18 | struct hlist_node *first; 19 | }; 20 | 21 | struct hlist_node { 22 | struct hlist_node *next, **pprev; 23 | }; 24 | 25 | 26 | //------------------------------------------------------------------------------ 27 | // #include 28 | 29 | /* 30 | * Architectures might want to move the poison pointer offset 31 | * into some well-recognized area such as 0xdead000000000000, 32 | * that is also not mappable by user-space exploits: 33 | */ 34 | #ifdef CONFIG_ILLEGAL_POINTER_VALUE 35 | # define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL) 36 | #else 37 | # define POISON_POINTER_DELTA 0 38 | #endif 39 | 40 | /* 41 | * These are non-NULL pointers that will result in page faults 42 | * under normal circumstances, used to verify that nobody uses 43 | * non-initialized list entries. 44 | */ 45 | #define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) 46 | #define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) 47 | 48 | 49 | //------------------------------------------------------------------------------ 50 | // #include 51 | 52 | //# include/linux/stddef.h 53 | #undef offsetof 54 | #ifdef __compiler_offsetof 55 | #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) 56 | #else 57 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 58 | #endif 59 | 60 | 61 | /** 62 | * container_of - cast a member of a structure out to the containing structure 63 | * @ptr: the pointer to the member. 64 | * @type: the type of the container struct this is embedded in. 65 | * @member: the name of the member within the struct. 66 | * 67 | */ 68 | #define container_of(ptr, type, member) ({ \ 69 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 70 | (type *)( (char *)__mptr - offsetof(type,member) );}) 71 | 72 | 73 | //////////////////////////////////////////////////////////////////////////////// 74 | 75 | 76 | /* 77 | * Simple doubly linked list implementation. 78 | * 79 | * Some of the internal functions ("__xxx") are useful when 80 | * manipulating whole lists rather than single entries, as 81 | * sometimes we already know the next/prev entries and we can 82 | * generate better code by using them directly rather than 83 | * using the generic single-entry routines. 84 | */ 85 | 86 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 87 | 88 | #define LIST_HEAD(name) \ 89 | struct list_head name = LIST_HEAD_INIT(name) 90 | 91 | static inline void INIT_LIST_HEAD(struct list_head *list) 92 | { 93 | list->next = list; 94 | list->prev = list; 95 | } 96 | 97 | /* 98 | * Insert a new entry between two known consecutive entries. 99 | * 100 | * This is only for internal list manipulation where we know 101 | * the prev/next entries already! 102 | */ 103 | #ifndef CONFIG_DEBUG_LIST 104 | static inline void __list_add(struct list_head *new, 105 | struct list_head *prev, 106 | struct list_head *next) 107 | { 108 | next->prev = new; 109 | new->next = next; 110 | new->prev = prev; 111 | prev->next = new; 112 | } 113 | #else 114 | extern void __list_add(struct list_head *new, 115 | struct list_head *prev, 116 | struct list_head *next); 117 | #endif 118 | 119 | /** 120 | * list_add - add a new entry 121 | * @new: new entry to be added 122 | * @head: list head to add it after 123 | * 124 | * Insert a new entry after the specified head. 125 | * This is good for implementing stacks. 126 | */ 127 | static inline void list_add(struct list_head *new, struct list_head *head) 128 | { 129 | __list_add(new, head, head->next); 130 | } 131 | 132 | 133 | /** 134 | * list_add_tail - add a new entry 135 | * @new: new entry to be added 136 | * @head: list head to add it before 137 | * 138 | * Insert a new entry before the specified head. 139 | * This is useful for implementing queues. 140 | */ 141 | static inline void list_add_tail(struct list_head *new, struct list_head *head) 142 | { 143 | __list_add(new, head->prev, head); 144 | } 145 | 146 | /* 147 | * Delete a list entry by making the prev/next entries 148 | * point to each other. 149 | * 150 | * This is only for internal list manipulation where we know 151 | * the prev/next entries already! 152 | */ 153 | static inline void __list_del(struct list_head * prev, struct list_head * next) 154 | { 155 | next->prev = prev; 156 | prev->next = next; 157 | } 158 | 159 | /** 160 | * list_del - deletes entry from list. 161 | * @entry: the element to delete from the list. 162 | * Note: list_empty() on entry does not return true after this, the entry is 163 | * in an undefined state. 164 | */ 165 | #ifndef CONFIG_DEBUG_LIST 166 | static inline void __list_del_entry(struct list_head *entry) 167 | { 168 | __list_del(entry->prev, entry->next); 169 | } 170 | 171 | static inline void list_del(struct list_head *entry) 172 | { 173 | __list_del(entry->prev, entry->next); 174 | entry->next = LIST_POISON1; 175 | entry->prev = LIST_POISON2; 176 | } 177 | #else 178 | extern void __list_del_entry(struct list_head *entry); 179 | extern void list_del(struct list_head *entry); 180 | #endif 181 | 182 | /** 183 | * list_replace - replace old entry by new one 184 | * @old : the element to be replaced 185 | * @new : the new element to insert 186 | * 187 | * If @old was empty, it will be overwritten. 188 | */ 189 | static inline void list_replace(struct list_head *old, 190 | struct list_head *new) 191 | { 192 | new->next = old->next; 193 | new->next->prev = new; 194 | new->prev = old->prev; 195 | new->prev->next = new; 196 | } 197 | 198 | static inline void list_replace_init(struct list_head *old, 199 | struct list_head *new) 200 | { 201 | list_replace(old, new); 202 | INIT_LIST_HEAD(old); 203 | } 204 | 205 | /** 206 | * list_del_init - deletes entry from list and reinitialize it. 207 | * @entry: the element to delete from the list. 208 | */ 209 | static inline void list_del_init(struct list_head *entry) 210 | { 211 | __list_del_entry(entry); 212 | INIT_LIST_HEAD(entry); 213 | } 214 | 215 | /** 216 | * list_move - delete from one list and add as another's head 217 | * @list: the entry to move 218 | * @head: the head that will precede our entry 219 | */ 220 | static inline void list_move(struct list_head *list, struct list_head *head) 221 | { 222 | __list_del_entry(list); 223 | list_add(list, head); 224 | } 225 | 226 | /** 227 | * list_move_tail - delete from one list and add as another's tail 228 | * @list: the entry to move 229 | * @head: the head that will follow our entry 230 | */ 231 | static inline void list_move_tail(struct list_head *list, 232 | struct list_head *head) 233 | { 234 | __list_del_entry(list); 235 | list_add_tail(list, head); 236 | } 237 | 238 | /** 239 | * list_is_last - tests whether @list is the last entry in list @head 240 | * @list: the entry to test 241 | * @head: the head of the list 242 | */ 243 | static inline int list_is_last(const struct list_head *list, 244 | const struct list_head *head) 245 | { 246 | return list->next == head; 247 | } 248 | 249 | /** 250 | * list_empty - tests whether a list is empty 251 | * @head: the list to test. 252 | */ 253 | static inline int list_empty(const struct list_head *head) 254 | { 255 | return head->next == head; 256 | } 257 | 258 | /** 259 | * list_empty_careful - tests whether a list is empty and not being modified 260 | * @head: the list to test 261 | * 262 | * Description: 263 | * tests whether a list is empty _and_ checks that no other CPU might be 264 | * in the process of modifying either member (next or prev) 265 | * 266 | * NOTE: using list_empty_careful() without synchronization 267 | * can only be safe if the only activity that can happen 268 | * to the list entry is list_del_init(). Eg. it cannot be used 269 | * if another CPU could re-list_add() it. 270 | */ 271 | static inline int list_empty_careful(const struct list_head *head) 272 | { 273 | struct list_head *next = head->next; 274 | return (next == head) && (next == head->prev); 275 | } 276 | 277 | /** 278 | * list_rotate_left - rotate the list to the left 279 | * @head: the head of the list 280 | */ 281 | static inline void list_rotate_left(struct list_head *head) 282 | { 283 | struct list_head *first; 284 | 285 | if (!list_empty(head)) { 286 | first = head->next; 287 | list_move_tail(first, head); 288 | } 289 | } 290 | 291 | /** 292 | * list_is_singular - tests whether a list has just one entry. 293 | * @head: the list to test. 294 | */ 295 | static inline int list_is_singular(const struct list_head *head) 296 | { 297 | return !list_empty(head) && (head->next == head->prev); 298 | } 299 | 300 | static inline void __list_cut_position(struct list_head *list, 301 | struct list_head *head, struct list_head *entry) 302 | { 303 | struct list_head *new_first = entry->next; 304 | list->next = head->next; 305 | list->next->prev = list; 306 | list->prev = entry; 307 | entry->next = list; 308 | head->next = new_first; 309 | new_first->prev = head; 310 | } 311 | 312 | /** 313 | * list_cut_position - cut a list into two 314 | * @list: a new list to add all removed entries 315 | * @head: a list with entries 316 | * @entry: an entry within head, could be the head itself 317 | * and if so we won't cut the list 318 | * 319 | * This helper moves the initial part of @head, up to and 320 | * including @entry, from @head to @list. You should 321 | * pass on @entry an element you know is on @head. @list 322 | * should be an empty list or a list you do not care about 323 | * losing its data. 324 | * 325 | */ 326 | static inline void list_cut_position(struct list_head *list, 327 | struct list_head *head, struct list_head *entry) 328 | { 329 | if (list_empty(head)) 330 | return; 331 | if (list_is_singular(head) && 332 | (head->next != entry && head != entry)) 333 | return; 334 | if (entry == head) 335 | INIT_LIST_HEAD(list); 336 | else 337 | __list_cut_position(list, head, entry); 338 | } 339 | 340 | static inline void __list_splice(const struct list_head *list, 341 | struct list_head *prev, 342 | struct list_head *next) 343 | { 344 | struct list_head *first = list->next; 345 | struct list_head *last = list->prev; 346 | 347 | first->prev = prev; 348 | prev->next = first; 349 | 350 | last->next = next; 351 | next->prev = last; 352 | } 353 | 354 | /** 355 | * list_splice - join two lists, this is designed for stacks 356 | * @list: the new list to add. 357 | * @head: the place to add it in the first list. 358 | */ 359 | static inline void list_splice(const struct list_head *list, 360 | struct list_head *head) 361 | { 362 | if (!list_empty(list)) 363 | __list_splice(list, head, head->next); 364 | } 365 | 366 | /** 367 | * list_splice_tail - join two lists, each list being a queue 368 | * @list: the new list to add. 369 | * @head: the place to add it in the first list. 370 | */ 371 | static inline void list_splice_tail(struct list_head *list, 372 | struct list_head *head) 373 | { 374 | if (!list_empty(list)) 375 | __list_splice(list, head->prev, head); 376 | } 377 | 378 | /** 379 | * list_splice_init - join two lists and reinitialise the emptied list. 380 | * @list: the new list to add. 381 | * @head: the place to add it in the first list. 382 | * 383 | * The list at @list is reinitialised 384 | */ 385 | static inline void list_splice_init(struct list_head *list, 386 | struct list_head *head) 387 | { 388 | if (!list_empty(list)) { 389 | __list_splice(list, head, head->next); 390 | INIT_LIST_HEAD(list); 391 | } 392 | } 393 | 394 | /** 395 | * list_splice_tail_init - join two lists and reinitialise the emptied list 396 | * @list: the new list to add. 397 | * @head: the place to add it in the first list. 398 | * 399 | * Each of the lists is a queue. 400 | * The list at @list is reinitialised 401 | */ 402 | static inline void list_splice_tail_init(struct list_head *list, 403 | struct list_head *head) 404 | { 405 | if (!list_empty(list)) { 406 | __list_splice(list, head->prev, head); 407 | INIT_LIST_HEAD(list); 408 | } 409 | } 410 | 411 | /** 412 | * list_entry - get the struct for this entry 413 | * @ptr: the &struct list_head pointer. 414 | * @type: the type of the struct this is embedded in. 415 | * @member: the name of the list_head within the struct. 416 | */ 417 | #define list_entry(ptr, type, member) \ 418 | container_of(ptr, type, member) 419 | 420 | /** 421 | * list_first_entry - get the first element from a list 422 | * @ptr: the list head to take the element from. 423 | * @type: the type of the struct this is embedded in. 424 | * @member: the name of the list_head within the struct. 425 | * 426 | * Note, that list is expected to be not empty. 427 | */ 428 | #define list_first_entry(ptr, type, member) \ 429 | list_entry((ptr)->next, type, member) 430 | 431 | /** 432 | * list_last_entry - get the last element from a list 433 | * @ptr: the list head to take the element from. 434 | * @type: the type of the struct this is embedded in. 435 | * @member: the name of the list_head within the struct. 436 | * 437 | * Note, that list is expected to be not empty. 438 | */ 439 | #define list_last_entry(ptr, type, member) \ 440 | list_entry((ptr)->prev, type, member) 441 | 442 | /** 443 | * list_first_entry_or_null - get the first element from a list 444 | * @ptr: the list head to take the element from. 445 | * @type: the type of the struct this is embedded in. 446 | * @member: the name of the list_head within the struct. 447 | * 448 | * Note that if the list is empty, it returns NULL. 449 | */ 450 | #define list_first_entry_or_null(ptr, type, member) \ 451 | (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) 452 | 453 | /** 454 | * list_next_entry - get the next element in list 455 | * @pos: the type * to cursor 456 | * @member: the name of the list_head within the struct. 457 | */ 458 | #define list_next_entry(pos, member) \ 459 | list_entry((pos)->member.next, typeof(*(pos)), member) 460 | 461 | /** 462 | * list_prev_entry - get the prev element in list 463 | * @pos: the type * to cursor 464 | * @member: the name of the list_head within the struct. 465 | */ 466 | #define list_prev_entry(pos, member) \ 467 | list_entry((pos)->member.prev, typeof(*(pos)), member) 468 | 469 | /** 470 | * list_for_each - iterate over a list 471 | * @pos: the &struct list_head to use as a loop cursor. 472 | * @head: the head for your list. 473 | */ 474 | #define list_for_each(pos, head) \ 475 | for (pos = (head)->next; pos != (head); pos = pos->next) 476 | 477 | /** 478 | * list_for_each_prev - iterate over a list backwards 479 | * @pos: the &struct list_head to use as a loop cursor. 480 | * @head: the head for your list. 481 | */ 482 | #define list_for_each_prev(pos, head) \ 483 | for (pos = (head)->prev; pos != (head); pos = pos->prev) 484 | 485 | /** 486 | * list_for_each_safe - iterate over a list safe against removal of list entry 487 | * @pos: the &struct list_head to use as a loop cursor. 488 | * @n: another &struct list_head to use as temporary storage 489 | * @head: the head for your list. 490 | */ 491 | #define list_for_each_safe(pos, n, head) \ 492 | for (pos = (head)->next, n = pos->next; pos != (head); \ 493 | pos = n, n = pos->next) 494 | 495 | /** 496 | * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry 497 | * @pos: the &struct list_head to use as a loop cursor. 498 | * @n: another &struct list_head to use as temporary storage 499 | * @head: the head for your list. 500 | */ 501 | #define list_for_each_prev_safe(pos, n, head) \ 502 | for (pos = (head)->prev, n = pos->prev; \ 503 | pos != (head); \ 504 | pos = n, n = pos->prev) 505 | 506 | /** 507 | * list_for_each_entry - iterate over list of given type 508 | * @pos: the type * to use as a loop cursor. 509 | * @head: the head for your list. 510 | * @member: the name of the list_head within the struct. 511 | */ 512 | #define list_for_each_entry(pos, head, member) \ 513 | for (pos = list_first_entry(head, typeof(*pos), member); \ 514 | &pos->member != (head); \ 515 | pos = list_next_entry(pos, member)) 516 | 517 | /** 518 | * list_for_each_entry_reverse - iterate backwards over list of given type. 519 | * @pos: the type * to use as a loop cursor. 520 | * @head: the head for your list. 521 | * @member: the name of the list_head within the struct. 522 | */ 523 | #define list_for_each_entry_reverse(pos, head, member) \ 524 | for (pos = list_last_entry(head, typeof(*pos), member); \ 525 | &pos->member != (head); \ 526 | pos = list_prev_entry(pos, member)) 527 | 528 | /** 529 | * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() 530 | * @pos: the type * to use as a start point 531 | * @head: the head of the list 532 | * @member: the name of the list_head within the struct. 533 | * 534 | * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). 535 | */ 536 | #define list_prepare_entry(pos, head, member) \ 537 | ((pos) ? : list_entry(head, typeof(*pos), member)) 538 | 539 | /** 540 | * list_for_each_entry_continue - continue iteration over list of given type 541 | * @pos: the type * to use as a loop cursor. 542 | * @head: the head for your list. 543 | * @member: the name of the list_head within the struct. 544 | * 545 | * Continue to iterate over list of given type, continuing after 546 | * the current position. 547 | */ 548 | #define list_for_each_entry_continue(pos, head, member) \ 549 | for (pos = list_next_entry(pos, member); \ 550 | &pos->member != (head); \ 551 | pos = list_next_entry(pos, member)) 552 | 553 | /** 554 | * list_for_each_entry_continue_reverse - iterate backwards from the given point 555 | * @pos: the type * to use as a loop cursor. 556 | * @head: the head for your list. 557 | * @member: the name of the list_head within the struct. 558 | * 559 | * Start to iterate over list of given type backwards, continuing after 560 | * the current position. 561 | */ 562 | #define list_for_each_entry_continue_reverse(pos, head, member) \ 563 | for (pos = list_prev_entry(pos, member); \ 564 | &pos->member != (head); \ 565 | pos = list_prev_entry(pos, member)) 566 | 567 | /** 568 | * list_for_each_entry_from - iterate over list of given type from the current point 569 | * @pos: the type * to use as a loop cursor. 570 | * @head: the head for your list. 571 | * @member: the name of the list_head within the struct. 572 | * 573 | * Iterate over list of given type, continuing from current position. 574 | */ 575 | #define list_for_each_entry_from(pos, head, member) \ 576 | for (; &pos->member != (head); \ 577 | pos = list_next_entry(pos, member)) 578 | 579 | /** 580 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 581 | * @pos: the type * to use as a loop cursor. 582 | * @n: another type * to use as temporary storage 583 | * @head: the head for your list. 584 | * @member: the name of the list_head within the struct. 585 | */ 586 | #define list_for_each_entry_safe(pos, n, head, member) \ 587 | for (pos = list_first_entry(head, typeof(*pos), member), \ 588 | n = list_next_entry(pos, member); \ 589 | &pos->member != (head); \ 590 | pos = n, n = list_next_entry(n, member)) 591 | 592 | /** 593 | * list_for_each_entry_safe_continue - continue list iteration safe against removal 594 | * @pos: the type * to use as a loop cursor. 595 | * @n: another type * to use as temporary storage 596 | * @head: the head for your list. 597 | * @member: the name of the list_head within the struct. 598 | * 599 | * Iterate over list of given type, continuing after current point, 600 | * safe against removal of list entry. 601 | */ 602 | #define list_for_each_entry_safe_continue(pos, n, head, member) \ 603 | for (pos = list_next_entry(pos, member), \ 604 | n = list_next_entry(pos, member); \ 605 | &pos->member != (head); \ 606 | pos = n, n = list_next_entry(n, member)) 607 | 608 | /** 609 | * list_for_each_entry_safe_from - iterate over list from current point safe against removal 610 | * @pos: the type * to use as a loop cursor. 611 | * @n: another type * to use as temporary storage 612 | * @head: the head for your list. 613 | * @member: the name of the list_head within the struct. 614 | * 615 | * Iterate over list of given type from current point, safe against 616 | * removal of list entry. 617 | */ 618 | #define list_for_each_entry_safe_from(pos, n, head, member) \ 619 | for (n = list_next_entry(pos, member); \ 620 | &pos->member != (head); \ 621 | pos = n, n = list_next_entry(n, member)) 622 | 623 | /** 624 | * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal 625 | * @pos: the type * to use as a loop cursor. 626 | * @n: another type * to use as temporary storage 627 | * @head: the head for your list. 628 | * @member: the name of the list_head within the struct. 629 | * 630 | * Iterate backwards over list of given type, safe against removal 631 | * of list entry. 632 | */ 633 | #define list_for_each_entry_safe_reverse(pos, n, head, member) \ 634 | for (pos = list_last_entry(head, typeof(*pos), member), \ 635 | n = list_prev_entry(pos, member); \ 636 | &pos->member != (head); \ 637 | pos = n, n = list_prev_entry(n, member)) 638 | 639 | /** 640 | * list_safe_reset_next - reset a stale list_for_each_entry_safe loop 641 | * @pos: the loop cursor used in the list_for_each_entry_safe loop 642 | * @n: temporary storage used in list_for_each_entry_safe 643 | * @member: the name of the list_head within the struct. 644 | * 645 | * list_safe_reset_next is not safe to use in general if the list may be 646 | * modified concurrently (eg. the lock is dropped in the loop body). An 647 | * exception to this is if the cursor element (pos) is pinned in the list, 648 | * and list_safe_reset_next is called after re-taking the lock and before 649 | * completing the current iteration of the loop body. 650 | */ 651 | #define list_safe_reset_next(pos, n, member) \ 652 | n = list_next_entry(pos, member) 653 | 654 | /* 655 | * Double linked lists with a single pointer list head. 656 | * Mostly useful for hash tables where the two pointer list head is 657 | * too wasteful. 658 | * You lose the ability to access the tail in O(1). 659 | */ 660 | 661 | #define HLIST_HEAD_INIT { .first = NULL } 662 | #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } 663 | #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 664 | static inline void INIT_HLIST_NODE(struct hlist_node *h) 665 | { 666 | h->next = NULL; 667 | h->pprev = NULL; 668 | } 669 | 670 | static inline int hlist_unhashed(const struct hlist_node *h) 671 | { 672 | return !h->pprev; 673 | } 674 | 675 | static inline int hlist_empty(const struct hlist_head *h) 676 | { 677 | return !h->first; 678 | } 679 | 680 | static inline void __hlist_del(struct hlist_node *n) 681 | { 682 | struct hlist_node *next = n->next; 683 | struct hlist_node **pprev = n->pprev; 684 | *pprev = next; 685 | if (next) 686 | next->pprev = pprev; 687 | } 688 | 689 | static inline void hlist_del(struct hlist_node *n) 690 | { 691 | __hlist_del(n); 692 | n->next = LIST_POISON1; 693 | n->pprev = LIST_POISON2; 694 | } 695 | 696 | static inline void hlist_del_init(struct hlist_node *n) 697 | { 698 | if (!hlist_unhashed(n)) { 699 | __hlist_del(n); 700 | INIT_HLIST_NODE(n); 701 | } 702 | } 703 | 704 | static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 705 | { 706 | struct hlist_node *first = h->first; 707 | n->next = first; 708 | if (first) 709 | first->pprev = &n->next; 710 | h->first = n; 711 | n->pprev = &h->first; 712 | } 713 | 714 | /* next must be != NULL */ 715 | static inline void hlist_add_before(struct hlist_node *n, 716 | struct hlist_node *next) 717 | { 718 | n->pprev = next->pprev; 719 | n->next = next; 720 | next->pprev = &n->next; 721 | *(n->pprev) = n; 722 | } 723 | 724 | static inline void hlist_add_behind(struct hlist_node *n, 725 | struct hlist_node *prev) 726 | { 727 | n->next = prev->next; 728 | prev->next = n; 729 | n->pprev = &prev->next; 730 | 731 | if (n->next) 732 | n->next->pprev = &n->next; 733 | } 734 | 735 | /* after that we'll appear to be on some hlist and hlist_del will work */ 736 | static inline void hlist_add_fake(struct hlist_node *n) 737 | { 738 | n->pprev = &n->next; 739 | } 740 | 741 | /* 742 | * Move a list from one list head to another. Fixup the pprev 743 | * reference of the first entry if it exists. 744 | */ 745 | static inline void hlist_move_list(struct hlist_head *old, 746 | struct hlist_head *new) 747 | { 748 | new->first = old->first; 749 | if (new->first) 750 | new->first->pprev = &new->first; 751 | old->first = NULL; 752 | } 753 | 754 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) 755 | 756 | #define hlist_for_each(pos, head) \ 757 | for (pos = (head)->first; pos ; pos = pos->next) 758 | 759 | #define hlist_for_each_safe(pos, n, head) \ 760 | for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ 761 | pos = n) 762 | 763 | #define hlist_entry_safe(ptr, type, member) \ 764 | ({ typeof(ptr) ____ptr = (ptr); \ 765 | ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ 766 | }) 767 | 768 | /** 769 | * hlist_for_each_entry - iterate over list of given type 770 | * @pos: the type * to use as a loop cursor. 771 | * @head: the head for your list. 772 | * @member: the name of the hlist_node within the struct. 773 | */ 774 | #define hlist_for_each_entry(pos, head, member) \ 775 | for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ 776 | pos; \ 777 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 778 | 779 | /** 780 | * hlist_for_each_entry_continue - iterate over a hlist continuing after current point 781 | * @pos: the type * to use as a loop cursor. 782 | * @member: the name of the hlist_node within the struct. 783 | */ 784 | #define hlist_for_each_entry_continue(pos, member) \ 785 | for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ 786 | pos; \ 787 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 788 | 789 | /** 790 | * hlist_for_each_entry_from - iterate over a hlist continuing from current point 791 | * @pos: the type * to use as a loop cursor. 792 | * @member: the name of the hlist_node within the struct. 793 | */ 794 | #define hlist_for_each_entry_from(pos, member) \ 795 | for (; pos; \ 796 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 797 | 798 | /** 799 | * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry 800 | * @pos: the type * to use as a loop cursor. 801 | * @n: another &struct hlist_node to use as temporary storage 802 | * @head: the head for your list. 803 | * @member: the name of the hlist_node within the struct. 804 | */ 805 | #define hlist_for_each_entry_safe(pos, n, head, member) \ 806 | for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ 807 | pos && ({ n = pos->member.next; 1; }); \ 808 | pos = hlist_entry_safe(n, typeof(*pos), member)) 809 | 810 | #endif 811 | -------------------------------------------------------------------------------- /list_example/list_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "list.h" 3 | 4 | 5 | struct object 6 | { 7 | int id; 8 | char name[16]; 9 | 10 | struct list_head node; 11 | }; 12 | 13 | 14 | //------------------------------------------------------------------------------ 15 | void list_add_example() 16 | { 17 | LIST_HEAD(obj_list); 18 | 19 | 20 | struct object obj1 = { 21 | .id = 1, 22 | .name = "obj1", 23 | }; 24 | list_add(&obj1.node, &obj_list); 25 | 26 | struct object obj2 = { 27 | .id = 2, 28 | .name = "obj2", 29 | }; 30 | list_add(&obj2.node, &obj_list); 31 | 32 | struct object obj3 = { 33 | .id = 3, 34 | .name = "obj3", 35 | }; 36 | list_add(&obj3.node, &obj_list); 37 | 38 | 39 | struct list_head* iter; 40 | list_for_each(iter, &obj_list) { 41 | struct object* obj = list_entry(iter, struct object, node); 42 | printf("%s\n", obj->name); 43 | } 44 | } 45 | 46 | void list_add_tail_example() 47 | { 48 | LIST_HEAD(obj_list); 49 | 50 | 51 | struct object obj1 = { 52 | .id = 1, 53 | .name = "obj1", 54 | }; 55 | list_add_tail(&obj1.node, &obj_list); 56 | 57 | struct object obj2 = { 58 | .id = 2, 59 | .name = "obj2", 60 | }; 61 | list_add_tail(&obj2.node, &obj_list); 62 | 63 | struct object obj3 = { 64 | .id = 3, 65 | .name = "obj3", 66 | }; 67 | list_add_tail(&obj3.node, &obj_list); 68 | 69 | 70 | struct list_head* iter; 71 | list_for_each(iter, &obj_list) { 72 | struct object* obj = list_entry(iter, struct object, node); 73 | printf("%s\n", obj->name); 74 | } 75 | } 76 | 77 | void list_del_example() 78 | { 79 | LIST_HEAD(obj_list); 80 | 81 | 82 | struct object obj1 = { 83 | .id = 1, 84 | .name = "obj1", 85 | }; 86 | list_add_tail(&obj1.node, &obj_list); 87 | 88 | struct object obj2 = { 89 | .id = 2, 90 | .name = "obj2", 91 | }; 92 | list_add_tail(&obj2.node, &obj_list); 93 | 94 | struct object obj3 = { 95 | .id = 3, 96 | .name = "obj3", 97 | }; 98 | list_add_tail(&obj3.node, &obj_list); 99 | 100 | 101 | //--------------------------// 102 | 103 | // list_del - deletes entry from list. 104 | list_del(&obj2.node); 105 | 106 | //--------------------------// 107 | 108 | 109 | struct list_head* iter; 110 | list_for_each(iter, &obj_list) { 111 | struct object* obj = list_entry(iter, struct object, node); 112 | printf("%s\n", obj->name); 113 | } 114 | } 115 | 116 | //------------------------------------------------------------------------------ 117 | 118 | int main() 119 | { 120 | list_add_example(); 121 | return 0; 122 | } 123 | 124 | --------------------------------------------------------------------------------