Commit 86e487a2 authored by simonmar's avatar simonmar

[project @ 2004-05-27 15:18:31 by simonmar]

Fix a nasty bug: when saving errno in the TSO after running a thread,
beware that the TSO might have moved, e.g. if the thread made a safe
foreign call in the threaded RTS and a GC happened.

We have to grab the new location of the TSO *before* saving errno.

MERGE TO STABLE

This was the most interesting bug hunt I've had in a while.  The crash
only showed up in about 1 in 4 runs of a program with 1000 Haskell
threads, running on the threaded RTS.  To make things worse, gdb
doesn't support watchpoints in programs with multiple threads... :-/
parent d2a09365
/* ---------------------------------------------------------------------------
* $Id: Schedule.c,v 1.196 2004/05/06 12:20:04 wolfgang Exp $
* $Id: Schedule.c,v 1.197 2004/05/27 15:18:31 simonmar Exp $
*
* (c) The GHC Team, 1998-2003
*
......@@ -395,7 +395,7 @@ schedule( StgMainThread *mainThread USED_WHEN_RTS_SUPPORTS_THREADS,
#endif
IF_DEBUG(scheduler, printAllThreads());
// IF_DEBUG(scheduler, printAllThreads());
#if defined(RTS_SUPPORTS_THREADS)
// Yield the capability to higher-priority tasks if necessary.
......@@ -897,23 +897,35 @@ run_thread:
/* Run the current thread
*/
prev_what_next = t->what_next;
errno = t->saved_errno;
switch (prev_what_next) {
case ThreadKilled:
case ThreadComplete:
/* Thread already finished, return to scheduler. */
ret = ThreadFinished;
break;
case ThreadRunGHC:
errno = t->saved_errno;
ret = StgRun((StgFunPtr) stg_returnToStackTop, &cap->r);
t->saved_errno = errno;
break;
case ThreadInterpret:
ret = interpretBCO(cap);
break;
default:
barf("schedule: invalid what_next field");
}
// The TSO might have moved, so find the new location:
t = cap->r.rCurrentTSO;
// And save the current errno in this thread.
t->saved_errno = errno;
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* Costs for the scheduler are assigned to CCS_SYSTEM */
......@@ -929,7 +941,6 @@ run_thread:
#elif !defined(GRAN) && !defined(PAR)
IF_DEBUG(scheduler,fprintf(stderr,"sched: "););
#endif
t = cap->r.rCurrentTSO;
#if defined(PAR)
/* HACK 675: if the last thread didn't yield, make sure to print a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment