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:
Ingo Weinhold
2008-04-20 15:15:58 +00:00
parent da63adf5ea
commit 66aac81e98
3 changed files with 9 additions and 41 deletions
+2 -2
View File
@@ -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;
+6 -33
View File
@@ -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();
+1 -6
View File
@@ -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);