Commit | Line | Data |
---|---|---|
f934e302 MD |
1 | #ifndef _LTTNG_WRAPPER_LIST_H |
2 | #define _LTTNG_WRAPPER_LIST_H | |
3 | ||
4 | /* | |
5 | * wrapper/list.h | |
6 | * | |
7 | * wrapper around linux/list.h. | |
8 | * | |
9 | * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
10 | * | |
11 | * This program is free software; you can redistribute it and/or modify | |
12 | * it under the terms of the GNU General Public License as published by | |
13 | * the Free Software Foundation; only version 2 of the License. | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU General Public License along | |
21 | * with this program; if not, write to the Free Software Foundation, Inc., | |
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
23 | * | |
24 | * This wrapper code is derived from Linux 3.19.2 include/linux/list.h | |
25 | * and include/linux/rculist.h, hence the GPLv2 license applied to this | |
26 | * file. | |
27 | */ | |
28 | ||
29 | #include <linux/list.h> | |
30 | #include <linux/rculist.h> | |
31 | ||
32 | #define lttng_hlist_entry_safe(ptr, type, member) \ | |
33 | ({ typeof(ptr) ____ptr = (ptr); \ | |
34 | ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ | |
35 | }) | |
36 | ||
37 | /** | |
38 | * lttng_hlist_for_each_entry - iterate over list of given type | |
39 | * @pos: the type * to use as a loop cursor. | |
40 | * @head: the head for your list. | |
41 | * @member: the name of the hlist_node within the struct. | |
42 | */ | |
43 | #define lttng_hlist_for_each_entry(pos, head, member) \ | |
44 | for (pos = lttng_hlist_entry_safe((head)->first, typeof(*(pos)), member);\ | |
45 | pos; \ | |
46 | pos = lttng_hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) | |
47 | ||
48 | /** | |
49 | * lttng_hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry | |
50 | * @pos: the type * to use as a loop cursor. | |
51 | * @n: another &struct hlist_node to use as temporary storage | |
52 | * @head: the head for your list. | |
53 | * @member: the name of the hlist_node within the struct. | |
54 | */ | |
55 | #define lttng_hlist_for_each_entry_safe(pos, n, head, member) \ | |
56 | for (pos = lttng_hlist_entry_safe((head)->first, typeof(*pos), member);\ | |
57 | pos && ({ n = pos->member.next; 1; }); \ | |
58 | pos = lttng_hlist_entry_safe(n, typeof(*pos), member)) | |
59 | ||
60 | #ifndef rcu_dereference_raw_notrace | |
61 | #define rcu_dereference_raw_notrace(p) rcu_dereference_raw(p) | |
62 | #endif | |
63 | ||
64 | /** | |
65 | * lttng_hlist_for_each_entry_rcu_notrace - iterate over rcu list of given type (for tracing) | |
66 | * @pos: the type * to use as a loop cursor. | |
67 | * @head: the head for your list. | |
68 | * @member: the name of the hlist_node within the struct. | |
69 | * | |
70 | * This list-traversal primitive may safely run concurrently with | |
71 | * the _rcu list-mutation primitives such as hlist_add_head_rcu() | |
72 | * as long as the traversal is guarded by rcu_read_lock(). | |
73 | * | |
74 | * This is the same as hlist_for_each_entry_rcu() except that it does | |
75 | * not do any RCU debugging or tracing. | |
76 | */ | |
77 | #define lttng_hlist_for_each_entry_rcu_notrace(pos, head, member) \ | |
78 | for (pos = lttng_hlist_entry_safe (rcu_dereference_raw_notrace(hlist_first_rcu(head)),\ | |
79 | typeof(*(pos)), member); \ | |
80 | pos; \ | |
81 | pos = lttng_hlist_entry_safe(rcu_dereference_raw_notrace(hlist_next_rcu(\ | |
82 | &(pos)->member)), typeof(*(pos)), member)) | |
83 | ||
84 | #endif /* _LTTNG_WRAPPER_LIST_H */ |