We use only a single condition variable (instead of thread different
ones) for wait_for_child(), which is notified when any job control condition (child dead, stopped, continued) occurs. These events are relatively rare anyway, and it simplifies the code. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25079 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -138,11 +138,11 @@ struct job_control_entry : DoublyLinkedListLinkImpl<job_control_entry> {
|
||||
typedef DoublyLinkedList<job_control_entry> JobControlEntryList;
|
||||
|
||||
struct team_job_control_children {
|
||||
ConditionVariable<team_job_control_children> condition_variable;
|
||||
JobControlEntryList entries;
|
||||
JobControlEntryList entries;
|
||||
};
|
||||
|
||||
struct team_dead_children : team_job_control_children {
|
||||
ConditionVariable<team_dead_children> condition_variable;
|
||||
uint32 count;
|
||||
bigtime_t kernel_time;
|
||||
bigtime_t user_time;
|
||||
|
||||
@@ -883,11 +883,7 @@ create_team_struct(const char *name, bool kernel)
|
||||
|
||||
// publish dead/stopped/continued children condition vars
|
||||
team->dead_children->condition_variable.Publish(team->dead_children,
|
||||
"dead children");
|
||||
team->stopped_children->condition_variable.Publish(team->stopped_children,
|
||||
"stopped children");
|
||||
team->continued_children->condition_variable.Publish(
|
||||
team->continued_children, "continued children");
|
||||
"team children");
|
||||
|
||||
// keep all allocated structures
|
||||
jobControlEntryDeleter.Detach();
|
||||
@@ -903,9 +899,6 @@ create_team_struct(const char *name, bool kernel)
|
||||
static void
|
||||
delete_team_struct(struct team *team)
|
||||
{
|
||||
team->stopped_children->condition_variable.Unpublish();
|
||||
team->continued_children->condition_variable.Unpublish();
|
||||
|
||||
team->dead_children->condition_variable.Unpublish();
|
||||
|
||||
while (death_entry* threadDeathEntry = (death_entry*)list_remove_head_item(
|
||||
@@ -1748,23 +1741,12 @@ wait_for_child(pid_t child, uint32 flags, int32 *_reason,
|
||||
}
|
||||
|
||||
// If we haven't got anything yet, add prepare for waiting for the
|
||||
// condition variables.
|
||||
// condition variable.
|
||||
ConditionVariableEntry<team_dead_children> deadWaitEntry;
|
||||
ConditionVariableEntry<team_job_control_children> continuedWaitEntry;
|
||||
ConditionVariableEntry<team_job_control_children> stoppedWaitEntry;
|
||||
|
||||
if (status == B_WOULD_BLOCK && (flags & WNOHANG) == 0) {
|
||||
if (status == B_WOULD_BLOCK && (flags & WNOHANG) == 0)
|
||||
deadWaitEntry.Add(team->dead_children);
|
||||
|
||||
if ((flags & WCONTINUED) != 0) {
|
||||
continuedWaitEntry.Add(team->continued_children,
|
||||
&deadWaitEntry);
|
||||
}
|
||||
|
||||
if ((flags & WUNTRACED) != 0)
|
||||
stoppedWaitEntry.Add(team->stopped_children, &deadWaitEntry);
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
// we got our entry and can return to our caller
|
||||
@@ -2453,13 +2435,6 @@ team_set_job_control_state(struct team* team, job_control_state newState,
|
||||
case JOB_CONTROL_STATE_DEAD:
|
||||
childList = team->parent->dead_children;
|
||||
team->parent->dead_children->count++;
|
||||
// When a child dies, we need to notify all lists, since that might
|
||||
// have been the last of the parent's children, and a waiting
|
||||
// parent thread wouldn't wake up otherwise.
|
||||
team->parent->stopped_children->condition_variable.NotifyAll(
|
||||
threadsLocked);
|
||||
team->parent->continued_children->condition_variable.NotifyAll(
|
||||
threadsLocked);
|
||||
break;
|
||||
case JOB_CONTROL_STATE_STOPPED:
|
||||
childList = team->parent->stopped_children;
|
||||
@@ -2471,7 +2446,8 @@ team_set_job_control_state(struct team* team, job_control_state newState,
|
||||
|
||||
if (childList != NULL) {
|
||||
childList->entries.Add(entry);
|
||||
childList->condition_variable.NotifyAll(threadsLocked);
|
||||
team->parent->dead_children->condition_variable.NotifyAll(
|
||||
threadsLocked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3059,11 +3035,8 @@ _user_setpgid(pid_t processID, pid_t groupID)
|
||||
|
||||
// Changing the process group might have changed the situation for a parent
|
||||
// waiting in wait_for_child(). Hence we notify it.
|
||||
if (status == B_OK) {
|
||||
if (status == B_OK)
|
||||
team->parent->dead_children->condition_variable.NotifyAll(false);
|
||||
team->parent->stopped_children->condition_variable.NotifyAll(false);
|
||||
team->parent->continued_children->condition_variable.NotifyAll(false);
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
|
||||
@@ -1034,13 +1034,8 @@ _dump_thread_info(struct thread *thread)
|
||||
kprintf(" sem.acquire_status: %#lx\n", thread->sem.acquire_status);
|
||||
kprintf(" sem.flags: %#lx\n", thread->sem.flags);
|
||||
|
||||
kprintf("condition variables:");
|
||||
PrivateConditionVariableEntry* entry = thread->condition_variable_entry;
|
||||
while (entry != NULL) {
|
||||
kprintf(" %p", entry->Variable());
|
||||
entry = entry->ThreadNext();
|
||||
}
|
||||
kprintf("\n");
|
||||
kprintf("condition variable: %p\n", entry ? entry->Variable() : NULL);
|
||||
|
||||
kprintf("fault_handler: %p\n", (void *)thread->fault_handler);
|
||||
kprintf("args: %p %p\n", thread->args1, thread->args2);
|
||||
|
||||
Reference in New Issue
Block a user