Mercurial > pub > ImplabNet
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); }