HPCToolkit
lush-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, Rice University.
60 //
61 //***************************************************************************
62 
63 //************************* System Include Files ****************************
64 
65 #include <stdlib.h>
66 #include <stdbool.h>
67 
68 #include <unistd.h> // sysconf
69 
70 
71 //*************************** User Include Files ****************************
72 
73 #include <include/gcc-attr.h>
74 
75 #include "lush-pthread.h"
76 
77 #include <messages/messages.h>
78 
79 
80 //*************************** Forward Declarations **************************
81 
82 #if (LUSH_PTHR_FN_TY == 3)
83 # define lushPthr_memSizeElem (5 * 1024 * 1024)
84 #else
85 # define lushPthr_memSizeElem (0)
86 #endif
87 
88 // FIXME: tallent: hardcoded size for now
89 lushPtr_SyncObjData_t lushPthr_mem[lushPthr_memSizeElem] GCC_ATTR_VAR_CACHE_ALIGN;
90 
91 #define lushPthr_memSize (sizeof(lushPthr_mem))
92 #define lushPthr_memSizeMax (0x3fffffff) /* lower 30 bits */
93 
96 
97 lushPthr_mem_ptr_t lushPthr_mem_ptr;
98 
99 
100 #if (LUSH_DBG_STATS)
101 atomic_long DBG_numLockAcq = 0; // total lock acquires
102 
103 atomic_long DBG_numLockAlloc = 0; // total locks allocated
104 
105 atomic_long DBG_maxLockAllocCur = 0; // max locks allocated simultaneously
106 atomic_long DBG_numLockFreelistCur = 0; // number of (spin) locks cur. on freelists
107 #endif
108 
109 
110 //*************************** Forward Declarations **************************
111 
112 // NOTE: For a portable alternative, union each cache-aligned variable
113 // to with an char array of the appropriate size.
114 
115 typedef struct {
116 
117  atomic_long ps_num_procs GCC_ATTR_VAR_CACHE_ALIGN;
118  atomic_long ps_num_threads;
119 
120  atomic_long ps_num_working GCC_ATTR_VAR_CACHE_ALIGN;
121 
122  atomic_long ps_num_working_lock GCC_ATTR_VAR_CACHE_ALIGN;
123 
124  atomic_long ps_num_idle_cond GCC_ATTR_VAR_CACHE_ALIGN;
125 
126  // LUSH_PTHR_FN_TY == 3
127  BalancedTree_t ps_syncObjToData; // synch-obj -> data
128 
130 
131 
133  .ps_num_procs = ATOMIC_VAR_INIT(0),
134  .ps_num_threads = ATOMIC_VAR_INIT(0),
135  .ps_num_working = ATOMIC_VAR_INIT(0),
136  .ps_num_working_lock = ATOMIC_VAR_INIT(0),
137  .ps_num_idle_cond = ATOMIC_VAR_INIT(0)
138  // ps_syncObjToData
139 };
140 
141 
142 // **************************************************************************
143 //
144 // **************************************************************************
145 
146 void
148 {
149  // WARNING: At the moment, this routine is called *after*
150  // lushPthr_init(), at least for the first thread.
151 
152  atomic_store_explicit(&globals.ps_num_procs, sysconf(_SC_NPROCESSORS_ONLN), memory_order_relaxed);
154 
155  atomic_store_explicit(&globals.ps_num_working, 0, memory_order_relaxed);
156  atomic_store_explicit(&globals.ps_num_working_lock, 0, memory_order_relaxed);
157 
158  atomic_store_explicit(&globals.ps_num_idle_cond, 0, memory_order_relaxed);
159 
160  // LUSH_PTHR_FN_TY == 3
162  sizeof(lushPtr_SyncObjData_t));
163 
164  lushPthr_mem_beg = (void*)lushPthr_mem;
165  lushPthr_mem_end = (void*)lushPthr_mem + lushPthr_memSize;
166 
167  // align with next cache line
169  (void*)( (uintptr_t)(lushPthr_mem_beg
171  + (HOST_CACHE_LINE_SZ - 1))
172  & (uintptr_t)~(HOST_CACHE_LINE_SZ - 1)),
174 
175 #if (LUSH_PTHR_FN_TY == 3)
176  // sanity check
177  if ( !(sizeof(pthread_spinlock_t) == 4) ) {
178  hpcrun_abort("LUSH Pthreads found unexpected pthread_spinlock_t type!");
179  }
181  hpcrun_abort("LUSH Pthreads found bad mem size!");
182  }
183 #endif
184 }
185 
186 
187 // **************************************************************************
188 
189 void
190 lushPthr_init(lushPthr_t* x)
191 {
192  x->is_working = false;
193  x->num_locks = 0;
194  x->cond_lock = 0;
195 
196  x->doIdlenessCnt = 0;
197  x->begIdleness = 0;
198  x->idleness = 0;
199 
200  x->ps_num_procs = &globals.ps_num_procs;
201  x->ps_num_threads = &globals.ps_num_threads;
202 
203  x->ps_num_working = &globals.ps_num_working;
204  x->ps_num_working_lock = &globals.ps_num_working_lock;
205 
206  x->ps_num_idle_cond = &globals.ps_num_idle_cond;
207 
208  // ------------------------------------------------------------
209  // LUSH_PTHR_FN_TY == 3
210  // ------------------------------------------------------------
211  x->ps_syncObjToData = &globals.ps_syncObjToData;
212  BalancedTree_init(&x->syncObjToData, hpcrun_malloc, 0/*nodeDataSz*/);
213 
214  x->syncObjData = NULL;
215 
216  x->cache_syncObj = NULL;
217  x->cache_syncObjData = NULL;
218 
219  x->freelstHead = NULL;
220  x->freelstTail = NULL;
221 }
222 
223 
224 void
225 lushPthr_dump(lushPthr_t* x, const char* nm, void* lock)
226 {
227 #if (LUSH_PTHR_FN_TY == 3)
228  int lckval = (lock) ? *((int*)lock) : 0;
229  int lushval = 0;
230  if (lushPthr_isSyncDataPointer(lckval)) {
231  lushPtr_SyncObjData_t* data = lushPthr_getSyncDataPointer(lckval);
232  lushval = data->lock.spin;
233  }
234  EMSG("lushPthr/%s:\t lck: %p->%#x->%d", nm, lock, lckval, lushval);
235 #else
236  EMSG("lushPthr/%s:\t is_wrking %d, num_lck %d, cnd_lck %d | "
237  "# wrking %ld, wrking_lck %ld, idle_cnd %ld | "
238  "# procs %ld, threads %d",
239  nm, x->is_working, x->num_locks, x->cond_lock,
240  atomic_load_explicit(x->ps_num_working, memory_order_relaxed),
241  atomic_load_explicit(x->ps_num_working_lock, memory_order_relaxed),
242  atomic_load_explicit(x->ps_num_idle_cond, memory_order_relaxed),
243  atomic_load_explicit(x->ps_num_procs, memory_order_relaxed),
244  atomic_load_explicit(x->ps_num_threads, memory_order_relaxed));
245 #endif
246 }
247 
248 
249 
250 //***************************************************************************
BalancedTree_t ps_syncObjToData
Definition: lush-pthread.c:127
#define ATOMIC_VAR_INIT(value)
Definition: stdatomic.h:132
lushPtr_SyncObjData_t lushPthr_mem [lushPthr_memSizeElem] GCC_ATTR_VAR_CACHE_ALIGN
Definition: lush-pthread.c:89
#define hpcrun_abort(...)
Definition: messages.h:102
void lushPthr_init(lushPthr_t *x)
Definition: lush-pthread.c:190
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:378
#define atomic_store_explicit(object, desired, order)
Definition: stdatomic.h:380
atomic_long ps_num_idle_cond GCC_ATTR_VAR_CACHE_ALIGN
Definition: lush-pthread.c:124
mcs_lock_t lock
static lushPtr_SyncObjData_t * lushPthr_getSyncDataPointer(atomic_pthread_spinlock_t lockval)
Definition: lush-pthread.h:596
#define lushPthr_maxValueOfLock
Definition: lush-pthread.h:584
atomic_long ps_num_working GCC_ATTR_VAR_CACHE_ALIGN
Definition: lush-pthread.c:120
void * lushPthr_mem_end
Definition: lush-pthread.c:95
#define EMSG
Definition: messages.h:70
void lushPthr_dump(lushPthr_t *x, const char *nm, void *lock)
Definition: lush-pthread.c:225
atomic_long ps_num_procs GCC_ATTR_VAR_CACHE_ALIGN
Definition: lush-pthread.c:117
void lushPthr_processInit()
Definition: lush-pthread.c:147
#define lushPthr_memSizeElem
Definition: lush-pthread.c:85
atomic_long ps_num_working_lock GCC_ATTR_VAR_CACHE_ALIGN
Definition: lush-pthread.c:122
void * hpcrun_malloc(size_t size)
Definition: mem.c:275
atomic_long ps_num_threads
Definition: lush-pthread.c:118
lushPthr_mem_ptr_t lushPthr_mem_ptr
Definition: lush-pthread.c:97
#define lushPthr_memSizeMax
Definition: lush-pthread.c:92
#define NULL
Definition: ElfHelper.cpp:85
void BalancedTree_init(BalancedTree_t *tree, BalancedTree_alloc_fn_t allocFn, size_t nodeDataSz)
Definition: BalancedTree.c:103
#define lushPthr_memSize
Definition: lush-pthread.c:91
void * lushPthr_mem_beg
Definition: lush-pthread.c:94
lushPthr_globals_t globals
Definition: lush-pthread.c:132
static bool lushPthr_isSyncDataPointer(pthread_spinlock_t lockval)
Definition: lush-pthread.h:589