HPCToolkit
agent-pthread.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-2019, 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 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // LUSH: Logical Unwind Support for HPCToolkit
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 // Author:
59 // Nathan Tallent
60 //
61 //***************************************************************************
62 
63 //************************* System Include Files ****************************
64 
65 #include <stdlib.h>
66 #include <stdbool.h>
67 
68 #include <string.h>
69 
70 #include <assert.h>
71 
72 //*************************** User Include Files ****************************
73 
74 #include <include/min-max.h>
75 
76 #include "agent-pthread.h"
77 
78 #include <thread_data.h> // N.B.: outside of LUSHI interface
79 #include <lush/lush-pthread.h> // N.B.: outside of LUSHI interface
80 
81 #include <lib/prof-lean/atomic.h> // N.B.: outside of LUSHI interface
82 
83 //*************************** Forward Declarations **************************
84 
85 #define LUSHCB_DECL(FN) \
86  LUSH ## FN ## _fn_t FN
87 
88 LUSHCB_DECL(CB_malloc);
89 LUSHCB_DECL(CB_free);
90 LUSHCB_DECL(CB_step);
91 LUSHCB_DECL(CB_loadmap_find);
92 // lush_cursor stuff
93 
94 #undef LUSHCB_DECL
95 
97 
98 // **************************************************************************
99 // Initialization/Finalization
100 // **************************************************************************
101 
102 extern int
103 LUSHI_init(int argc, char** argv,
104  lush_agentid_t aid,
105  LUSHCB_malloc_fn_t malloc_fn,
106  LUSHCB_free_fn_t free_fn,
107  LUSHCB_step_fn_t step_fn,
108  LUSHCB_loadmap_find_fn_t loadmap_fn)
109 {
110  MY_lush_aid = aid;
111 
112  CB_malloc = malloc_fn;
113  CB_free = free_fn;
114  CB_step = step_fn;
115  CB_loadmap_find = loadmap_fn;
116 
117  return 0;
118 }
119 
120 
121 extern int
123 {
124  return 0;
125 }
126 
127 
128 extern char*
129 LUSHI_strerror(int code)
130 {
131  return ""; // STUB
132 }
133 
134 
135 // **************************************************************************
136 // Maintaining Responsibility for Code/Frame-space
137 // **************************************************************************
138 
139 extern int
141 {
142  return 0; // FIXME: coordinate with dylib stuff
143 }
144 
145 
146 extern bool
148 {
149  // NOTE: Currently, this does not prevent our LUSHI_do_backtrace
150  // from being called, but it may not be quite right in the context
151  // of multiple agents.
152  return false; // force LUSH to use the identity logical unwind
153 }
154 
155 
156 // **************************************************************************
157 //
158 // **************************************************************************
159 
160 extern lush_step_t
162 {
163  assert(0 && "LUSHI_step_bichord: should never be called");
164  return LUSH_STEP_ERROR;
165 }
166 
167 
168 extern lush_step_t
170 {
171  assert(0 && "LUSHI_step_pnote: should never be called");
172  return LUSH_STEP_ERROR;
173 }
174 
175 
176 extern lush_step_t
178 {
179  assert(0 && "LUSHI_step_lnote: should never be called");
180  return LUSH_STEP_ERROR;
181 }
182 
183 
184 extern int
186 {
187  return 0; // STUB
188 }
189 
190 
191 // **************************************************************************
192 //
193 // **************************************************************************
194 
195 extern int
197 {
198  return 0; // STUB
199 }
200 
201 
202 extern int
204 {
205  return 0; // STUB
206 }
207 
208 
209 extern int
211 {
212  return 0; // STUB
213 }
214 
215 
216 extern int
218 {
219  return 0; // STUB
220 }
221 
222 
223 // **************************************************************************
224 // Metrics
225 // **************************************************************************
226 
227 extern bool
228 LUSHI_do_metric(uint64_t incrMetricIn,
229  bool* doMetric, bool* doMetricIdleness,
230  uint64_t* incrMetric, double* incrMetricIdleness)
231 {
232  lushPthr_t* pthr = &TD_GET(pthr_metrics);
233  bool isWorking = pthr->is_working;
234 
235  if (isWorking) {
236 #if (LUSH_PTHR_FN_TY == 1)
237  // NOTE: pthr->idleness is only changed when this thread is not working
238  *doMetric = true;
239  *doMetricIdleness = (pthr->idleness > 0);
240  *incrMetric = incrMetricIn;
241  *incrMetricIdleness = pthr->idleness;
242  pthr->idleness = 0;
243 #elif (LUSH_PTHR_FN_TY == 2)
244  bool is_working_lock = lushPthr_isWorking_lock(pthr);
245 
246  double num_working = *(pthr->ps_num_working);
247  double num_working_lock = *(pthr->ps_num_working_lock);
248  double num_idle_cond = MAX(0, *(pthr->ps_num_idle_cond)); // timing!
249 
250  // INVARIANT: Since this thread is working, it is either working
251  // while locked or it is working as 'other' (within a condition
252  // variable critical section or without a lock).
253  double idleness = 0.0;
254  if (is_working_lock) {
255  // -----------------------------------------------------
256  // is_working_lock() : num_idle_lock / num_working_lock
257  // -----------------------------------------------------
258  double num_idle = (*(pthr->ps_num_threads) - num_working);
259  double num_idle_lock = MAX(0, num_idle - num_idle_cond);
260  num_working_lock = MAX(1, num_working_lock); // timing windows
261  idleness = (num_idle_lock / num_working_lock);
262  }
263  else {
264  // -----------------------------------------------------
265  // is_working_cond() || is_working : num_idle_cond / num_working_othr
266  // -----------------------------------------------------
267  // INVARIANT: (num_working - num_working_lock) should always be > 0
268  double num_working_othr = MAX(1, num_working - num_working_lock);
269  idleness = (num_idle_cond / num_working_othr);
270  }
271 
272  *doMetric = true;
273  *doMetricIdleness = true;
274  *incrMetric = incrMetricIn;
275  *incrMetricIdleness = (double)incrMetricIn * idleness;
276 #elif (LUSH_PTHR_FN_TY == 3)
277  // Same as 1
278  *doMetric = true;
279  *doMetricIdleness = (pthr->idleness > 0);
280  *incrMetric = incrMetricIn;
281  *incrMetricIdleness = pthr->idleness;
282  pthr->idleness = 0;
283 #else
284 # error "agent-pthread.c!"
285 #endif
286  }
287  else {
288 #if (LUSH_PTHR_FN_TY == 1)
289  *doMetric = true;
290  *doMetricIdleness = true;
291  *incrMetric = 0;
292  *incrMetricIdleness = (double)incrMetricIn;
293 #elif (LUSH_PTHR_FN_TY == 2)
294  *doMetric = false;
295  *doMetricIdleness = false;
296  //*incrMetric = 0;
297  //*incrMetricIdleness = 0.0;
298 #elif (LUSH_PTHR_FN_TY == 3)
299  if (pthr->syncObjData) {
300  // INVARIANT: spin waiting on pthr->syncObjData
301  hpcrun_atomicAdd(&pthr->syncObjData->idleness, incrMetricIn);
302  }
303  *doMetric = false;
304  *doMetricIdleness = false;
305 #else
306 # error "agent-pthread.c!"
307 #endif
308  }
309  return *doMetric;
310 }
311 
312 // **************************************************************************
#define MAX(a, b)
Definition: min-max.h:77
int LUSHI_lip_destroy(lush_lip_t *lip)
int LUSHI_lip_write()
lush_step_t LUSHI_step_lnote(lush_cursor_t *cursor)
#define doMetric(metricIdExpr, metricIncr, type)
Definition: ga-overrides.c:296
#define LUSHCB_DECL(FN)
Definition: agent-pthread.c:85
lush_step_t LUSHI_step_pnote(lush_cursor_t *cursor)
lush_step_t LUSHI_step_bichord(lush_cursor_t *cursor)
int lush_agentid_t
Definition: lush-support.h:99
int LUSHI_fini()
int LUSHI_set_active_frame_marker()
int LUSHI_lip_read()
static lush_agentid_t MY_lush_aid
Definition: agent-pthread.c:96
#define TD_GET(field)
Definition: thread_data.h:256
enum lush_step lush_step_t
bool LUSHI_do_metric(uint64_t incrMetricIn, bool *doMetric, bool *doMetricIdleness, uint64_t *incrMetric, double *incrMetricIdleness)
bool LUSHI_ismycode(void *addr)
int LUSHI_reg_dlopen()
int LUSHI_lip_eq(lush_lip_t *lip)
int LUSHI_init(int argc, char **argv, lush_agentid_t aid, LUSHCB_malloc_fn_t malloc_fn, LUSHCB_free_fn_t free_fn, LUSHCB_step_fn_t step_fn, LUSHCB_loadmap_find_fn_t loadmap_fn)
cct_addr_t * addr
Definition: cct.c:130
char * LUSHI_strerror(int code)
static bool lushPthr_isWorking_lock(lushPthr_t *x)
Definition: lush-pthread.h:326