HPCToolkit
binarytree_uwi.c
Go to the documentation of this file.
1 //******************************************************************************
2 // global include files
3 //******************************************************************************
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stddef.h> // ptrdiff_t
8 
9 
10 //******************************************************************************
11 // local include files
12 //******************************************************************************
13 
14 #include <lib/prof-lean/mcs-lock.h>
16 #include "binarytree_uwi.h"
17 
18 #define NUM_NODES 10
19 
20 static struct {
21  bitree_uwi_t *tree; // global free unwind interval tree
22  mcs_lock_t lock; // lock for tree
24 } GF[NUM_UNWINDERS];
25 
26 static __thread bitree_uwi_t *_lf_uwi_tree[NUM_UNWINDERS]; // thread local free unwind interval tree
27 
28 /*
29  * initialize the MCS lock for the hidden global free unwind interval tree.
30  */
31 void
33 {
34  int i;
35  for (i = 0; i < NUM_UNWINDERS; ++i) {
36  mcs_init(&GF[i].lock);
37  GF[i].tree = NULL;
38  GF[i].alloc = m_alloc;
39  }
40 }
41 
42 // constructors
45  size_t recipe_size)
46 {
47  if (!_lf_uwi_tree[uw]) {
48  mcs_node_t me;
49  if (mcs_trylock(&GF[uw].lock, &me)) {
50  // the global free list is locked, so use it
51  _lf_uwi_tree[uw] = GF[uw].tree;
52  if (_lf_uwi_tree[uw])
53  GF[uw].tree = bitree_uwi_leftsubtree(_lf_uwi_tree[uw]);
54  mcs_unlock(&GF[uw].lock, &me);
55  if (_lf_uwi_tree[uw])
57  }
58  if (!_lf_uwi_tree[uw])
59  _lf_uwi_tree[uw] =
60  (bitree_uwi_t *)binarytree_listalloc(sizeof(uwi_t) + recipe_size,
61  NUM_NODES, GF[uw].alloc);
62  }
63 
64  bitree_uwi_t *top = _lf_uwi_tree[uw];
65  if (top) {
68  }
69  return top;
70 }
71 
72 /*
73  * link only non null tree to GF.tree
74  */
76 {
77  if(!tree) return;
78  tree = bitree_uwi_flatten(tree);
79  // link to the global free unwind interval tree:
80  mcs_node_t me;
81  mcs_lock(&GF[uw].lock, &me);
82  bitree_uwi_set_leftsubtree(tree, GF[uw].tree);
83  GF[uw].tree = tree;
84  mcs_unlock(&GF[uw].lock, &me);
85 }
86 
87 // return the value at the root
88 // pre-condition: tree != NULL
89 uwi_t*
91 {
92  return (uwi_t*) binarytree_rootval((binarytree_t*) tree);
93 }
94 
95 // pre-condition: tree != NULL
98 {
100 }
101 
102 // pre-condition: tree != NULL
105 {
107 }
108 
109 void
112  bitree_uwi_t* subtree)
113 {
115 }
116 
117 void
120  bitree_uwi_t* subtree)
121 {
123 }
124 
125 
126 // return the interval_t part of the interval_t key of the tree root
127 // pre-condition: tree != NULL
128 interval_t*
130 {
131  if (tree == NULL) return NULL;
132  uwi_t* uwi = bitree_uwi_rootval(tree);
133  if (uwi == NULL) return NULL;
134  return &uwi->interval;
135 }
136 
137 // return the recipe_t value of the tree root
138 // pre-condition: tree != NULL
141 {
142  if (tree == NULL) return NULL;
143  uwi_t* uwi = bitree_uwi_rootval(tree);
144  if (uwi == NULL) return NULL;
145  return (uw_recipe_t *)uwi->recipe;
146 }
147 
148 // change a tree of all right children into a balanced tree
151 {
152  binarytree_t *balanced = binarytree_list_to_tree((binarytree_t**)&tree, count);
153  return (bitree_uwi_t*)balanced;
154 }
155 
158 {
159  binarytree_t *flattened = binarytree_listify((binarytree_t*)tree);
160  return (bitree_uwi_t*)flattened;
161 }
162 
163 static int
164 uwi_t_cmp(void* lhs, void* rhs)
165 {
166  uwi_t* uwi1 = (uwi_t*)lhs;
167  uwi_t* uwi2 = (uwi_t*)rhs;
168  return interval_t_cmp(&uwi1->interval, &uwi2->interval);
169 }
170 
171 // use uwi_t_cmp to find a matching node in a binary search tree of uwi_t
172 // empty tree is returned if no match is found.
175 {
177  binarytree_find((binarytree_t*)tree, uwi_t_cmp, val);
178  return (bitree_uwi_t*)found;
179 }
180 
181 // use uwi_t_inrange to find a node in a binary search tree of uwi_t that
182 // contains the given address
183 // empty tree is returned if no such node is found.
184 static int
185 uwi_t_inrange(void* lhs, void* address)
186 {
187  uwi_t* uwi = (uwi_t*)lhs;
188  return interval_t_inrange(&uwi->interval, address);
189 }
190 
193 {
194  binarytree_t * found =
195  binarytree_find((binarytree_t*)tree, uwi_t_inrange, (void*)address);
196  return (bitree_uwi_t*)found;
197 }
198 
199 
200 //******************************************************************************
201 // String output
202 //******************************************************************************
203 
204 #define MAX_UWI_STR MAX_INTERVAL_STR+MAX_RECIPE_STR+4
205 static void
206 uwi_t_any_tostr(void* uwip, char str[], unwinder_t uw)
207 {
208  uwi_t *uwi = uwip;
209  char intervalstr[MAX_INTERVAL_STR];
210  interval_t_tostr(&uwi->interval, intervalstr);
211  char recipestr[MAX_RECIPE_STR];
212  uw_recipe_tostr(uwi->recipe, recipestr, uw);
213  sprintf(str, "(%s %s)", intervalstr, recipestr);
214 }
215 
216 static void
217 uwi_t_dwarf_tostr(void* uwip, char str[])
218 {
219  uwi_t_any_tostr(uwip, str, DWARF_UNWINDER);
220 }
221 
222 static void
223 uwi_t_native_tostr(void* uwip, char str[])
224 {
225  uwi_t_any_tostr(uwip, str, NATIVE_UNWINDER);
226 }
227 
228 static void
229 (*uwi_t_tostr[NUM_UNWINDERS])(void *uwip, char str[]) =
230 {
233 };
234 
235 void
237  char treestr[], unwinder_t uw)
238 {
239  char uwibuff[MAX_UWI_STR];
241  uwi_t_tostr[uw], uwibuff, indents, treestr);
242 }
#define MAX_INTERVAL_STR
Definition: interval_t.h:20
void *(* mem_alloc)(size_t size)
Definition: mem_manager.h:17
static __thread bitree_uwi_t * _lf_uwi_tree[NUM_UNWINDERS]
bitree_uwi_t * bitree_uwi_rebalance(bitree_uwi_t *tree, int count)
#define NUM_NODES
static void(* uwi_t_tostr[NUM_UNWINDERS])(void *uwip, char str[])
void mcs_lock(mcs_lock_t *l, mcs_node_t *me)
Definition: mcs-lock.c:77
#define MAX_UWI_STR
bitree_uwi_t * bitree_uwi_rightsubtree(bitree_uwi_t *tree)
uwi_t * bitree_uwi_rootval(bitree_uwi_t *tree)
int interval_t_cmp(void *lhs, void *rhs)
Definition: interval_t.c:21
int interval_t_inrange(void *lhs, void *val)
Definition: interval_t.c:31
static int uwi_t_cmp(void *lhs, void *rhs)
void uw_recipe_tostr(void *uwr, char str[], unwinder_t uw)
bitree_uwi_t * bitree_uwi_inrange(bitree_uwi_t *tree, uintptr_t address)
static void uwi_t_any_tostr(void *uwip, char str[], unwinder_t uw)
void * binarytree_rootval(binarytree_t *tree)
Definition: binarytree.c:163
mcs_lock_t lock
bool mcs_trylock(mcs_lock_t *l, mcs_node_t *me)
Definition: mcs-lock.c:122
void mcs_unlock(mcs_lock_t *l, mcs_node_t *me)
Definition: mcs-lock.c:146
bitree_uwi_t * bitree_uwi_malloc(unwinder_t uw, size_t recipe_size)
interval_t interval
binarytree_t * binarytree_list_to_tree(binarytree_t **head, int count)
Definition: binarytree.c:211
binarytree_t * binarytree_find(binarytree_t *root, val_cmp matches, void *val)
Definition: binarytree.c:257
static void uwi_t_native_tostr(void *uwip, char str[])
binarytree_t * binarytree_listify(binarytree_t *root)
Definition: binarytree.c:237
uw_recipe_t * bitree_uwi_recipe(bitree_uwi_t *tree)
struct bitree_uwi_s bitree_uwi_t
static int uwi_t_inrange(void *lhs, void *address)
#define MAX_RECIPE_STR
void bitree_uwi_init(mem_alloc m_alloc)
void bitree_uwi_free(unwinder_t uw, bitree_uwi_t *tree)
void interval_t_tostr(void *ptrinterval, char result[])
Definition: interval_t.c:49
bool found
Definition: cct.c:129
mem_alloc alloc
interval_t * bitree_uwi_interval(bitree_uwi_t *tree)
char recipe[]
#define NULL
Definition: ElfHelper.cpp:85
void binarytree_set_rightsubtree(binarytree_t *tree, binarytree_t *subtree)
Definition: binarytree.c:195
void binarytree_tostring_indent(binarytree_t *root, val_tostr tostr, char valstr[], char *indents, char result[])
Definition: binarytree.c:278
enum unwinder_e unwinder_t
binarytree_t * binarytree_leftsubtree(binarytree_t *tree)
Definition: binarytree.c:171
void bitree_uwi_set_leftsubtree(bitree_uwi_t *tree, bitree_uwi_t *subtree)
struct recipe_s uw_recipe_t
static struct @16 GF[NUM_UNWINDERS]
void binarytree_set_leftsubtree(binarytree_t *tree, binarytree_t *subtree)
Definition: binarytree.c:186
binarytree_t * binarytree_rightsubtree(binarytree_t *tree)
Definition: binarytree.c:179
bitree_uwi_t * bitree_uwi_leftsubtree(bitree_uwi_t *tree)
static void mcs_init(mcs_lock_t *l)
Definition: mcs-lock.h:100
binarytree_t * binarytree_listalloc(size_t elt_size, int num_elts, mem_alloc m_alloc)
Definition: binarytree.c:245
bitree_uwi_t * bitree_uwi_find(bitree_uwi_t *tree, uwi_t *val)
static void uwi_t_dwarf_tostr(void *uwip, char str[])
void bitree_uwi_set_rightsubtree(bitree_uwi_t *tree, bitree_uwi_t *subtree)
bitree_uwi_t * tree
bitree_uwi_t * bitree_uwi_flatten(bitree_uwi_t *tree)
void bitree_uwi_tostring_indent(bitree_uwi_t *tree, char *indents, char treestr[], unwinder_t uw)