// construct the blocking queue public BlockingQueueAsync(int capacity) { this.capacity = capacity; this.room = new T[capacity]; this.putIdx = this.takeIdx = 0; this.freeSlots = new SemaphoreSlim1(capacity, capacity); this.filledSlots = new SemaphoreSlim1(0, capacity); }
internal Request(SemaphoreSlim1 sem) { this.sem = sem; }
// test semaphore as a mutual exclusion lock using synchronous acquires private static bool TestSemaphoreAsLockSync() { const int SETUP_TIME = 50; const int RUN_TIME = 30 * 1000; int THREADS = 50; const int MIN_TIMEOUT = 1; const int MAX_TIMEOUT = 50; const int MIN_CANCEL_INTERVAL = 1; const int MAX_CANCEL_INTERVAL = 50; Thread[] tthrs = new Thread[THREADS]; int[] privateCounters = new int[THREADS]; int[] timeouts = new int[THREADS]; int[] cancellations = new int[THREADS]; int issuedInterrupts = 0; int[] sensedInterrupts = new int[THREADS]; int sharedCounter = 0; bool exit = false; ManualResetEventSlim start = new ManualResetEventSlim(); SemaphoreSlim1 _lock = new SemaphoreSlim1(1, 1); /** * Create and start acquirer/releaser threads */ for (int i = 0; i < THREADS; i++) { int tid = i; tthrs[i] = new Thread(() => { Random rnd = new Random(Thread.CurrentThread.ManagedThreadId); start.Wait(); CancellationTokenSource cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL)); do { do { try { if (_lock.Acquire(timeout: rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT), token: cts.Token)) { break; } timeouts[tid]++; } catch (OperationCanceledException) { cancellations[tid]++; cts.Dispose(); cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL)); } catch (ThreadInterruptedException) { sensedInterrupts[tid]++; } } while (true); try { Thread.Sleep(0); } catch (ThreadInterruptedException) { sensedInterrupts[tid]++; } sharedCounter++; if (THREADS > 1) { if (rnd.Next(100) < 99) { Thread.Yield(); } else { try { Thread.Sleep(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT)); } catch (ThreadInterruptedException) { sensedInterrupts[tid]++; } } } // release the lock _lock.Release(); privateCounters[tid]++; if (THREADS > 1) { try { if ((privateCounters[tid] % 100) == 0) { Console.Write("[#{0:D2}]", tid); } } catch (ThreadInterruptedException) { sensedInterrupts[tid]++; } } } while (!Volatile.Read(ref exit)); try { Thread.Sleep(10); } catch (ThreadInterruptedException) { sensedInterrupts[tid]++; } }); tthrs[i].Start(); } Thread.Sleep(SETUP_TIME); Stopwatch sw = Stopwatch.StartNew(); start.Set(); Random grnd = new Random(Thread.CurrentThread.ManagedThreadId); int endTime = Environment.TickCount + RUN_TIME; //... do { Thread.Sleep(grnd.Next(5)); #if SEND_INTERRUPTS if (THREADS > 1) { tthrs[grnd.Next(THREADS)].Interrupt(); issuedInterrupts++; } #endif if (Console.KeyAvailable) { Console.Read(); break; } #if RUN_CONTINOUSLY } while (true); #else } while (Environment.TickCount < endTime);