aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--callgrind/main.c15
-rw-r--r--coregrind/m_scheduler/scheduler.c27
-rw-r--r--coregrind/m_tooliface.c2
-rw-r--r--coregrind/pub_core_tooliface.h2
-rw-r--r--include/pub_tool_tooliface.h14
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)