| @@ -103,15 +103,15 namespace Implab.Test { | |||
| 
             | 
        103 | 103 | |
| 
             | 
        104 | 104 | Assert.AreEqual(5, pool.PoolSize); | 
| 
             | 
        105 | 105 | |
| 
             | 
        106 | pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | |
| 
             | 
        107 | pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | |
| 
             | 
        108 | pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | |
| 
             | 
        106 | pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
| 
             | 
        107 | pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
| 
             | 
        108 | pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
| 
             | 
        109 | 109 | |
| 
             | 
        110 | 110 | Assert.AreEqual(5, pool.PoolSize); | 
| 
             | 
        111 | 111 | |
| 
             | 
        112 | 112 | for (int i = 0; i < 100; i++) | 
| 
             | 
        113 | pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | |
| 
             | 
        114 | 
            
                         Thread.Sleep( | 
    |
| 
             | 
        113 | pool.Invoke(() => { Thread.Sleep(100000000); return 10; }); | |
| 
             | 
        114 | Thread.Sleep(200); | |
| 
             | 
        115 | 115 | Assert.AreEqual(10, pool.PoolSize); | 
| 
             | 
        116 | 116 | |
| 
             | 
        117 | 117 | pool.Dispose(); | 
| @@ -244,7 +244,7 namespace Implab.Test { | |||
| 
             | 
        244 | 244 | [TestMethod] | 
| 
             | 
        245 | 245 | public void ChainedMapTest() { | 
| 
             | 
        246 | 246 | |
| 
             | 
        247 | 
            
                         using (var pool = new WorkerPool(0 | 
    |
| 
             | 
        247 | using (var pool = new WorkerPool(4,4,0)) { | |
| 
             | 
        248 | 248 | int count = 10000; | 
| 
             | 
        249 | 249 | |
| 
             | 
        250 | 250 | double[] args = new double[count]; | 
| 
             | 
        1 | NO CONTENT: modified file, binary diff hidden | 
| @@ -83,14 +83,42 namespace Implab.Parallels { | |||
| 
             | 
        83 | 83 | return signals; | 
| 
             | 
        84 | 84 | } | 
| 
             | 
        85 | 85 | |
| 
             | 
        86 | bool FetchSignalOrWait(int timeout) { | |
| 
             | 
        87 | var start = Environment.TickCount; | |
| 
             | 
        88 | ||
| 
             | 
        89 | // ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΏΠΎΡΠΎΠΊ Π²Π»Π°Π΄Π΅Π΅Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΎΠΉ ΠΈ ΠΏΡΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ ΡΠΈΠ³Π½Π°Π»Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ | |
| 
             | 
        90 | // Π΅Π΅ Π²Π΅ΡΠ½ΡΡΡ, ΡΡΠΎΠ±Ρ Π΄ΡΡΠ³ΠΎΠΉ ΠΎΠΆΠΈΠ΄Π°ΡΡΠΈΠΉ ΠΏΠΎΡΠΎΠΊ ΡΠΌΠΎΠ³ | |
| 
             | 
        91 | bool hasLock = false; | |
| 
             | 
        92 | do { | |
| 
             | 
        93 | int signals; | |
| 
             | 
        94 | do { | |
| 
             | 
        95 | signals = m_wakeEvents; | |
| 
             | 
        96 | if (signals == 0) | |
| 
             | 
        97 | break; | |
| 
             | 
        98 | } while (Interlocked.CompareExchange(ref m_wakeEvents, signals - 1, signals) != signals); | |
| 
             | 
        99 | ||
| 
             | 
        100 | if (signals >= 1) { | |
| 
             | 
        101 | if (signals > 1 && hasLock) | |
| 
             | 
        102 | m_hasTasks.Set(); | |
| 
             | 
        103 | return true; | |
| 
             | 
        104 | } | |
| 
             | 
        105 | ||
| 
             | 
        106 | if (timeout != -1) | |
| 
             | 
        107 | timeout = Math.Max(0, timeout - (Environment.TickCount - start)); | |
| 
             | 
        108 | ||
| 
             | 
        109 | // Π΅ΡΠ»ΠΈ ΡΠΈΠ³Π½Π°Π»ΠΎΠ² Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ ΠΎΡΡΠ°Π»ΠΎΡΡ, ΡΠΎ ΠΏΠ΅ΡΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ, ΠΊΠΎΡΠΎΡΡΠΉ Π΄ΠΎΡΠ΅Π» ΡΡΠ΄Π° ΡΠ±ΡΠΎΡΠΈΡ ΡΠΎΠ±ΡΡΠΈΠ΅ | |
| 
             | 
        110 | // ΠΈ ΡΠΉΠ΄Π΅Ρ Π½Π° ΠΏΡΡΡΠΎΠΉ ΡΠΈΠΊΠ», ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ | |
| 
             | 
        111 | ||
| 
             | 
        112 | hasLock = true; | |
| 
             | 
        113 | } while (m_hasTasks.WaitOne(timeout)); | |
| 
             | 
        114 | ||
| 
             | 
        115 | return false; | |
| 
             | 
        116 | } | |
| 
             | 
        117 | ||
| 
             | 
        86 | 118 | bool Sleep(int timeout) { | 
| 
             | 
        87 | 119 | Interlocked.Increment(ref m_sleepingThreads); | 
| 
             | 
        88 | 
            
                         if ( | 
    |
| 
             | 
        89 | // this is autoreset event, only one thread can run this block simultaneously | |
| 
             | 
        90 | var sleeping = Interlocked.Decrement(ref m_sleepingThreads); | |
| 
             | 
        91 | if (Interlocked.Decrement(ref m_wakeEvents) > 0) | |
| 
             | 
        92 | m_hasTasks.Set(); // wake next worker | |
| 
             | 
        93 | ||
| 
             | 
        120 | if (FetchSignalOrWait(timeout)) { | |
| 
             | 
        121 | Interlocked.Decrement(ref m_sleepingThreads); | |
| 
             | 
        94 | 122 | return true; | 
| 
             | 
        95 | 123 | } else { | 
| 
             | 
        96 | 124 | Interlocked.Decrement(ref m_sleepingThreads); | 
| @@ -106,6 +134,8 namespace Implab.Parallels { | |||
| 
             | 
        106 | 134 | if (m_exitRequired != 0) | 
| 
             | 
        107 | 135 | return; | 
| 
             | 
        108 | 136 | if (m_sleepingThreads > m_wakeEvents) { | 
| 
             | 
        137 | //Console.WriteLine("Waking threads (sleeps {0}, pending {1})", m_sleepingThreads, m_wakeEvents); | |
| 
             | 
        138 | ||
| 
             | 
        109 | 139 | // all sleeping threads may gone | 
| 
             | 
        110 | 140 | SignalThread(); // wake a sleeping thread; | 
| 
             | 
        111 | 141 | |
| @@ -130,8 +160,6 namespace Implab.Parallels { | |||
| 
             | 
        130 | 160 | bool last; | 
| 
             | 
        131 | 161 | bool requestExit; | 
| 
             | 
        132 | 162 | |
| 
             | 
        133 | ||
| 
             | 
        134 | ||
| 
             | 
        135 | 163 | // if threads have a timeout before releasing | 
| 
             | 
        136 | 164 | if (m_releaseTimeout > 0) | 
| 
             | 
        137 | 165 | requestExit = !Sleep(m_releaseTimeout); | 
| @@ -242,8 +270,8 namespace Implab.Parallels { | |||
| 
             | 
        242 | 270 | |
| 
             | 
        243 | 271 | void Worker() { | 
| 
             | 
        244 | 272 | TUnit unit; | 
| 
             | 
        273 | //Console.WriteLine("{0}: Active", Thread.CurrentThread.ManagedThreadId); | |
| 
             | 
        245 | 274 | Interlocked.Increment(ref m_activeThreads); | 
| 
             | 
        246 | Sleep(0); // remove wake request if the new thread is started | |
| 
             | 
        247 | 275 | do { | 
| 
             | 
        248 | 276 | // exit if requested | 
| 
             | 
        249 | 277 | if (m_exitRequired != 0) { | 
| @@ -269,10 +297,10 namespace Implab.Parallels { | |||
| 
             | 
        269 | 297 | // keep this thread and wait | 
| 
             | 
        270 | 298 | if (!Suspend()) | 
| 
             | 
        271 | 299 | break; | 
| 
             | 
        272 | ||
| 
             | 
        300 | //Console.WriteLine("{0}: Awake", Thread.CurrentThread.ManagedThreadId); | |
| 
             | 
        273 | 301 | Interlocked.Increment(ref m_activeThreads); | 
| 
             | 
        274 | 302 | } while (true); | 
| 
             | 
        275 | ||
| 
             | 
        303 | //Console.WriteLine("{0}: Exited", Thread.CurrentThread.ManagedThreadId); | |
| 
             | 
        276 | 304 | } | 
| 
             | 
        277 | 305 | |
| 
             | 
        278 | 306 | protected virtual void Dispose(bool disposing) { | 
        
        General Comments 0
    
    
  
  
                      You need to be logged in to leave comments.
                      Login now
                    
                