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