diff options
-rw-r--r-- | callgrind/main.c | 15 | ||||
-rw-r--r-- | coregrind/m_scheduler/scheduler.c | 27 | ||||
-rw-r--r-- | coregrind/m_tooliface.c | 2 | ||||
-rw-r--r-- | coregrind/pub_core_tooliface.h | 2 | ||||
-rw-r--r-- | include/pub_tool_tooliface.h | 14 |
5 files changed, 49 insertions, 11 deletions
diff --git a/callgrind/main.c b/callgrind/main.c index 4bae4e022..b54b72cc4 100644 --- a/callgrind/main.c +++ b/callgrind/main.c @@ -1022,6 +1022,19 @@ void CLG_(fini)(Int exitcode) /*--- Setup ---*/ /*--------------------------------------------------------------------*/ +static void clg_thread_runstate_callback ( ThreadId tid, + Bool is_running, + ULong blocks_done ) +{ + if (0) + VG_(printf)("%d %c %llu\n", + (Int)tid, is_running ? 'R' : 's', blocks_done); + /* Simply call onwards to CLG_(run_thread). Maybe this can be + simplified later? */ + if (is_running) + CLG_(run_thread)( tid ); +} + static void CLG_(post_clo_init)(void) { @@ -1088,7 +1101,7 @@ void CLG_(pre_clo_init)(void) VG_(needs_syscall_wrapper)(CLG_(pre_syscalltime), CLG_(post_syscalltime)); - VG_(track_thread_run) ( & CLG_(run_thread) ); + VG_(track_thread_runstate) ( & clg_thread_runstate_callback ); VG_(track_pre_deliver_signal) ( & CLG_(pre_signal) ); VG_(track_post_deliver_signal) ( & CLG_(post_signal) ); diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index e439e4994..27bff8989 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -233,10 +233,6 @@ void VG_(acquire_BigLock)(ThreadId tid, HChar* who) VG_(sprintf)(buf, " acquired lock (%s)", who); print_sched_event(tid, buf); } - - // While thre modeling is disable, issue thread_run events here - // VG_(tm_thread_switchto)(tid); - VG_TRACK( thread_run, tid ); } /* @@ -616,6 +612,9 @@ static UInt run_thread_for_a_while ( ThreadId tid ) VG_(printf)("\n"); } + // Tell the tool this thread is about to run client code + VG_TRACK( thread_runstate, tid, True, bbs_done ); + vg_assert(VG_(in_generated_code) == False); VG_(in_generated_code) = True; @@ -641,6 +640,9 @@ static UInt run_thread_for_a_while ( ThreadId tid ) vg_assert(done_this_time >= 0); bbs_done += (ULong)done_this_time; + // Tell the tool this thread has stopped running client code + VG_TRACK( thread_runstate, tid, False, bbs_done ); + return trc; } @@ -652,6 +654,7 @@ static UInt run_noredir_translation ( Addr hcode, ThreadId tid ) volatile Int jumped; volatile ThreadState* tst; volatile UWord argblock[4]; + volatile UInt retval; /* Paranoia */ vg_assert(VG_(is_valid_tid)(tid)); @@ -686,6 +689,9 @@ static UInt run_noredir_translation ( Addr hcode, ThreadId tid ) argblock[2] = 0; /* next guest IP is written here */ argblock[3] = 0; /* guest state ptr afterwards is written here */ + // Tell the tool this thread is about to run client code + VG_TRACK( thread_runstate, tid, True, bbs_done ); + vg_assert(VG_(in_generated_code) == False); VG_(in_generated_code) = True; @@ -703,16 +709,23 @@ static UInt run_noredir_translation ( Addr hcode, ThreadId tid ) vg_assert(argblock[2] == 0); /* next guest IP was not written */ vg_assert(argblock[3] == 0); /* trc was not written */ block_signals(tid); - return VG_TRC_FAULT_SIGNAL; + retval = VG_TRC_FAULT_SIGNAL; } else { /* store away the guest program counter */ VG_(set_IP)( tid, argblock[2] ); if (argblock[3] == argblock[1]) /* the guest state pointer afterwards was unchanged */ - return VG_TRC_BORING; + retval = VG_TRC_BORING; else - return (UInt)argblock[3]; + retval = (UInt)argblock[3]; } + + bbs_done++; + + // Tell the tool this thread has stopped running client code + VG_TRACK( thread_runstate, tid, False, bbs_done ); + + return retval; } diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c index 843ac5b10..4dbf196ca 100644 --- a/coregrind/m_tooliface.c +++ b/coregrind/m_tooliface.c @@ -321,7 +321,7 @@ DEF(track_post_reg_write, CorePart, ThreadId, OffT, SizeT) DEF(track_post_reg_write_clientcall_return, ThreadId, OffT, SizeT, Addr) -DEF(track_thread_run, ThreadId) +DEF(track_thread_runstate, ThreadId, Bool, ULong) DEF(track_post_thread_create, ThreadId, ThreadId) DEF(track_post_thread_join, ThreadId, ThreadId) diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h index bde51bdef..603dee1d3 100644 --- a/coregrind/pub_core_tooliface.h +++ b/coregrind/pub_core_tooliface.h @@ -200,7 +200,7 @@ typedef struct { void (*track_post_reg_write)(CorePart, ThreadId, OffT, SizeT); void (*track_post_reg_write_clientcall_return)(ThreadId, OffT, SizeT, Addr); - void (*track_thread_run)(ThreadId); + void (*track_thread_runstate)(ThreadId, Bool, ULong); void (*track_post_thread_create)(ThreadId, ThreadId); void (*track_post_thread_join) (ThreadId, ThreadId); diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h index be530a4b1..a3f1b6ce4 100644 --- a/include/pub_tool_tooliface.h +++ b/include/pub_tool_tooliface.h @@ -537,7 +537,19 @@ void VG_(track_post_reg_write_clientcall_return)( /* Scheduler events (not exhaustive) */ -void VG_(track_thread_run)(void(*f)(ThreadId tid)); + +/* Called when 'tid' starts or stops running client code blocks. + Gives the total dispatched block count at that event. Note, this + is not the same as 'tid' holding the BigLock: a thread can hold the + lock for other purposes (making translations, etc) yet not be + running client blocks. Obviously though, a thread must hold the + lock in order to run client code blocks, so the times bracketed by + thread_runstate(tid, True, ..) .. thread_runstate(tid, False, ..) + are a subset of the times when 'tid' holds the cpu lock. +*/ +void VG_(track_thread_runstate)( + void(*f)(ThreadId tid, Bool running, ULong blocks_dispatched) + ); /* Thread events (not exhaustive) |