From 66aac81e98b1cf8720817d87a7f1973dc976fb3e Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 20 Apr 2008 15:15:58 +0000 Subject: [PATCH] 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 --- headers/private/kernel/thread_types.h | 4 +-- src/system/kernel/team.cpp | 39 +++++---------------------- src/system/kernel/thread.cpp | 7 +---- 3 files changed, 9 insertions(+), 41 deletions(-) diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 3ef4532423..ac7f02d0c9 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -138,11 +138,11 @@ struct job_control_entry : DoublyLinkedListLinkImpl { typedef DoublyLinkedList JobControlEntryList; struct team_job_control_children { - ConditionVariable condition_variable; - JobControlEntryList entries; + JobControlEntryList entries; }; struct team_dead_children : team_job_control_children { + ConditionVariable condition_variable; uint32 count; bigtime_t kernel_time; bigtime_t user_time; diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 606c9058d5..595faae505 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -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 deadWaitEntry; - ConditionVariableEntry continuedWaitEntry; - ConditionVariableEntry 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(); diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index cf21b07cf5..3bf6babb96 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -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);