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-2010, 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[VG_N_THREADS]; 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 Int i; 79 for(i=0;i<VG_N_THREADS;i++) 80 thread[i] = 0; 81 CLG_(current_tid) = VG_INVALID_THREADID; 82 } 83 84 /* switches through all threads and calls func */ 85 void CLG_(forall_threads)(void (*func)(thread_info*)) 86 { 87 Int t, orig_tid = CLG_(current_tid); 88 89 for(t=1;t<VG_N_THREADS;t++) { 90 if (!thread[t]) continue; 91 CLG_(switch_thread)(t); 92 (*func)(thread[t]); 93 } 94 CLG_(switch_thread)(orig_tid); 95 } 96 97 98 static 99 thread_info* new_thread(void) 100 { 101 thread_info* t; 102 103 t = (thread_info*) CLG_MALLOC("cl.threads.nt.1", 104 sizeof(thread_info)); 105 106 /* init state */ 107 CLG_(init_exec_stack)( &(t->states) ); 108 CLG_(init_call_stack)( &(t->calls) ); 109 CLG_(init_fn_stack) ( &(t->fns) ); 110 /* t->states.entry[0]->cxt = CLG_(get_cxt)(t->fns.bottom); */ 111 112 /* event counters */ 113 t->lastdump_cost = CLG_(get_eventset_cost)( CLG_(sets).full ); 114 t->sighandler_cost = CLG_(get_eventset_cost)( CLG_(sets).full ); 115 CLG_(init_cost)( CLG_(sets).full, t->lastdump_cost ); 116 CLG_(init_cost)( CLG_(sets).full, t->sighandler_cost ); 117 118 /* init data containers */ 119 CLG_(init_fn_array)( &(t->fn_active) ); 120 CLG_(init_bbcc_hash)( &(t->bbccs) ); 121 CLG_(init_jcc_hash)( &(t->jccs) ); 122 123 return t; 124 } 125 126 127 void CLG_(switch_thread)(ThreadId tid) 128 { 129 if (tid == CLG_(current_tid)) return; 130 131 CLG_DEBUG(0, ">> thread %d (was %d)\n", tid, CLG_(current_tid)); 132 133 if (CLG_(current_tid) != VG_INVALID_THREADID) { 134 /* save thread state */ 135 thread_info* t = thread[CLG_(current_tid)]; 136 137 CLG_ASSERT(t != 0); 138 139 /* current context (including signal handler contexts) */ 140 exec_state_save(); 141 CLG_(copy_current_exec_stack)( &(t->states) ); 142 CLG_(copy_current_call_stack)( &(t->calls) ); 143 CLG_(copy_current_fn_stack) ( &(t->fns) ); 144 145 CLG_(copy_current_fn_array) ( &(t->fn_active) ); 146 /* If we cumulate costs of threads, use TID 1 for all jccs/bccs */ 147 if (!CLG_(clo).separate_threads) t = thread[1]; 148 CLG_(copy_current_bbcc_hash)( &(t->bbccs) ); 149 CLG_(copy_current_jcc_hash) ( &(t->jccs) ); 150 } 151 152 CLG_(current_tid) = tid; 153 CLG_ASSERT(tid < VG_N_THREADS); 154 155 if (tid != VG_INVALID_THREADID) { 156 thread_info* t; 157 158 /* load thread state */ 159 160 if (thread[tid] == 0) thread[tid] = new_thread(); 161 t = thread[tid]; 162 163 /* current context (including signal handler contexts) */ 164 CLG_(set_current_exec_stack)( &(t->states) ); 165 exec_state_restore(); 166 CLG_(set_current_call_stack)( &(t->calls) ); 167 CLG_(set_current_fn_stack) ( &(t->fns) ); 168 169 CLG_(set_current_fn_array) ( &(t->fn_active) ); 170 /* If we cumulate costs of threads, use TID 1 for all jccs/bccs */ 171 if (!CLG_(clo).separate_threads) t = thread[1]; 172 CLG_(set_current_bbcc_hash) ( &(t->bbccs) ); 173 CLG_(set_current_jcc_hash) ( &(t->jccs) ); 174 } 175 } 176 177 178 void CLG_(run_thread)(ThreadId tid) 179 { 180 /* check for dumps needed */ 181 static ULong bbs_done = 0; 182 static Char buf[512]; 183 184 if (CLG_(clo).dump_every_bb >0) { 185 if (CLG_(stat).bb_executions - bbs_done > CLG_(clo).dump_every_bb) { 186 VG_(sprintf)(buf, "--dump-every-bb=%llu", CLG_(clo).dump_every_bb); 187 CLG_(dump_profile)(buf, False); 188 bbs_done = CLG_(stat).bb_executions; 189 } 190 } 191 192 CLG_(check_command)(); 193 194 /* now check for thread switch */ 195 CLG_(switch_thread)(tid); 196 } 197 198 void CLG_(pre_signal)(ThreadId tid, Int sigNum, Bool alt_stack) 199 { 200 exec_state *es; 201 202 CLG_DEBUG(0, ">> pre_signal(TID %d, sig %d, alt_st %s)\n", 203 tid, sigNum, alt_stack ? "yes":"no"); 204 205 /* switch to the thread the handler runs in */ 206 CLG_(switch_thread)(tid); 207 208 /* save current execution state */ 209 exec_state_save(); 210 211 /* setup new cxtinfo struct for this signal handler */ 212 es = push_exec_state(sigNum); 213 CLG_(zero_cost)( CLG_(sets).full, es->cost ); 214 CLG_(current_state).cost = es->cost; 215 es->call_stack_bottom = CLG_(current_call_stack).sp; 216 217 /* setup current state for a spontaneous call */ 218 CLG_(init_exec_state)( &CLG_(current_state) ); 219 CLG_(current_state).sig = sigNum; 220 CLG_(push_cxt)(0); 221 } 222 223 /* Run post-signal if the stackpointer for call stack is at 224 * the bottom in current exec state (e.g. a signal handler) 225 * 226 * Called from CLG_(pop_call_stack) 227 */ 228 void CLG_(run_post_signal_on_call_stack_bottom)() 229 { 230 exec_state* es = top_exec_state(); 231 CLG_ASSERT(es != 0); 232 CLG_ASSERT(CLG_(current_state).sig >0); 233 234 if (CLG_(current_call_stack).sp == es->call_stack_bottom) 235 CLG_(post_signal)( CLG_(current_tid), CLG_(current_state).sig ); 236 } 237 238 void CLG_(post_signal)(ThreadId tid, Int sigNum) 239 { 240 exec_state* es; 241 UInt fn_number, *pactive; 242 243 CLG_DEBUG(0, ">> post_signal(TID %d, sig %d)\n", 244 tid, sigNum); 245 246 /* thread switching potentially needed, eg. with instrumentation off */ 247 CLG_(switch_thread)(tid); 248 CLG_ASSERT(sigNum == CLG_(current_state).sig); 249 250 /* Unwind call stack of this signal handler. 251 * This should only be needed at finalisation time 252 */ 253 es = top_exec_state(); 254 CLG_ASSERT(es != 0); 255 while(CLG_(current_call_stack).sp > es->call_stack_bottom) 256 CLG_(pop_call_stack)(); 257 258 if (CLG_(current_state).cxt) { 259 /* correct active counts */ 260 fn_number = CLG_(current_state).cxt->fn[0]->number; 261 pactive = CLG_(get_fn_entry)(fn_number); 262 (*pactive)--; 263 CLG_DEBUG(0, " set active count of %s back to %d\n", 264 CLG_(current_state).cxt->fn[0]->name, *pactive); 265 } 266 267 if (CLG_(current_fn_stack).top > CLG_(current_fn_stack).bottom) { 268 /* set fn_stack_top back. 269 * top can point to 0 if nothing was executed in the signal handler; 270 * this is possible at end on unwinding handlers. 271 */ 272 if (*(CLG_(current_fn_stack).top) != 0) { 273 CLG_(current_fn_stack).top--; 274 CLG_ASSERT(*(CLG_(current_fn_stack).top) == 0); 275 } 276 if (CLG_(current_fn_stack).top > CLG_(current_fn_stack).bottom) 277 CLG_(current_fn_stack).top--; 278 } 279 280 /* sum up costs */ 281 CLG_ASSERT(CLG_(current_state).cost == es->cost); 282 CLG_(add_and_zero_cost)( CLG_(sets).full, 283 thread[CLG_(current_tid)]->sighandler_cost, 284 CLG_(current_state).cost ); 285 286 /* restore previous context */ 287 es->sig = -1; 288 current_states.sp--; 289 es = top_exec_state(); 290 CLG_(current_state).sig = es->sig; 291 exec_state_restore(); 292 293 /* There is no way to reliable get the thread ID we are switching to 294 * after this handler returns. So we sync with actual TID at start of 295 * CLG_(setup_bb)(), which should be the next for callgrind. 296 */ 297 } 298 299 300 301 /*------------------------------------------------------------*/ 302 /*--- Execution states in a thread & signal handlers ---*/ 303 /*------------------------------------------------------------*/ 304 305 /* Each thread can be interrupted by a signal handler, and they 306 * themselves again. But as there's no scheduling among handlers 307 * of the same thread, we don't need additional stacks. 308 * So storing execution contexts and 309 * adding separators in the callstack(needed to not intermix normal/handler 310 * functions in contexts) should be enough. 311 */ 312 313 /* not initialized: call_stack_bottom, sig */ 314 void CLG_(init_exec_state)(exec_state* es) 315 { 316 es->collect = CLG_(clo).collect_atstart; 317 es->cxt = 0; 318 es->jmps_passed = 0; 319 es->bbcc = 0; 320 es->nonskipped = 0; 321 } 322 323 324 static exec_state* new_exec_state(Int sigNum) 325 { 326 exec_state* es; 327 es = (exec_state*) CLG_MALLOC("cl.threads.nes.1", 328 sizeof(exec_state)); 329 330 /* allocate real cost space: needed as incremented by 331 * simulation functions */ 332 es->cost = CLG_(get_eventset_cost)(CLG_(sets).full); 333 CLG_(zero_cost)( CLG_(sets).full, es->cost ); 334 CLG_(init_exec_state)(es); 335 es->sig = sigNum; 336 es->call_stack_bottom = 0; 337 338 return es; 339 } 340 341 void CLG_(init_exec_stack)(exec_stack* es) 342 { 343 Int i; 344 345 /* The first element is for the main thread */ 346 es->entry[0] = new_exec_state(0); 347 for(i=1;i<MAX_SIGHANDLERS;i++) 348 es->entry[i] = 0; 349 es->sp = 0; 350 } 351 352 void CLG_(copy_current_exec_stack)(exec_stack* dst) 353 { 354 Int i; 355 356 dst->sp = current_states.sp; 357 for(i=0;i<MAX_SIGHANDLERS;i++) 358 dst->entry[i] = current_states.entry[i]; 359 } 360 361 void CLG_(set_current_exec_stack)(exec_stack* dst) 362 { 363 Int i; 364 365 current_states.sp = dst->sp; 366 for(i=0;i<MAX_SIGHANDLERS;i++) 367 current_states.entry[i] = dst->entry[i]; 368 } 369 370 371 /* Get top context info struct of current thread */ 372 static 373 exec_state* top_exec_state(void) 374 { 375 Int sp = current_states.sp; 376 exec_state* es; 377 378 CLG_ASSERT((sp >= 0) && (sp < MAX_SIGHANDLERS)); 379 es = current_states.entry[sp]; 380 CLG_ASSERT(es != 0); 381 return es; 382 } 383 384 /* Allocates a free context info structure for a new entered 385 * signal handler, putting it on the context stack. 386 * Returns a pointer to the structure. 387 */ 388 static exec_state* push_exec_state(int sigNum) 389 { 390 Int sp; 391 exec_state* es; 392 393 current_states.sp++; 394 sp = current_states.sp; 395 396 CLG_ASSERT((sigNum > 0) && (sigNum <= _VKI_NSIG)); 397 CLG_ASSERT((sp > 0) && (sp < MAX_SIGHANDLERS)); 398 es = current_states.entry[sp]; 399 if (!es) { 400 es = new_exec_state(sigNum); 401 current_states.entry[sp] = es; 402 } 403 else 404 es->sig = sigNum; 405 406 return es; 407 } 408 409 /* Save current context to top cxtinfo struct */ 410 static 411 exec_state* exec_state_save(void) 412 { 413 exec_state* es = top_exec_state(); 414 415 es->cxt = CLG_(current_state).cxt; 416 es->collect = CLG_(current_state).collect; 417 es->jmps_passed = CLG_(current_state).jmps_passed; 418 es->bbcc = CLG_(current_state).bbcc; 419 es->nonskipped = CLG_(current_state).nonskipped; 420 CLG_ASSERT(es->cost == CLG_(current_state).cost); 421 422 CLG_DEBUGIF(1) { 423 CLG_DEBUG(1, " cxtinfo_save(sig %d): collect %s, jmps_passed %d\n", 424 es->sig, es->collect ? "Yes": "No", es->jmps_passed); 425 CLG_(print_bbcc)(-9, es->bbcc); 426 CLG_(print_cost)(-9, CLG_(sets).full, es->cost); 427 } 428 429 /* signal number does not need to be saved */ 430 CLG_ASSERT(CLG_(current_state).sig == es->sig); 431 432 return es; 433 } 434 435 static 436 exec_state* exec_state_restore(void) 437 { 438 exec_state* es = top_exec_state(); 439 440 CLG_(current_state).cxt = es->cxt; 441 CLG_(current_state).collect = es->collect; 442 CLG_(current_state).jmps_passed = es->jmps_passed; 443 CLG_(current_state).bbcc = es->bbcc; 444 CLG_(current_state).nonskipped = es->nonskipped; 445 CLG_(current_state).cost = es->cost; 446 CLG_(current_state).sig = es->sig; 447 448 CLG_DEBUGIF(1) { 449 CLG_DEBUG(1, " exec_state_restore(sig %d): collect %s, jmps_passed %d\n", 450 es->sig, es->collect ? "Yes": "No", es->jmps_passed); 451 CLG_(print_bbcc)(-9, es->bbcc); 452 CLG_(print_cxt)(-9, es->cxt, 0); 453 CLG_(print_cost)(-9, CLG_(sets).full, es->cost); 454 } 455 456 return es; 457 } 458 459