projects
/
ghc-hetmet.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Redesign 64-bit HEAP_ALLOCED (FIX #2934 at the same time)
[ghc-hetmet.git]
/
rts
/
Schedule.c
diff --git
a/rts/Schedule.c
b/rts/Schedule.c
index
9baf755
..
28e54f9
100644
(file)
--- a/
rts/Schedule.c
+++ b/
rts/Schedule.c
@@
-32,6
+32,7
@@
#include "Proftimer.h"
#include "ProfHeap.h"
#include "GC.h"
#include "Proftimer.h"
#include "ProfHeap.h"
#include "GC.h"
+#include "Weak.h"
/* PARALLEL_HASKELL includes go here */
/* PARALLEL_HASKELL includes go here */
@@
-281,6
+282,12
@@
schedule (Capability *initialCapability, Task *task)
"### NEW SCHEDULER LOOP (task: %p, cap: %p)",
task, initialCapability);
"### NEW SCHEDULER LOOP (task: %p, cap: %p)",
task, initialCapability);
+ if (running_finalizers) {
+ errorBelch("error: a C finalizer called back into Haskell.\n"
+ " use Foreign.Concurrent.newForeignPtr for Haskell finalizers.");
+ stg_exit(EXIT_FAILURE);
+ }
+
schedulePreLoop();
// -----------------------------------------------------------
schedulePreLoop();
// -----------------------------------------------------------
@@
-737,6
+744,7
@@
scheduleYield (Capability **pcap, Task *task)
// if we have work, and we don't need to give up the Capability, continue.
if (!shouldYieldCapability(cap,task) &&
(!emptyRunQueue(cap) ||
// if we have work, and we don't need to give up the Capability, continue.
if (!shouldYieldCapability(cap,task) &&
(!emptyRunQueue(cap) ||
+ !emptyWakeupQueue(cap) ||
blackholes_need_checking ||
sched_state >= SCHED_INTERRUPTING))
return;
blackholes_need_checking ||
sched_state >= SCHED_INTERRUPTING))
return;
@@
-1403,10
+1411,9
@@
scheduleHandleThreadFinished (Capability *cap STG_UNUSED, Task *task, StgTSO *t)
(unsigned long)t->id, whatNext_strs[t->what_next]);
// blocked exceptions can now complete, even if the thread was in
(unsigned long)t->id, whatNext_strs[t->what_next]);
// blocked exceptions can now complete, even if the thread was in
- // blocked mode (see #2910). The thread is already marked
- // ThreadComplete, so any further throwTos will complete
- // immediately and we don't need to worry about synchronising with
- // those.
+ // blocked mode (see #2910). This unconditionally calls
+ // lockTSO(), which ensures that we don't miss any threads that
+ // are engaged in throwTo() with this thread as a target.
awakenBlockedExceptionQueue (cap, t);
//
awakenBlockedExceptionQueue (cap, t);
//
@@
-1988,7
+1995,10
@@
resumeThread (void *task_)
debugTrace(DEBUG_sched, "thread %lu: re-entering RTS", (unsigned long)tso->id);
if (tso->why_blocked == BlockedOnCCall) {
debugTrace(DEBUG_sched, "thread %lu: re-entering RTS", (unsigned long)tso->id);
if (tso->why_blocked == BlockedOnCCall) {
- awakenBlockedExceptionQueue(cap,tso);
+ // avoid locking the TSO if we don't have to
+ if (tso->blocked_exceptions != END_TSO_QUEUE) {
+ awakenBlockedExceptionQueue(cap,tso);
+ }
tso->flags &= ~(TSO_BLOCKEX | TSO_INTERRUPTIBLE);
}
tso->flags &= ~(TSO_BLOCKEX | TSO_INTERRUPTIBLE);
}
@@
-2193,22
+2203,16
@@
exitScheduler(
{
Task *task = NULL;
{
Task *task = NULL;
-#if defined(THREADED_RTS)
ACQUIRE_LOCK(&sched_mutex);
task = newBoundTask();
RELEASE_LOCK(&sched_mutex);
ACQUIRE_LOCK(&sched_mutex);
task = newBoundTask();
RELEASE_LOCK(&sched_mutex);
-#endif
// If we haven't killed all the threads yet, do it now.
if (sched_state < SCHED_SHUTTING_DOWN) {
sched_state = SCHED_INTERRUPTING;
// If we haven't killed all the threads yet, do it now.
if (sched_state < SCHED_SHUTTING_DOWN) {
sched_state = SCHED_INTERRUPTING;
-#if defined(THREADED_RTS)
waitForReturnCapability(&task->cap,task);
scheduleDoGC(task->cap,task,rtsFalse);
releaseCapability(task->cap);
waitForReturnCapability(&task->cap,task);
scheduleDoGC(task->cap,task,rtsFalse);
releaseCapability(task->cap);
-#else
- scheduleDoGC(&MainCapability,task,rtsFalse);
-#endif
}
sched_state = SCHED_SHUTTING_DOWN;
}
sched_state = SCHED_SHUTTING_DOWN;