1 /*--------------------------------------------------------------------*/ 2 /*--- Callgrind ---*/ 3 /*--- ct_threads.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Callgrind, a Valgrind tool for call tracing. 8 9 Copyright (C) 2002-2017, Josef Weidendorfer (Josef.Weidendorfer (at) gmx.de) 10 11 This program is free software; you can redistribute it and/or 12 modify it under the terms of the GNU General Public License as 13 published by the Free Software Foundation; either version 2 of the 14 License, or (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, but 17 WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 24 02111-1307, USA. 25 26 The GNU General Public License is contained in the file COPYING. 27 */ 28 29 #include "global.h" 30 31 #include "pub_tool_threadstate.h" 32 33 /* forward decls */ 34 static exec_state* exec_state_save(void); 35 static exec_state* exec_state_restore(void); 36 static exec_state* push_exec_state(int); 37 static exec_state* top_exec_state(void); 38 39 static exec_stack current_states; 40 41 42 /*------------------------------------------------------------*/ 43 /*--- Support for multi-threading ---*/ 44 /*------------------------------------------------------------*/ 45 46 47 /* 48 * For Valgrind, MT is cooperative (no preemting in our code), 49 * so we don't need locks... 50 * 51 * Per-thread data: 52 * - BBCCs 53 * - call stack 54 * - call hash 55 * - event counters: last, current 56 * 57 * Even when ignoring MT, we need this functions to set up some 58 * datastructures for the process (= Thread 1). 59 */ 60 61 /* current running thread */ 62 ThreadId CLG_(current_tid); 63 64 static thread_info** thread; 65 66 thread_info** CLG_(get_threads)() 67 { 68 return thread; 69 } 70 71 thread_info* CLG_(get_current_thread)() 72 { 73 return thread[CLG_(current_tid)]; 74 } 75 76 void CLG_(init_threads)() 77 { 78 UInt i; 79 80 thread = CLG_MALLOC("cl.threads.it.1", VG_N_THREADS * sizeof thread[0]); 81 82 for(i=0;i<VG_N_THREADS;i++) 83 thread[i] = 0; 84 CLG_(current_tid) = VG_INVALID_THREADID; 85 } 86 87 /* switches through all threads and calls func */ 88 void CLG_(forall_threads)(void (*func)(thread_info*)) 89 { 90 Int t, orig_tid = CLG_(current_tid); 91 92 for(t=1;t<VG_N_THREADS;t++) { 93 if (!thread[t]) continue; 94 CLG_(switch_thread)(t); 95 (*func)(thread[t]); 96 } 97 CLG_(switch_thread)(orig_tid); 98 } 99 100 101 static 102 thread_info* new_thread(void) 103 { 104 thread_info* t; 105 106 t = (thread_info*) CLG_MALLOC("cl.threads.nt.1", 107 sizeof(thread_info)); 108 109 /* init state */ 110 CLG_(init_exec_stack)( &(t->states) ); 111 CLG_(init_call_stack)( &(t->calls) ); 112 CLG_(init_fn_stack) ( &(t->fns) ); 113 /* t->states.entry[0]->cxt = CLG_(get_cxt)(t->fns.bottom); */ 114 115 /* event counters */ 116 t->lastdump_cost = CLG_(get_eventset_cost)( CLG_(sets).full ); 117 t->sighandler_cost = CLG_(get_eventset_cost)( CLG_(sets).full ); 118 CLG_(init_cost)( CLG_(sets).full, t->lastdump_cost ); 119 CLG_(init_cost)( CLG_(sets).full, t->sighandler_cost ); 120 121 /* init data containers */ 122 CLG_(init_fn_array)( &(t->fn_active) ); 123 CLG_(init_bbcc_hash)( &(t->bbccs) ); 124 CLG_(init_jcc_hash)( &(t->jccs) ); 125 126 return t; 127 } 128 129 130 void CLG_(switch_thread)(ThreadId tid) 131 { 132 if (tid == CLG_(current_tid)) return; 133 134 CLG_DEBUG(0, ">> thread %u (was %u)\n", tid, CLG_(current_tid)); 135 136 if (CLG_(current_tid) != VG_INVALID_THREADID) { 137 /* save thread state */ 138 thread_info* t = thread[CLG_(current_tid)]; 139 140 CLG_ASSERT(t != 0); 141 142 /* current context (including signal handler contexts) */ 143 exec_state_save(); 144 CLG_(copy_current_exec_stack)( &(t->states) ); 145 CLG_(copy_current_call_stack)( &(t->calls) ); 146 CLG_(copy_current_fn_stack) ( &(t->fns) ); 147 148 CLG_(copy_current_fn_array) ( &(t->fn_active) ); 149 /* If we cumulate costs of threads, use TID 1 for all jccs/bccs */ 150 if (!CLG_(clo).separate_threads) t = thread[1]; 151 CLG_(copy_current_bbcc_hash)( &(t->bbccs) ); 152 CLG_(copy_current_jcc_hash) ( &(t->jccs) ); 153 } 154 155 CLG_(current_tid) = tid; 156 CLG_ASSERT(tid < VG_N_THREADS); 157 158 if (tid != VG_INVALID_THREADID) { 159 thread_info* t; 160 161 /* load thread state */ 162 163 if (thread[tid] == 0) thread[tid] = new_thread(); 164 t = thread[tid]; 165 166 /* current context (including signal handler contexts) */ 167 CLG_(set_current_exec_stack)( &(t->states) ); 168 exec_state_restore(); 169 CLG_(set_current_call_stack)( &(t->calls) ); 170 CLG_(set_current_fn_stack) ( &(t->fns) ); 171 172 CLG_(set_current_fn_array) ( &(t->fn_active) ); 173 /* If we cumulate costs of threads, use TID 1 for all jccs/bccs */ 174 if (!CLG_(clo).separate_threads) t = thread[1]; 175 CLG_(set_current_bbcc_hash) ( &(t->bbccs) ); 176 CLG_(set_current_jcc_hash) ( &(t->jccs) ); 177 } 178 } 179 180 181 void CLG_(run_thread)(ThreadId tid) 182 { 183 /* check for dumps needed */ 184 static ULong bbs_done = 0; 185 HChar buf[50]; // large enough 186 187 if (CLG_(clo).dump_every_bb >0) { 188 if (CLG_(stat).bb_executions - bbs_done > CLG_(clo).dump_every_bb) { 189 VG_(sprintf)(buf, "--dump-every-bb=%llu", CLG_(clo).dump_every_bb); 190 CLG_(dump_profile)(buf, False); 191 bbs_done = CLG_(stat).bb_executions; 192 } 193 } 194 195 /* now check for thread switch */ 196 CLG_(switch_thread)(tid); 197 } 198 199 void CLG_(pre_signal)(ThreadId tid, Int sigNum, Bool alt_stack) 200 { 201 exec_state *es; 202 203 CLG_DEBUG(0, ">> pre_signal(TID %u, sig %d, alt_st %s)\n", 204 tid, sigNum, alt_stack ? "yes":"no"); 205 206 /* switch to the thread the handler runs in */ 207 CLG_(switch_thread)(tid); 208 209 /* save current execution state */ 210 exec_state_save(); 211 212 /* setup new cxtinfo struct for this signal handler */ 213 es = push_exec_state(sigNum); 214 CLG_(zero_cost)( CLG_(sets).full, es->cost ); 215 CLG_(current_state).cost = es->cost; 216 es->call_stack_bottom = CLG_(current_call_stack).sp; 217 218 /* setup current state for a spontaneous call */ 219 CLG_(init_exec_state)( &CLG_(current_state) ); 220 CLG_(current_state).sig = sigNum; 221 CLG_(push_cxt)(0); 222 } 223 224 /* Run post-signal if the stackpointer for call stack is at 225 * the bottom in current exec state (e.g. a signal handler) 226 * 227 * Called from CLG_(pop_call_stack) 228 */ 229 void CLG_(run_post_signal_on_call_stack_bottom)() 230 { 231 exec_state* es = top_exec_state(); 232 CLG_ASSERT(es != 0); 233 CLG_ASSERT(CLG_(current_state).sig >0); 234 235 if (CLG_(current_call_stack).sp == es->call_stack_bottom) 236 CLG_(post_signal)( CLG_(current_tid), CLG_(current_state).sig ); 237 } 238 239 void CLG_(post_signal)(ThreadId tid, Int sigNum) 240 { 241 exec_state* es; 242 UInt fn_number, *pactive; 243 244 CLG_DEBUG(0, ">> post_signal(TID %u, sig %d)\n", 245 tid, sigNum); 246 247 /* thread switching potentially needed, eg. with instrumentation off */ 248 CLG_(switch_thread)(tid); 249 CLG_ASSERT(sigNum == CLG_(current_state).sig); 250 251 /* Unwind call stack of this signal handler. 252 * This should only be needed at finalisation time 253 */ 254 es = top_exec_state(); 255 CLG_ASSERT(es != 0); 256 while(CLG_(current_call_stack).sp > es->call_stack_bottom) 257 CLG_(pop_call_stack)(); 258 259 if (CLG_(current_state).cxt) { 260 /* correct active counts */ 261 fn_number = CLG_(current_state).cxt->fn[0]->number; 262 pactive = CLG_(get_fn_entry)(fn_number); 263 (*pactive)--; 264 CLG_DEBUG(0, " set active count of %s back to %u\n", 265 CLG_(current_state).cxt->fn[0]->name, *pactive); 266 } 267 268 if (CLG_(current_fn_stack).top > CLG_(current_fn_stack).bottom) { 269 /* set fn_stack_top back. 270 * top can point to 0 if nothing was executed in the signal handler; 271 * this is possible at end on unwinding handlers. 272 */ 273 if (*(CLG_(current_fn_stack).top) != 0) { 274 CLG_(current_fn_stack).top--; 275 CLG_ASSERT(*(CLG_(current_fn_stack).top) == 0); 276 } 277 if (CLG_(current_fn_stack).top > CLG_(current_fn_stack).bottom) 278 CLG_(current_fn_stack).top--; 279 } 280 281 /* sum up costs */ 282 CLG_ASSERT(CLG_(current_state).cost == es->cost); 283 CLG_(add_and_zero_cost)( CLG_(sets).full, 284 thread[CLG_(current_tid)]->sighandler_cost, 285 CLG_(current_state).cost ); 286 287 /* restore previous context */ 288 es->sig = -1; 289 current_states.sp--; 290 es = top_exec_state(); 291 CLG_(current_state).sig = es->sig; 292 exec_state_restore(); 293 294 /* There is no way to reliable get the thread ID we are switching to 295 * after this handler returns. So we sync with actual TID at start of 296 * CLG_(setup_bb)(), which should be the next for callgrind. 297 */ 298 } 299 300 301 302 /*------------------------------------------------------------*/ 303 /*--- Execution states in a thread & signal handlers ---*/ 304 /*------------------------------------------------------------*/ 305 306 /* Each thread can be interrupted by a signal handler, and they 307 * themselves again. But as there's no scheduling among handlers 308 * of the same thread, we don't need additional stacks. 309 * So storing execution contexts and 310 * adding separators in the callstack(needed to not intermix normal/handler 311 * functions in contexts) should be enough. 312 */ 313 314 /* not initialized: call_stack_bottom, sig */ 315 void CLG_(init_exec_state)(exec_state* es) 316 { 317 es->collect = CLG_(clo).collect_atstart; 318 es->cxt = 0; 319 es->jmps_passed = 0; 320 es->bbcc = 0; 321 es->nonskipped = 0; 322 } 323 324 325 static exec_state* new_exec_state(Int sigNum) 326 { 327 exec_state* es; 328 es = (exec_state*) CLG_MALLOC("cl.threads.nes.1", 329 sizeof(exec_state)); 330 331 /* allocate real cost space: needed as incremented by 332 * simulation functions */ 333 es->cost = CLG_(get_eventset_cost)(CLG_(sets).full); 334 CLG_(zero_cost)( CLG_(sets).full, es->cost ); 335 CLG_(init_exec_state)(es); 336 es->sig = sigNum; 337 es->call_stack_bottom = 0; 338 339 return es; 340 } 341 342 void CLG_(init_exec_stack)(exec_stack* es) 343 { 344 Int i; 345 346 /* The first element is for the main thread */ 347 es->entry[0] = new_exec_state(0); 348 for(i=1;i<MAX_SIGHANDLERS;i++) 349 es->entry[i] = 0; 350 es->sp = 0; 351 } 352 353 void CLG_(copy_current_exec_stack)(exec_stack* dst) 354 { 355 Int i; 356 357 dst->sp = current_states.sp; 358 for(i=0;i<MAX_SIGHANDLERS;i++) 359 dst->entry[i] = current_states.entry[i]; 360 } 361 362 void CLG_(set_current_exec_stack)(exec_stack* dst) 363 { 364 Int i; 365 366 current_states.sp = dst->sp; 367 for(i=0;i<MAX_SIGHANDLERS;i++) 368 current_states.entry[i] = dst->entry[i]; 369 } 370 371 372 /* Get top context info struct of current thread */ 373 static 374 exec_state* top_exec_state(void) 375 { 376 Int sp = current_states.sp; 377 exec_state* es; 378 379 CLG_ASSERT((sp >= 0) && (sp < MAX_SIGHANDLERS)); 380 es = current_states.entry[sp]; 381 CLG_ASSERT(es != 0); 382 return es; 383 } 384 385 /* Allocates a free context info structure for a new entered 386 * signal handler, putting it on the context stack. 387 * Returns a pointer to the structure. 388 */ 389 static exec_state* push_exec_state(int sigNum) 390 { 391 Int sp; 392 exec_state* es; 393 394 current_states.sp++; 395 sp = current_states.sp; 396 397 CLG_ASSERT((sigNum > 0) && (sigNum <= _VKI_NSIG)); 398 CLG_ASSERT((sp > 0) && (sp < MAX_SIGHANDLERS)); 399 es = current_states.entry[sp]; 400 if (!es) { 401 es = new_exec_state(sigNum); 402 current_states.entry[sp] = es; 403 } 404 else 405 es->sig = sigNum; 406 407 return es; 408 } 409 410 /* Save current context to top cxtinfo struct */ 411 static 412 exec_state* exec_state_save(void) 413 { 414 exec_state* es = top_exec_state(); 415 416 es->cxt = CLG_(current_state).cxt; 417 es->collect = CLG_(current_state).collect; 418 es->jmps_passed = CLG_(current_state).jmps_passed; 419 es->bbcc = CLG_(current_state).bbcc; 420 es->nonskipped = CLG_(current_state).nonskipped; 421 CLG_ASSERT(es->cost == CLG_(current_state).cost); 422 423 CLG_DEBUGIF(1) { 424 CLG_DEBUG(1, " cxtinfo_save(sig %d): collect %s, jmps_passed %d\n", 425 es->sig, es->collect ? "Yes": "No", es->jmps_passed); 426 CLG_(print_bbcc)(-9, es->bbcc); 427 CLG_(print_cost)(-9, CLG_(sets).full, es->cost); 428 } 429 430 /* signal number does not need to be saved */ 431 CLG_ASSERT(CLG_(current_state).sig == es->sig); 432 433 return es; 434 } 435 436 static 437 exec_state* exec_state_restore(void) 438 { 439 exec_state* es = top_exec_state(); 440 441 CLG_(current_state).cxt = es->cxt; 442 CLG_(current_state).collect = es->collect; 443 CLG_(current_state).jmps_passed = es->jmps_passed; 444 CLG_(current_state).bbcc = es->bbcc; 445 CLG_(current_state).nonskipped = es->nonskipped; 446 CLG_(current_state).cost = es->cost; 447 CLG_(current_state).sig = es->sig; 448 449 CLG_DEBUGIF(1) { 450 CLG_DEBUG(1, " exec_state_restore(sig %d): collect %s, jmps_passed %d\n", 451 es->sig, es->collect ? "Yes": "No", es->jmps_passed); 452 CLG_(print_bbcc)(-9, es->bbcc); 453 CLG_(print_cxt)(-9, es->cxt, 0); 454 CLG_(print_cost)(-9, CLG_(sets).full, es->cost); 455 } 456 457 return es; 458 } 459