├── .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 |
--------------------------------------------------------------------------------