HPCToolkit
data_tree.c
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2017, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 
48 /******************************************************************************
49  * local include files
50  *****************************************************************************/
51 
52 #include <messages/messages.h>
53 #include <lib/prof-lean/spinlock.h>
55 
56 #include <include/queue.h> // slist
57 
58 #include <memory/hpcrun-malloc.h>
59 
60 #include "data_tree.h"
61 
62 /******************************************************************************
63  * macros
64  *****************************************************************************/
65 
66 #define DATATREE_DEBUG 0
67 
68 
69 /******************************************************************************
70  * private data
71  *****************************************************************************/
72 
74 
76 
77 
78 
79 /******************************************************************************
80  * PRIVATE splay operations
81  *****************************************************************************/
82 
83 
84 static struct datatree_info_s *
85 splay(struct datatree_info_s *root, void *key)
86 {
88  return root;
89 }
90 
91 static struct datatree_info_s **
92 interval_splay(struct datatree_info_s **root, void *key, void **start, void **end)
93 {
95  return root;
96 }
97 
98 #if DATATREE_DEBUG
99 // for debugging purpose
100 static int
101 splay_tree_count_size(struct datatree_info_s *current)
102 {
103  int result = 0;
104 
105  if (!current) return 0;
106  result += splay_tree_count_size(current->left);
107  result += splay_tree_count_size(current->right);
108 
109  return result + 1;
110 }
111 
112 
113 static int
114 splay_tree_size()
115 {
116  return splay_tree_count_size(datacentric_tree_root);
117 }
118 #endif
119 
120 /******************************************************************************
121  * PUBLIC splay operations
122  *****************************************************************************/
123 
124 
125 /*
126  * Insert a node
127  */
128 void
130 {
131  void *memblock = node->memblock;
132 
133  node->left = node->right = NULL;
134 
135  spinlock_lock(&datatree_lock);
136 
137  if (datacentric_tree_root != NULL) {
138 
139  datacentric_tree_root = splay(datacentric_tree_root, memblock);
140 
141  if (memblock < datacentric_tree_root->memblock) {
142  node->left = datacentric_tree_root->left;
144  datacentric_tree_root->left = NULL;
145  } else if (memblock > datacentric_tree_root->memblock) {
146  node->left = datacentric_tree_root;
147  node->right = datacentric_tree_root->right;
148  datacentric_tree_root->right = NULL;
149  }
150  }
151  datacentric_tree_root = node;
152 
153 #if DATATREE_DEBUG
154  TMSG(DATACENTRIC, "[%x] %d items addr %x (%d bytes)",
155  node->magic, splay_tree_size(), node->memblock, node->bytes);
156 #endif
157 
158  spinlock_unlock(&datatree_lock);
159 }
160 
161 /*
162  * remove a node containing a memory block
163  */
164 struct datatree_info_s *
166 {
167  struct datatree_info_s *result = NULL;
168 
169  if (datacentric_tree_root == NULL) {
170  return NULL;
171  }
172 
173  spinlock_lock(&datatree_lock);
174 
175  datacentric_tree_root = splay(datacentric_tree_root, memblock);
176 
177  if (!datacentric_tree_root ||
178  memblock != datacentric_tree_root->memblock) {
179  spinlock_unlock(&datatree_lock);
180  return NULL;
181  }
182 
183  result = datacentric_tree_root;
184 
185 
186  if (datacentric_tree_root->left == NULL) {
187  datacentric_tree_root = datacentric_tree_root->right;
188  spinlock_unlock(&datatree_lock);
189  return result;
190  }
191 
192  datacentric_tree_root->left = splay(datacentric_tree_root->left, memblock);
193  datacentric_tree_root->left->right = datacentric_tree_root->right;
194  datacentric_tree_root = datacentric_tree_root->left;
195 
196  spinlock_unlock(&datatree_lock);
197  return result;
198 }
199 
200 
201 /* interface for data-centric analysis */
202 struct datatree_info_s *
203 datatree_splay_lookup(void *key, void **start, void **end)
204 {
205  if(!datacentric_tree_root || !key) {
206  return NULL;
207  }
208 
209  spinlock_lock(&datatree_lock);
210 
211  struct datatree_info_s **root = NULL;
212  root = interval_splay(&datacentric_tree_root, key, start, end);
213  if (!root) {
214  spinlock_unlock(&datatree_lock);
215  return NULL;
216  }
217 
218  struct datatree_info_s *info = *root;
219 
220 #if DATATREE_DEBUG
221  TMSG(DATACENTRIC, "lookup key: %p %result: %p ", key, info);
222 #endif
223 
224  if(info && (info->memblock <= key) && (info->rmemblock > key)) {
225  *start = info->memblock;
226  *end = info->rmemblock;
227 
228  spinlock_unlock(&datatree_lock);
229  return info;
230  }
231 
232  spinlock_unlock(&datatree_lock);
233 
234  return NULL;
235 }
#define INTERVAL_SPLAY_TREE(type, root, key, start, end, left, right)
Definition: splay-macros.h:198
void * memblock
Definition: data_tree.h:70
struct datatree_info_s * right
Definition: data_tree.h:74
static void spinlock_unlock(spinlock_t *l)
Definition: spinlock.h:96
cct_node_t * node
Definition: cct.c:128
size_t bytes
Definition: data_tree.h:69
#define REGULAR_SPLAY_TREE(type, root, key, value, left, right)
Definition: splay-macros.h:172
void datatree_splay_insert(struct datatree_info_s *node)
Definition: data_tree.c:129
struct datatree_info_s * left
Definition: data_tree.h:73
static struct datatree_info_s ** interval_splay(struct datatree_info_s **root, void *key, void **start, void **end)
Definition: data_tree.c:92
struct datatree_info_s * datatree_splay_delete(void *memblock)
Definition: data_tree.c:165
static struct datatree_info_s * splay(struct datatree_info_s *root, void *key)
Definition: data_tree.c:85
static void DATACENTRIC()
Definition: cct_bundle.c:71
static void spinlock_lock(spinlock_t *l)
Definition: spinlock.h:111
static struct datatree_info_s * datacentric_tree_root
Definition: data_tree.c:75
#define TMSG(f,...)
Definition: messages.h:93
static spinlock_t datatree_lock
Definition: data_tree.c:73
#define NULL
Definition: ElfHelper.cpp:85
struct datatree_info_s * datatree_splay_lookup(void *key, void **start, void **end)
Definition: data_tree.c:203
void * rmemblock
Definition: data_tree.h:71
#define SPINLOCK_UNLOCKED
Definition: spinlock.h:84