| ... |
... |
@@ -2051,7 +2051,26 @@ forkProcess(HsStablePtr *entry |
|
2051
|
2051
|
waitForCapability(&cap, task);
|
|
2052
|
2052
|
|
|
2053
|
2053
|
#if defined(THREADED_RTS)
|
|
2054
|
|
- stopAllCapabilities(&cap, task);
|
|
|
2054
|
+ while (true) {
|
|
|
2055
|
+ stopAllCapabilities(&cap, task);
|
|
|
2056
|
+
|
|
|
2057
|
+ // The nonmoving collector's worker is not copied by fork(). Only
|
|
|
2058
|
+ // proceed when it is idle, keeping its lock held to prevent another
|
|
|
2059
|
+ // collection from starting before the fork. We must not wait for an
|
|
|
2060
|
+ // active mark while holding capabilities since the mark may need to
|
|
|
2061
|
+ // synchronize with the mutator before it can finish.
|
|
|
2062
|
+ if (nonmovingBlockConcurrentMark(false)) {
|
|
|
2063
|
+ break;
|
|
|
2064
|
+ }
|
|
|
2065
|
+
|
|
|
2066
|
+ releaseAllCapabilities(n_capabilities, NULL, task);
|
|
|
2067
|
+ CHECK(nonmovingBlockConcurrentMark(true));
|
|
|
2068
|
+ nonmovingUnblockConcurrentMark();
|
|
|
2069
|
+ cap = NULL;
|
|
|
2070
|
+ waitForCapability(&cap, task);
|
|
|
2071
|
+ }
|
|
|
2072
|
+#else
|
|
|
2073
|
+ CHECK(nonmovingBlockConcurrentMark(false));
|
|
2055
|
2074
|
#endif
|
|
2056
|
2075
|
|
|
2057
|
2076
|
// no funny business: hold locks while we fork, otherwise if some
|
| ... |
... |
@@ -2089,6 +2108,8 @@ forkProcess(HsStablePtr *entry |
|
2089
|
2108
|
|
|
2090
|
2109
|
if (pid) { // parent
|
|
2091
|
2110
|
|
|
|
2111
|
+ nonmovingUnblockConcurrentMark();
|
|
|
2112
|
+
|
|
2092
|
2113
|
RELEASE_LOCK(&sched_mutex);
|
|
2093
|
2114
|
RELEASE_LOCK(&sm_mutex);
|
|
2094
|
2115
|
RELEASE_LOCK(&stable_ptr_mutex);
|
| ... |
... |
@@ -2213,6 +2234,10 @@ forkProcess(HsStablePtr *entry |
|
2213
|
2234
|
generations[g].threads = END_TSO_QUEUE;
|
|
2214
|
2235
|
}
|
|
2215
|
2236
|
|
|
|
2237
|
+ // The persistent nonmoving collector worker is an OS thread and was
|
|
|
2238
|
+ // not copied by fork(). Recreate it before running the child action.
|
|
|
2239
|
+ nonmovingInitAfterFork();
|
|
|
2240
|
+
|
|
2216
|
2241
|
// The timer thread is not present in the child process, so we need
|
|
2217
|
2242
|
// to initialise the timer again.
|
|
2218
|
2243
|
initTimer();
|