[haiku-commits] haiku: hrev44360 - src/apps/debugger

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 20 Jul 2012 02:25:08 +0200 (CEST)

hrev44360 adds 1 changeset to branch 'master'
old head: 02378956042046a9fc635820f73d2cbeb7a4b5df
new head: 1f80f2eec3fcca13f5d0f4e146bde2058672a0ab

----------------------------------------------------------------------------

1f80f2e: Fix #8749.
  
  - When a job needs to go dependent on another job, we no longer use recursion
    to manage the execution stack. Instead the job is simply marked as waiting
    and we execute other jobs with no dependencies in the meantime. When a job
    completes, all dependents are moved back onto the unscheduled list and
    executed as needed.
  
  - Adjustments to ResolveValueNodeJob to handle the now asynchronous nature
    of waiting.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev44360
Commit:      1f80f2eec3fcca13f5d0f4e146bde2058672a0ab
URL:         http://cgit.haiku-os.org/haiku/commit/?id=1f80f2e
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Fri Jul 20 00:21:06 2012 UTC

Ticket:      https://dev.haiku-os.org/ticket/8749

----------------------------------------------------------------------------

3 files changed, 28 insertions(+), 25 deletions(-)
src/apps/debugger/Jobs.cpp   |    6 +++++
src/apps/debugger/Worker.cpp |   45 ++++++++++++++++++--------------------
src/apps/debugger/Worker.h   |    2 +-

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Jobs.cpp b/src/apps/debugger/Jobs.cpp
index 0e812cc..bfd2fe1 100644
--- a/src/apps/debugger/Jobs.cpp
+++ b/src/apps/debugger/Jobs.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
  * Distributed under the terms of the MIT License.
  */
@@ -523,6 +524,9 @@ ResolveValueNodeValueJob::_ResolveNodeValue()
                                fValueNode, fValueNode->Name().String(), 
parentNode);
                        return error;
                }
+
+               if (State() == JOB_STATE_WAITING)
+                       return B_OK;
        }
 
        // resolve the node child location, if necessary
@@ -629,6 +633,8 @@ 
ResolveValueNodeValueJob::_ResolveParentNodeValue(ValueNode* parentNode)
                        // "Not found" can happen due to a race condition 
between
                        // unlocking the worker and starting to wait.
                        break;
+               case JOB_DEPENDENCY_ACTIVE:
+                       return B_OK;
                case JOB_DEPENDENCY_FAILED:
                case JOB_DEPENDENCY_ABORTED:
                default:
diff --git a/src/apps/debugger/Worker.cpp b/src/apps/debugger/Worker.cpp
index dc1f06a..409ff2b 100644
--- a/src/apps/debugger/Worker.cpp
+++ b/src/apps/debugger/Worker.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
  * Distributed under the terms of the MIT License.
  */
@@ -138,6 +139,15 @@ void
 Job::SetWaitStatus(job_wait_status status)
 {
        fWaitStatus = status;
+       switch (fWaitStatus) {
+       case JOB_DEPENDENCY_ACTIVE:
+               fState = JOB_STATE_WAITING;
+               break;
+       default:
+               fState = JOB_STATE_ACTIVE;
+               break;
+
+       }
 }
 
 
@@ -346,18 +356,6 @@ Worker::WaitForJob(Job* waitingJob, const JobKey& key)
        waitingJob->SetDependency(job);
        job->DependentJobs().Add(waitingJob);
 
-       // TODO: Continuations would be nice. For the time being we have to use
-       // recursion. Disadvantages are that we'll use more stack and that 
aborting
-       // a job waiting for a dependency won't abort the job before the 
dependency
-       // is done.
-       locker.Unlock();
-       _ProcessJobs(waitingJob);
-       locker.Lock();
-
-       // ignore the actual wait status when the game is over anyway
-       if (fTerminating || waitingJob->State() == JOB_STATE_ABORTED)
-               return JOB_DEPENDENCY_ABORTED;
-
        return waitingJob->WaitStatus();
 }
 
@@ -372,7 +370,7 @@ Worker::_WorkerLoopEntry(void* data)
 status_t
 Worker::_WorkerLoop()
 {
-       _ProcessJobs(NULL);
+       _ProcessJobs();
 
        // clean up aborted jobs
        AutoLocker<Worker> locker(this);
@@ -384,7 +382,7 @@ Worker::_WorkerLoop()
 
 
 void
-Worker::_ProcessJobs(Job* waitingJob)
+Worker::_ProcessJobs()
 {
        while (true) {
                AutoLocker<Worker> locker(this);
@@ -395,8 +393,10 @@ Worker::_ProcessJobs(Job* waitingJob)
 
                        status_t error = acquire_sem(fWorkToDoSem);
                        if (error != B_OK) {
-                               if (error == B_INTERRUPTED)
+                               if (error == B_INTERRUPTED) {
+                                       locker.Lock();
                                        continue;
+                               }
                                break;
                        }
 
@@ -404,13 +404,9 @@ Worker::_ProcessJobs(Job* waitingJob)
                }
 
                // clean up aborted jobs
-               while (Job* job = fAbortedJobs.RemoveHead()) {
+               while (Job* job = fAbortedJobs.RemoveHead())
                        _FinishJob(job);
 
-                       if (waitingJob != NULL && waitingJob->State() != 
JOB_STATE_WAITING)
-                               break;
-               }
-
                // process the next job
                if (Job* job = fUnscheduledJobs.RemoveHead()) {
                        job->SetState(JOB_STATE_ACTIVE);
@@ -422,12 +418,10 @@ Worker::_ProcessJobs(Job* waitingJob)
                        if (job->State() == JOB_STATE_ACTIVE) {
                                job->SetState(
                                        error == B_OK ? JOB_STATE_SUCCEEDED : 
JOB_STATE_FAILED);
-                       }
+                       } else if (job->State() == JOB_STATE_WAITING)
+                               continue;
 
                        _FinishJob(job);
-
-                       if (waitingJob != NULL && waitingJob->State() != 
JOB_STATE_WAITING)
-                               break;
                }
        }
 }
@@ -492,7 +486,10 @@ Worker::_FinishJob(Job* job)
                while (Job* dependentJob = job->DependentJobs().RemoveHead()) {
                        dependentJob->SetDependency(NULL);
                        dependentJob->SetWaitStatus(waitStatus);
+                       fUnscheduledJobs.Add(dependentJob);
                }
+
+               release_sem(fWorkToDoSem);
        }
 
        if (job->State() != JOB_STATE_ABORTED)
diff --git a/src/apps/debugger/Worker.h b/src/apps/debugger/Worker.h
index 241a3f4..7e35699 100644
--- a/src/apps/debugger/Worker.h
+++ b/src/apps/debugger/Worker.h
@@ -182,7 +182,7 @@ private:
        static  status_t                        _WorkerLoopEntry(void* data);
                        status_t                        _WorkerLoop();
 
-                       void                            _ProcessJobs(Job* 
waitingJob);
+                       void                            _ProcessJobs();
                        void                            _AbortJob(Job* job, 
bool removeFromTable);
                        void                            _FinishJob(Job* job);
 


Other related posts: