Add the 'current_kthread' helper
[akaros.git] / kern / include / radix.h
1 /* Copyright (c) 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Radix Tree, modeled after Linux's (described here:
6  * http://lwn.net/Articles/175432/).
7  *
8  * It maps unsigned longs to void*s, growing the depth of the tree as needed to
9  * handle more items.  It won't allow the insertion of existing keys, and it
10  * can fail due to lack of memory.
11  *
12  * There are some utility functions, probably unimplemented til we need them,
13  * that will make the tree have enough memory for future calls.
14  *
15  * You can also store a tag along with the void* for a given item, and do
16  * lookups based on those tags.  Or you will be able to, once it is
17  * implemented. */
18
19 #pragma once
20
21 #define LOG_RNODE_SLOTS 6
22 #define NR_RNODE_SLOTS (1 << LOG_RNODE_SLOTS)
23
24 #include <ros/common.h>
25 #include <kthread.h>
26 #include <atomic.h>
27
28 struct radix_node {
29         void                                            *items[NR_RNODE_SLOTS];
30         unsigned int                            num_items;
31         bool                                            leaf;
32         struct radix_node                       *parent;
33         struct radix_node                       **my_slot;
34 };
35
36 /* writers (insert, delete, and callbacks) must synchronize externally, e.g. a
37  * qlock in the pagemap.
38  *
39  * radix_lookup_slot returns an rcu-protected pointer that needs to be
40  * rcu_read_locked.  The item in the slot (either by *slot or by a regular
41  * radix_lookup) has limited protections.  Higher layers (pagemap) can do their
42  * own thing.  For instance, the page cache writers can zero an item if they
43  * know they cleared the page without someone else grabbing a ref.  We'll
44  * rcu-protect the item pointer, so that higher layers can use RCU for the
45  * actual object.
46  *
47  * Basically the only functions that don't need the caller to hold a qlock are
48  * the two lookup routines: the readers.  The seq counter protects the atomicity
49  * of root, depth, and upper_bound, which defines the reader's start point.  RCU
50  * protects the lifetime of the rnodes, which is where lookup_slot's pointer
51  * points to.
52  *
53  * Note that we use rcu_assign_pointer and rcu_dereference whenever we
54  * manipulate pointers in the tree (pointers to or within rnodes).  We use RCU
55  * for the item pointer too, so that our callers can use RCU if they want.  Both
56  * the slot pointer and what it points to are protected by RCU.
57  */
58 struct radix_tree {
59         seq_ctr_t                                       seq;
60         struct radix_node                       *root;
61         unsigned int                            depth;
62         unsigned long                           upper_bound;
63 };
64
65 void radix_init(void);          /* initializes the whole radix system */
66 void radix_tree_init(struct radix_tree *tree);  /* inits one tree */
67 void radix_tree_destroy(struct radix_tree *tree);
68
69 /* Item management */
70 int radix_insert(struct radix_tree *tree, unsigned long key, void *item,
71                  void ***slot_p);
72 void *radix_delete(struct radix_tree *tree, unsigned long key);
73 void *radix_lookup(struct radix_tree *tree, unsigned long key);
74 void **radix_lookup_slot(struct radix_tree *tree, unsigned long key);
75
76 typedef bool (*radix_cb_t)(void **slot, unsigned long tree_idx, void *arg);
77 void radix_for_each_slot(struct radix_tree *tree, radix_cb_t cb, void *arg);
78 /* [start_idx, end_idx) */
79 void radix_for_each_slot_in_range(struct radix_tree *tree,
80                                   unsigned long start_idx,
81                                   unsigned long end_idx,
82                                   radix_cb_t cb, void *arg);
83
84 /* Memory management */
85 int radix_grow(struct radix_tree *tree, unsigned long max);
86 int radix_preload(struct radix_tree *tree, int flags);
87
88 /* Tag management */
89 void *radix_tag_set(struct radix_tree *tree, unsigned long key, int tag);
90 void *radix_tag_clear(struct radix_tree *tree, unsigned long key, int tag);
91 int radix_tag_get(struct radix_tree *tree, unsigned long key, int tag);
92 int radix_tree_tagged(struct radix_tree *tree, int tag);
93 int radix_tag_gang_lookup(struct radix_tree *tree, void **results,
94                           unsigned long first, unsigned int max_items, int tag);
95
96 /* Debugging */
97 void print_radix_tree(struct radix_tree *tree);