void discardTasksExcept (Task *keep) { Task *task, *next; // Wipe the task list, except the current Task. ACQUIRE_LOCK(&all_tasks_mutex); for (task = all_tasks; task != NULL; task=next) { next = task->all_next; if (task != keep) { debugTrace(DEBUG_sched, "discarding task %ld", (long)TASK_ID(task)); freeTask(task); } } all_tasks = keep; keep->all_next = NULL; keep->all_prev = NULL; RELEASE_LOCK(&all_tasks_mutex); }
void discardTasksExcept (Task *keep) { Task *task, *next; // Wipe the task list, except the current Task. ACQUIRE_LOCK(&all_tasks_mutex); for (task = all_tasks; task != NULL; task=next) { next = task->all_next; if (task != keep) { debugTrace(DEBUG_sched, "discarding task %" FMT_SizeT "", (size_t)TASK_ID(task)); #if defined(THREADED_RTS) // It is possible that some of these tasks are currently blocked // (in the parent process) either on their condition variable // `cond` or on their mutex `lock`. If they are we may deadlock // when `freeTask` attempts to call `closeCondition` or // `closeMutex` (the behaviour of these functions is documented to // be undefined in the case that there are threads blocked on // them). To avoid this, we re-initialize both the condition // variable and the mutex before calling `freeTask` (we do // precisely the same for all global locks in `forkProcess`). initCondition(&task->cond); initMutex(&task->lock); #endif // Note that we do not traceTaskDelete here because // we are not really deleting a task. // The OS threads for all these tasks do not exist in // this process (since we're currently // in the child of a forkProcess). freeTask(task); } } all_tasks = keep; keep->all_next = NULL; keep->all_prev = NULL; RELEASE_LOCK(&all_tasks_mutex); }
void discardTasksExcept (Task *keep) { Task *task, *next; // Wipe the task list, except the current Task. ACQUIRE_LOCK(&all_tasks_mutex); for (task = all_tasks; task != NULL; task=next) { next = task->all_next; if (task != keep) { debugTrace(DEBUG_sched, "discarding task %" FMT_SizeT "", (size_t)TASK_ID(task)); // Note that we do not traceTaskDelete here because // we are not really deleting a task. // The OS threads for all these tasks do not exist in // this process (since we're currently // in the child of a forkProcess). freeTask(task); } } all_tasks = keep; keep->all_next = NULL; keep->all_prev = NULL; RELEASE_LOCK(&all_tasks_mutex); }