|
From: <sv...@va...> - 2005-05-31 15:41:47
|
Author: sewardj
Date: 2005-05-31 16:41:42 +0100 (Tue, 31 May 2005)
New Revision: 3824
Modified:
trunk/coregrind/m_syscalls/syscalls-amd64-linux.c
Log:
Unbreak amd64 build.
Modified: trunk/coregrind/m_syscalls/syscalls-amd64-linux.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_syscalls/syscalls-amd64-linux.c 2005-05-31 13:08:03=
UTC (rev 3823)
+++ trunk/coregrind/m_syscalls/syscalls-amd64-linux.c 2005-05-31 15:41:42=
UTC (rev 3824)
@@ -30,6 +30,7 @@
=20
#include "core.h"
#include "ume.h" /* for jmp_with_stack */
+#include "pub_core_debuglog.h"
#include "pub_core_aspacemgr.h"
#include "pub_core_sigframe.h"
#include "pub_core_syscalls.h"
@@ -245,64 +246,116 @@
return ((Addr)p) - tst->os_state.valgrind_stack_base;
}
=20
-/*
- Allocate a stack for the main thread, and call VGA_(thread_wrapper)
- on that stack.
- */
-void VGA_(main_thread_wrapper)(ThreadId tid)
+
+/* Run a thread all the way to the end, then do appropriate exit actions
+ (this is the last-one-out-turn-off-the-lights bit).=20
+*/
+static void run_a_thread_NORETURN ( Word tidW )
{
- UWord* rsp =3D allocstack(tid);
+ ThreadId tid =3D (ThreadId)tidW;
=20
- vg_assert(tid =3D=3D VG_(master_tid));
+ VG_(debugLog)(1, "syscalls-x86-linux",=20
+ "run_a_thread_NORETURN(tid=3D%lld): "
+ "VGO_(thread_wrapper) called\n",
+ (ULong)tidW);
=20
- call_on_new_stack_0_1(=20
- (Addr)rsp, /* stack */
- 0, /*bogus return address*/
- VGA_(thread_wrapper), /* fn to call */
- (Word)tid /* arg to give it */
- );
+ /* Run the thread all the way through. */
+ VgSchedReturnCode src =3D VGO_(thread_wrapper)(tid); =20
=20
+ VG_(debugLog)(1, "syscalls-x86-linux",=20
+ "run_a_thread_NORETURN(tid=3D%lld): "
+ "VGO_(thread_wrapper) done\n",
+ (ULong)tidW);
+
+ Int c =3D VG_(count_living_threads)();
+ vg_assert(c >=3D 1); /* stay sane */
+
+ if (c =3D=3D 1) {
+
+ VG_(debugLog)(1, "syscalls-x86-linux",=20
+ "run_a_thread_NORETURN(tid=3D%lld): "
+ "last one standing\n",
+ (ULong)tidW);
+
+ /* We are the last one standing. Keep hold of the lock and
+ carry on to show final tool results, then exit the entire syste=
m. */
+ VG_(shutdown_actions_NORETURN)(tid, src);
+
+ } else {
+
+ VG_(debugLog)(1, "syscalls-x86-linux",=20
+ "run_a_thread_NORETURN(tid=3D%lld): "
+ "not last one standing\n",
+ (ULong)tidW);
+
+ /* OK, thread is dead, but others still exist. Just exit. */
+ ThreadState *tst =3D VG_(get_ThreadState)(tid);
+
+ /* This releases the run lock */
+ VG_(exit_thread)(tid);
+ vg_assert(tst->status =3D=3D VgTs_Zombie);
+
+ /* We have to use this sequence to terminate the thread to
+ prevent a subtle race. If VG_(exit_thread)() had left the
+ ThreadState as Empty, then it could have been reallocated,
+ reusing the stack while we're doing these last cleanups.
+ Instead, VG_(exit_thread) leaves it as Zombie to prevent
+ reallocation. We need to make sure we don't touch the stack
+ between marking it Empty and exiting. Hence the
+ assembler. */
+ asm volatile (
+ "movl %1, %0\n" /* set tst->status =3D VgTs_Empty */
+ "movq %2, %%rax\n" /* set %rax =3D __NR_exit */
+ "movq %3, %%rdi\n" /* set %rdi =3D tst->os_state.exitcode */
+ "syscall\n" /* exit(tst->os_state.exitcode) */
+ : "=3Dm" (tst->status)
+ : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcod=
e));
+
+ VG_(core_panic)("Thread exit failed?\n");
+ }
+
/*NOTREACHED*/
vg_assert(0);
}
=20
-static Int start_thread(void *arg)
+
+/*
+ Allocate a stack for the main thread, and run it all the way to the
+ end. =20
+*/
+void VGP_(main_thread_wrapper_NORETURN)(ThreadId tid)
{
- ThreadState *tst =3D (ThreadState *)arg;
- ThreadId tid =3D tst->tid;
+ VG_(debugLog)(1, "syscalls-amd64-linux",=20
+ "entering VGP_(main_thread_wrapper_NORETURN)\n");
=20
- VGA_(thread_wrapper)(tid);
+ UWord* rsp =3D allocstack(tid);
=20
- /* OK, thread is dead; this releases the run lock */
- VG_(exit_thread)(tid);
+ /* shouldn't be any other threads around yet */
+ vg_assert( VG_(count_living_threads)() =3D=3D 1 );
=20
- vg_assert(tst->status =3D=3D VgTs_Zombie);
+ call_on_new_stack_0_1(=20
+ (Addr)rsp, /* stack */
+ 0, /*bogus return address*/
+ run_a_thread_NORETURN, /* fn to call */
+ (Word)tid /* arg to give it */
+ );
=20
- /* Poke the reaper */
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "Sending SIGVGCHLD to master tid=3D%d lw=
p=3D%d",=20
- VG_(master_tid), VG_(threads)[VG_(master_tid)].os_state.lwpid);
+ /*NOTREACHED*/
+ vg_assert(0);
+}
=20
- VG_(tkill)(VG_(threads)[VG_(master_tid)].os_state.lwpid, VKI_SIGVGCHL=
D);
=20
- /* We have to use this sequence to terminate the thread to prevent
- a subtle race. If VG_(exit_thread)() had left the ThreadState
- as Empty, then it could have been reallocated, reusing the stack
- while we're doing these last cleanups. Instead,
- VG_(exit_thread) leaves it as Zombie to prevent reallocation.
- We need to make sure we don't touch the stack between marking it
- Empty and exiting. Hence the assembler. */
- asm volatile (
- "movl %1, %0\n" /* set tst->status =3D VgTs_Empty */
- "movq %2, %%rax\n" /* set %rax =3D __NR_exit */
- "movq %3, %%rdi\n" /* set %rdi =3D tst->os_state.exitcode */
- "syscall\n" /* exit(tst->os_state.exitcode) */
- : "=3Dm" (tst->status)
- : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode))=
;
+static Int start_thread_NORETURN ( void* arg )
+{
+ ThreadState* tst =3D (ThreadState*)arg;
+ ThreadId tid =3D tst->tid;
=20
- VG_(core_panic)("Thread exit failed?\n");
+ run_a_thread_NORETURN ( (Word)tid );
+ /*NOTREACHED*/
+ vg_assert(0);
}
=20
+
/* ---------------------------------------------------------------------
clone() handling
------------------------------------------------------------------ */
@@ -398,7 +451,7 @@
VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
=20
/* Create the new thread */
- ret =3D VG_(clone)(start_thread, stack, flags, &VG_(threads)[ctid],
+ ret =3D VG_(clone)(start_thread_NORETURN, stack, flags, &VG_(threads)=
[ctid],
child_tidptr, parent_tidptr, NULL);
=20
VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
|