Merge patch from Jeremy Fitzhardinge:

13-kill-1ifroot
  Kill VG_(get_current_tid_1_if_root)() and replace it with the slightly
  more appetising (though still hackish)
  VG_(get_current_or_recent_tid)(). This is intended for use when
  there's no thread actually loaded into the baseblock, but we're doing
  work on behalf of the the thread that was last running (such as during
  a syscall).

  This probably fixes a bug with helgrind misattributing memory created
  with mmap to thread 1 rather than the thread which called mmap (though
  the behaviour is still probably wrong: mmapped memory should be
  magically_inited).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1262 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c
index 60eb0b8..59804c4 100644
--- a/coregrind/vg_scheduler.c
+++ b/coregrind/vg_scheduler.c
@@ -95,6 +95,10 @@
 /* The tid of the thread currently in VG_(baseBlock). */
 static Int vg_tid_currently_in_baseBlock = VG_INVALID_THREADID;
 
+/* The tid either currently in baseBlock, or was in baseBlock before
+   was saved it out; this is only updated when a new thread is loaded
+   into the baseBlock */
+static Int vg_tid_last_in_baseBlock = VG_INVALID_THREADID;
 
 /* vg_oursignalhandler() might longjmp().  Here's the jmp_buf. */
 jmp_buf VG_(scheduler_jmpbuf);
@@ -376,17 +380,18 @@
 
 ThreadId VG_(get_current_tid) ( void )
 {
-   vg_assert(VG_(is_valid_tid)(vg_tid_currently_in_baseBlock));
+   if (!VG_(is_valid_tid)(vg_tid_currently_in_baseBlock))
+      return VG_INVALID_THREADID;
    return vg_tid_currently_in_baseBlock;
 }
 
-ThreadId VG_(get_current_tid_1_if_root) ( void )
+ThreadId VG_(get_current_or_recent_tid) ( void )
 {
-   if (0 == vg_tid_currently_in_baseBlock)
-      return 1;     /* root thread */
-    
-   vg_assert(VG_(is_valid_tid)(vg_tid_currently_in_baseBlock));
-   return vg_tid_currently_in_baseBlock;
+   vg_assert(vg_tid_currently_in_baseBlock == vg_tid_last_in_baseBlock ||
+	     vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
+   vg_assert(VG_(is_valid_tid)(vg_tid_last_in_baseBlock));
+
+   return vg_tid_last_in_baseBlock;
 }
 
 ThreadId VG_(get_tid_from_ThreadState) (ThreadState* tst)
@@ -453,6 +458,7 @@
    }
 
    vg_tid_currently_in_baseBlock = tid;
+   vg_tid_last_in_baseBlock = tid;
 }
 
 
@@ -693,6 +699,7 @@
 
    /* Copy VG_(baseBlock) state to tid_main's slot. */
    vg_tid_currently_in_baseBlock = tid_main;
+   vg_tid_last_in_baseBlock = tid_main;
    VG_(save_thread_state) ( tid_main );
 
    VG_(threads)[tid_main].stack_highest_word 
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index af73e98..8d0b0e7 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -287,8 +287,10 @@
 void init_nonvirgin_sword(Addr a)
 {
    shadow_word sword;
+   ThreadId tid = VG_(get_current_or_recent_tid)();
 
-   sword.other = VG_(get_current_tid_1_if_root)();
+   sk_assert(tid != VG_INVALID_THREADID);
+   sword.other = tid;
    sword.state = Vge_Excl;
    set_sword(a, sword);
 }
@@ -303,7 +305,7 @@
 {
    shadow_word sword;
 
-   sk_assert(1 == VG_(get_current_tid_1_if_root)());
+   sk_assert(VG_INVALID_THREADID == VG_(get_current_tid)());
    sword.other = TID_INDICATING_NONVIRGIN;
    sword.state = Vge_Virgin;
    set_sword(a, virgin_sword);
diff --git a/include/vg_skin.h b/include/vg_skin.h
index b87f477..4a06bee 100644
--- a/include/vg_skin.h
+++ b/include/vg_skin.h
@@ -254,7 +254,7 @@
    ThreadState;
 
 extern ThreadId     VG_(get_current_tid)           ( void );
-extern ThreadId     VG_(get_current_tid_1_if_root) ( void );
+extern ThreadId     VG_(get_current_or_recent_tid) ( void );
 extern ThreadId     VG_(get_tid_from_ThreadState)  ( ThreadState* );
 extern ThreadState* VG_(get_ThreadState)           ( ThreadId tid );