diff Implab/Parallels/DispatchPool.cs @ 16:5a4b735ba669 promises

sync
author cin
date Thu, 07 Nov 2013 20:20:26 +0400
parents 0f982f9b7d4d
children 7cd4a843b4e4
line wrap: on
line diff
--- a/Implab/Parallels/DispatchPool.cs	Thu Nov 07 03:41:32 2013 +0400
+++ b/Implab/Parallels/DispatchPool.cs	Thu Nov 07 20:20:26 2013 +0400
@@ -63,9 +63,10 @@
         }
 
         bool StartWorker() {
-            var current = m_runningThreads;
+            int current;
             // use spins to allocate slot for the new thread
             do {
+                current = m_runningThreads;
                 if (current >= m_maxThreads || m_exitRequired != 0)
                     // no more slots left or the pool has been disposed
                     return false;
@@ -84,24 +85,33 @@
 
         protected abstract bool TryDequeue(out TUnit unit);
 
-        protected virtual void WakeNewWorker() {
+        protected virtual void WakeNewWorker(bool extend) {
             if (m_suspended > 0)
                 m_hasTasks.Set();
             else
                 StartWorker();
         }
 
+        /// <summary>
+        /// Запускает либо новый поток, если раньше не было ни одного потока, либо устанавливает событие пробуждение одного спящего потока
+        /// </summary>
+        protected void StartIfIdle() {
+            int threads;
+            do {
+
+            }
+        }
+
+        protected virtual void Suspend() {
+            m_hasTasks.WaitOne();
+        }
+
         bool FetchTask(out TUnit unit) {
             do {
                 // exit if requested
                 if (m_exitRequired != 0) {
                     // release the thread slot
-                    int running;
-                    do {
-                        running = m_runningThreads;
-                    } while (running != Interlocked.CompareExchange(ref m_runningThreads, running - 1, running));
-                    running--;
-
+                    var running = Interlocked.Decrement(ref m_runningThreads);
                     if (running == 0) // it was the last worker
                         m_hasTasks.Dispose();
                     else
@@ -112,7 +122,7 @@
 
                 // fetch task
                 if (TryDequeue(out unit)) {
-                    WakeNewWorker();
+                    WakeNewWorker(true);
                     return true;
                 }
 
@@ -122,19 +132,21 @@
                 do {
                     runningThreads = m_runningThreads;
                     if (runningThreads <= m_minThreads) {
+                        // check wheather this is the last thread and we have tasks
+
                         exit = false;
                         break;
                     }
                 } while (runningThreads != Interlocked.CompareExchange(ref m_runningThreads, runningThreads - 1, runningThreads));
 
                 if (exit) {
-                    Interlocked.Decrement(ref m_runningThreads);
                     return false;
                 }
 
-                // keep this thread and wait
+                // entering suspend state
                 Interlocked.Increment(ref m_suspended);
-                m_hasTasks.WaitOne();
+                // keep this thread and wait                
+                Suspend();
                 Interlocked.Decrement(ref m_suspended);
             } while (true);
         }