much neater.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2542
extern void VG_(pp_sched_status) ( void );
-/* vg_oursignalhandler() might longjmp(). Here's the jmp_buf. */
-extern jmp_buf VG_(scheduler_jmpbuf);
-/* This says whether scheduler_jmpbuf is actually valid. Needed so
- that our signal handler doesn't longjmp when the buffer isn't
- actually valid. */
-extern Bool VG_(scheduler_jmpbuf_valid);
-/* ... and if so, here's the signal which caused it to do so. */
-extern Int VG_(longjmpd_on_signal);
-
+// Longjmp back to the scheduler and thus enter the sighandler immediately.
+extern void VG_(resume_scheduler) ( Int sigNo, vki_ksiginfo_t *info );
/* The red-zone size which we put at the bottom (highest address) of
thread stacks, for paranoia reasons. This can be arbitrary, and
static ThreadId vg_tid_last_in_baseBlock = VG_INVALID_THREADID;
/* vg_oursignalhandler() might longjmp(). Here's the jmp_buf. */
-jmp_buf VG_(scheduler_jmpbuf);
+jmp_buf scheduler_jmpbuf;
/* This says whether scheduler_jmpbuf is actually valid. Needed so
that our signal handler doesn't longjmp when the buffer isn't
actually valid. */
-Bool VG_(scheduler_jmpbuf_valid) = False;
+Bool scheduler_jmpbuf_valid = False;
/* ... and if so, here's the signal which caused it to do so. */
-Int VG_(longjmpd_on_signal);
+Int longjmpd_on_signal;
/* If the current thread gets a syncronous unresumable signal, then
its details are placed here by the signal handler, to be passed to
the applications signal handler later on. */
}
+void VG_(resume_scheduler)(Int sigNo, vki_ksiginfo_t *info)
+{
+ if (scheduler_jmpbuf_valid) {
+ /* Can't continue; must longjmp back to the scheduler and thus
+ enter the sighandler immediately. */
+ VG_(memcpy)(&VG_(unresumable_siginfo), info, sizeof(vki_ksiginfo_t));
+
+ longjmpd_on_signal = sigNo;
+ __builtin_longjmp(scheduler_jmpbuf,1);
+ }
+}
+
/* Run the thread tid for a while, and return a VG_TRC_* value to the
scheduler indicating what happened. */
static
volatile UInt trc = 0;
vg_assert(VG_(is_valid_tid)(tid));
vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
- vg_assert(!VG_(scheduler_jmpbuf_valid));
+ vg_assert(!scheduler_jmpbuf_valid);
VGP_PUSHCC(VgpRun);
VG_(load_thread_state) ( tid );
/* there should be no undealt-with signals */
vg_assert(VG_(unresumable_siginfo).si_signo == 0);
- if (__builtin_setjmp(VG_(scheduler_jmpbuf)) == 0) {
+ if (__builtin_setjmp(scheduler_jmpbuf) == 0) {
/* try this ... */
- VG_(scheduler_jmpbuf_valid) = True;
+ scheduler_jmpbuf_valid = True;
trc = VG_(run_innerloop)();
- VG_(scheduler_jmpbuf_valid) = False;
+ scheduler_jmpbuf_valid = False;
/* We get here if the client didn't take a fault. */
} else {
/* We get here if the client took a fault, which caused our
signal handler to longjmp. */
- VG_(scheduler_jmpbuf_valid) = False;
+ scheduler_jmpbuf_valid = False;
vg_assert(trc == 0);
trc = VG_TRC_UNRESUMABLE_SIGNAL;
}
- vg_assert(!VG_(scheduler_jmpbuf_valid));
+ vg_assert(!scheduler_jmpbuf_valid);
VG_(save_thread_state) ( tid );
VGP_POPCC(VgpRun);
vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
/* Not running client code right now. */
- VG_(scheduler_jmpbuf_valid) = False;
+ scheduler_jmpbuf_valid = False;
/* Proxy for main thread */
VG_(proxy_create)(tid_main);
VG_(unresumable_siginfo).si_signo == VKI_SIGBUS ||
VG_(unresumable_siginfo).si_signo == VKI_SIGILL ||
VG_(unresumable_siginfo).si_signo == VKI_SIGFPE);
- vg_assert(VG_(longjmpd_on_signal) == VG_(unresumable_siginfo).si_signo);
+ vg_assert(longjmpd_on_signal == VG_(unresumable_siginfo).si_signo);
/* make sure we've unblocked the signals which the handler blocked */
- VG_(unblock_host_signal)(VG_(longjmpd_on_signal));
+ VG_(unblock_host_signal)(longjmpd_on_signal);
VG_(deliver_signal)(tid, &VG_(unresumable_siginfo), False);
VG_(unresumable_siginfo).si_signo = 0; /* done */
with shared signal state (Linux 2.5+, RedHat's 2.4), then these are
the only signals it needs to handle.
- If we get a synchronous signal, the details are placed into
- VG_(unresumable_siginfo) and we longjmp back into the scheduler,
+ If we get a synchronous signal, we longjmp back into the scheduler,
since we can't resume executing the client code. The scheduler
immediately starts signal delivery to the thread which generated
the signal.
static void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
static void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
static void proxy_sigvg_handler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
-static void resume_scheduler(Int signo, vki_ksiginfo_t *info);
static Bool is_correct_sigmask(void);
static const Char *signame(Int sigNo);
info.si_code = 2;
info._sifields._sigfault._addr = (void*)addr;
- resume_scheduler(VKI_SIGSEGV, &info);
+ VG_(resume_scheduler)(VKI_SIGSEGV, &info);
VG_(deliver_signal)(tid, &info, False);
}
info.si_code = 1;
info._sifields._sigfault._addr = (void*)addr;
- resume_scheduler(VKI_SIGSEGV, &info);
+ VG_(resume_scheduler)(VKI_SIGSEGV, &info);
VG_(deliver_signal)(tid, &info, False);
}
info.si_code = 0x80;
info._sifields._sigfault._addr = (void*)0;
- resume_scheduler(VKI_SIGSEGV, &info);
+ VG_(resume_scheduler)(VKI_SIGSEGV, &info);
VG_(deliver_signal)(tid, &info, False);
}
VG_(proxy_handlesig)(info, &uc->uc_mcontext);
}
-static void resume_scheduler(Int sigNo, vki_ksiginfo_t *info)
-{
- if (VG_(scheduler_jmpbuf_valid)) {
- /* Can't continue; must longjmp back to the scheduler and thus
- enter the sighandler immediately. */
- VG_(memcpy)(&VG_(unresumable_siginfo), info, sizeof(vki_ksiginfo_t));
-
- VG_(longjmpd_on_signal) = sigNo;
- __builtin_longjmp(VG_(scheduler_jmpbuf),1);
- }
-}
-
/*
Recieve a sync signal from the host.
/* Can't continue; must longjmp back to the scheduler and thus
enter the sighandler immediately. */
- resume_scheduler(sigNo, info);
+ VG_(resume_scheduler)(sigNo, info);
if (info->si_code <= VKI_SI_USER) {
/*