Xenomai  3.1
tree.h
1 /*
2  * Copyright (C) 2014 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 #ifndef _COBALT_KERNEL_TREE_H
19 #define _COBALT_KERNEL_TREE_H
20 
21 #include <linux/errno.h>
22 #include <linux/rbtree.h>
23 #include <cobalt/kernel/assert.h>
24 
25 typedef unsigned long long xnkey_t;
26 
27 static inline xnkey_t PTR_KEY(void *p)
28 {
29  return (xnkey_t)(long)p;
30 }
31 
32 struct xnid {
33  xnkey_t key;
34  struct rb_node link;
35 };
36 
37 #define xnid_entry(ptr, type, member) \
38  ({ \
39  typeof(ptr) _ptr = (ptr); \
40  (_ptr ? container_of(_ptr, type, member.link) : NULL); \
41  })
42 
43 #define xnid_next_entry(ptr, member) \
44  xnid_entry(rb_next(&ptr->member.link), typeof(*ptr), member)
45 
46 static inline void xntree_init(struct rb_root *t)
47 {
48  *t = RB_ROOT;
49 }
50 
51 #define xntree_for_each_entry(pos, root, member) \
52  for (pos = xnid_entry(rb_first(root), typeof(*pos), member); \
53  pos; pos = xnid_next_entry(pos, member))
54 
55 void xntree_cleanup(struct rb_root *t, void *cookie,
56  void (*destroy)(void *cookie, struct xnid *id));
57 
58 int xnid_enter(struct rb_root *t, struct xnid *xnid, xnkey_t key);
59 
60 static inline xnkey_t xnid_key(struct xnid *i)
61 {
62  return i->key;
63 }
64 
65 static inline
66 struct xnid *xnid_fetch(struct rb_root *t, xnkey_t key)
67 {
68  struct rb_node *node = t->rb_node;
69 
70  while (node) {
71  struct xnid *i = container_of(node, struct xnid, link);
72 
73  if (key < i->key)
74  node = node->rb_left;
75  else if (key > i->key)
76  node = node->rb_right;
77  else
78  return i;
79  }
80 
81  return NULL;
82 }
83 
84 static inline int xnid_remove(struct rb_root *t, struct xnid *xnid)
85 {
86 #ifdef CONFIG_XENO_OPT_DEBUG_COBALT
87  if (xnid_fetch(t, xnid->key) != xnid)
88  return -ENOENT;
89 #endif
90  rb_erase(&xnid->link, t);
91  return 0;
92 }
93 
94 #endif /* _COBALT_KERNEL_TREE_H */