fix vlist_simple_add version handling
[project/netifd.git] / utils.h
1 #ifndef __NETIFD_UTILS_H
2 #define __NETIFD_UTILS_H
3
4 #include <libubox/list.h>
5 #include <libubox/avl.h>
6 #include <libubox/blobmsg.h>
7
8 #ifndef __OPTIMIZE__
9 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
10 #else
11 extern int __build_bug_on_failed;
12 #define BUILD_BUG_ON(condition) \
13 do { \
14 ((void)sizeof(char[1 - 2*!!(condition)])); \
15 if (condition) __build_bug_on_failed = 1; \
16 } while(0)
17 #endif
18
19 static inline bool blobmsg_get_bool_default(struct blob_attr *attr, bool val)
20 {
21 if (!attr)
22 return val;
23
24 return blobmsg_get_bool(attr);
25 }
26
27 #define __init __attribute__((constructor))
28
29 struct vlist_tree;
30 struct vlist_node;
31
32 typedef void (*vlist_update_cb)(struct vlist_tree *tree,
33 struct vlist_node *node_new,
34 struct vlist_node *node_old);
35
36 struct vlist_tree {
37 struct avl_tree avl;
38
39 vlist_update_cb update;
40 bool keep_old;
41 bool no_delete;
42
43 int version;
44 };
45
46 struct vlist_node {
47 struct avl_node avl;
48 int version;
49 };
50
51 void vlist_init(struct vlist_tree *tree, avl_tree_comp cmp, vlist_update_cb update);
52
53 #define vlist_find(tree, name, element, node_member) \
54 avl_find_element(&(tree)->avl, name, element, node_member.avl)
55
56 static inline void vlist_update(struct vlist_tree *tree)
57 {
58 tree->version++;
59 }
60
61 void vlist_add(struct vlist_tree *tree, struct vlist_node *node, void *key);
62 void vlist_delete(struct vlist_tree *tree, struct vlist_node *node);
63 void vlist_flush(struct vlist_tree *tree);
64 void vlist_flush_all(struct vlist_tree *tree);
65
66 #define vlist_for_each_element(tree, element, node_member) \
67 avl_for_each_element(&(tree)->avl, element, node_member.avl)
68
69
70 struct vlist_simple_tree {
71 struct list_head list;
72 int head_offset;
73 int version;
74 };
75
76 struct vlist_simple_node {
77 struct list_head list;
78 int version;
79 };
80
81 #define vlist_simple_init(tree, node, member) \
82 __vlist_simple_init(tree, offsetof(node, member))
83
84 void __vlist_simple_init(struct vlist_simple_tree *tree, int offset);
85 void vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node);
86 void vlist_simple_flush(struct vlist_simple_tree *tree);
87 void vlist_simple_flush_all(struct vlist_simple_tree *tree);
88
89 static inline void vlist_simple_update(struct vlist_simple_tree *tree)
90 {
91 tree->version++;
92 }
93
94 static inline void vlist_simple_add(struct vlist_simple_tree *tree, struct vlist_simple_node *node)
95 {
96 node->version = tree->version;
97 list_add(&node->list, &tree->list);
98 }
99
100 #define vlist_simple_for_each_element(tree, element, node_member) \
101 list_for_each_entry(element, &(tree)->list, node_member.list)
102
103 #define vlist_simple_empty(tree) \
104 list_empty(&(tree)->list)
105
106
107 #ifdef __linux__
108 static inline int fls(int x)
109 {
110 int r = 32;
111
112 if (!x)
113 return 0;
114 if (!(x & 0xffff0000u)) {
115 x <<= 16;
116 r -= 16;
117 }
118 if (!(x & 0xff000000u)) {
119 x <<= 8;
120 r -= 8;
121 }
122 if (!(x & 0xf0000000u)) {
123 x <<= 4;
124 r -= 4;
125 }
126 if (!(x & 0xc0000000u)) {
127 x <<= 2;
128 r -= 2;
129 }
130 if (!(x & 0x80000000u)) {
131 x <<= 1;
132 r -= 1;
133 }
134 return r;
135 }
136 #endif
137
138 int avl_strcmp(const void *k1, const void *k2, void *ptr);
139
140 #endif