/// <summary>
        /// The entry point of the program, where the program control starts and ends.
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        public static void Main(String[] args)
        {
            Console.Write("Where would you like the output file?: ");
            String path = Console.ReadLine();

            Semaphore askWait = new Semaphore(1);

            FileWriter fileWriter = new FileWriter(path);
            VowelCount vowelCount = new VowelCount();

            // Plug all the correct channels to each active object
            vowelCount.outputChannel = fileWriter.inputChannel;
            VowelFilter vowelFilter = new VowelFilter(vowelCount.inputChannel);
            SentenceReader sentenceReader = new SentenceReader(askWait);
            sentenceReader.outputChannel = vowelFilter.inputChannel;

            // Start all the active objects
            fileWriter.Start();
            vowelFilter.Start();
            vowelCount.Start();
            sentenceReader.Start();

            while (true)
            {
                vowelCount.PrintCount();
                askWait.Release();
            }
        }
        /// <summary>
        /// The entry point of the program, where the program control starts and ends.
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        public static void Main(string[] args)
        {
            Semaphore hydrogenSemaphore = new Semaphore(2);	// Controls the amount of hydrogen present in the barrier.
            Semaphore oxygenSemaphore = new Semaphore(1);	// Controls the amount of oxygen present in the barrier.
            Barrier bondBarrier = new Barrier(3);

            /* Create six oxygen and hydrogen atoms */
            for (int i = 0; i < 6; i++)
            {
                Atom hydrogen = new Atom(hydrogenSemaphore, bondBarrier, "H" + i);
                Atom oxygen = new Atom(oxygenSemaphore, bondBarrier, "O" + i);
                hydrogen.Start();
                oxygen.Start();
            }
        }
 /// <summary>
 ///     The acquiring thread creates a semaphore of it's own and adds it to the queue. 
 ///     The thread then tries to acquire from that semaphore. Once acquired, the thread can acquire a token.
 /// </summary>
 public override void Acquire()
 {
     Semaphore threadSemaphore;
     lock(queueLock)
     {
         lock (lockObject)
         {
             if (tokens > 0 && (waitingThreadsQueue.Count == 0))
             {
                 tokens--;
                 return;
             }
             else
             {
                 threadSemaphore = new Semaphore(0);
                 waitingThreadsQueue.Enqueue(threadSemaphore);
             }
         }
     }
     threadSemaphore.Acquire();
 }
 /// <summary>
 /// 	Initializes a new instance of the Smoker class.
 /// </summary>
 /// <param name="watchSemaphore">The agent's semaphore that will be released to when ingredients are available.</param>
 public Smoker(Semaphore watchSemaphore, Semaphore agentSemaphore)
 {
     this.watchSemaphore = watchSemaphore;
     this.agentSemaphore = agentSemaphore;
 }
 static void Main(string[] args)
 {
     Console.WriteLine("Enter the utility class you would like to test:\n" +
         "OPTIONS:\n" +
       	"\tsemaphore\n" +
       	"\tchannel\n" +
       	"\tboundedchannel\n" +
       	"\tlightswitch\n" +
       				"\tlatch\n" +
      	"\trwlock\n" +
       	"\tmutex\n" +
         "\tFIFOSemaphore\n" +
         "\tExchanger");
     Console.Write("> ");
     String command = Console.ReadLine();
     command = command.ToLower();
     if (command.Length > 0)
     {
         switch (command)
         {
             case "semaphore":
                 ConcurrencyUtils.Semaphore testSemaphore = new ConcurrencyUtils.Semaphore(0);
                 List<Thread> threads = new List<Thread>();
                 for (int i = 0; i < TEST_THREADS; i++)
                 {
                     Thread newThread = new Thread(() => SemaphoreTest(testSemaphore));
                     newThread.Name = i.ToString();
                     // Console.WriteLine(newThread.Name + " created");
                     newThread.Start();
                     threads.Add(newThread);
                 }
                 Thread releaserThread = new Thread(() => SemaphoreTestReleaser(testSemaphore));
                 releaserThread.Name = "R";
                 releaserThread.Start();
                 break;
             case "mutex":
                 ConcurrencyUtils.Mutex testMutex = new ConcurrencyUtils.Mutex();
                 List<Thread> mutexThreads = new List<Thread>();
                 for (int i = 0; i < TEST_THREADS; i++)
                 {
                     Thread newThread = new Thread(() => SemaphoreTest(testMutex));
                     newThread.Name = i.ToString();
                     newThread.Start();
                     mutexThreads.Add(newThread);
                 }
                 Thread mutexReleaserThread = new Thread(() => MutexTestReleaser(testMutex));
                 mutexReleaserThread.Name = "R";
                 mutexReleaserThread.Start();
                 break;
             case "channel":
                 Channel<String> testChannel = new Channel<String>();
                 List<Thread> grabberThreads = new List<Thread>();
                 Thread putterThread = new Thread(() => putData(testChannel));
                 putterThread.Name = "Putter";
                 putterThread.Start();
                 for (int i = 0; i < TEST_THREADS; i++)
                 {
                     Thread newThread = new Thread(() => grabData(testChannel));
                     newThread.Name = "Thread" + i;
                     Console.WriteLine(newThread.Name + " created");
                     newThread.Start();
                     grabberThreads.Add(newThread);
                 }
                 break;
             case "boundedchannel":
                 BoundChannel<String> testBoundChannel = new BoundChannel<String>(CHANNEL_SIZE);
                 List<Thread> putterThreads = new List<Thread>();
                 Thread grabberThread = new Thread(() => grabData(testBoundChannel));
                 grabberThread.Name = "Grabber";
                 grabberThread.Start();
                 for (int i = 0; i < TEST_THREADS; i++)
                 {
                     Thread newThread = new Thread(() => putData(testBoundChannel));
                     newThread.Name = "Thread" + i;
                     Console.WriteLine(newThread.Name + " created");
                     newThread.Start();
                     putterThreads.Add(newThread);
                 }
                 break;
             case "lightswitch":
                 ConcurrencyUtils.Semaphore semaphore = new ConcurrencyUtils.Semaphore(1);
                 LightSwitch writeSwitch = new LightSwitch(semaphore);
                 List<Thread> writerThreads = new List<Thread>();
                 Thread lonelyThread = new Thread(() => lonelyThreadWrite( semaphore ) );
                 lonelyThread.Start();
                 for (int i = 0; i < 10; i++)
                 {
                     Thread newThread = new Thread(() => groupThreadWrite(writeSwitch));
                     newThread.Name = "Thread" + i;
                     newThread.Start();
                     writerThreads.Add(newThread);
                 }
                 break;
             case "latch":
                 Latch latch = new Latch();
                 List<Thread> waiters = new List<Thread>();
                 for (int i = 0; i < 100; i++)
                 {
                     Thread newThread = new Thread(() => latchAcquire(latch));
                     newThread.Name = "Thread" + i;
                     newThread.Start();
                 }
                 Thread unlocker = new Thread(() => latchRelease(latch));
                 unlocker.Start();
                 break;
             case "rwlock":
                 ConcurrencyUtils.ReaderWriterLock RWLock = new ConcurrencyUtils.ReaderWriterLock();
                 for (int i = 0; i < 10; i++)
                 {
                     Thread newThread = new Thread(() => readLots(RWLock));
                     newThread.Name = "Reader Thread" + i;
                     newThread.Start();
                 }
                 for (int i = 0; i < 2; i++)
                 {
                     Thread newThread = new Thread(() => writeLots(RWLock));
                     newThread.Name = "Writer Thread" + i;
                     newThread.Start();
                 }
                 break;
             case "fifosemaphore":
                 FIFOSemaphore fifoSemaphore = new FIFOSemaphore(1);
                 for (int i = 0; i < 4; i++)
                 {
                     Thread t = new Thread(() => acquireWaitRelease(fifoSemaphore));
                     t.Name = "Thread" + i;
                     t.Start();
                     Thread.Sleep(1000);
                 }
                 break;
             case "exchanger":
                 Exchanger<String> exchanger = new Exchanger<String>();
                 String string1 = "String 1";
                 String string2 = "String 2";
                 Thread thread1 = new Thread(() => exchangeString(exchanger, string1));
                 Thread thread2 = new Thread(() => exchangeString(exchanger, string2));
                 thread1.Name = "Thread 1";
                 thread2.Name = "Thread 2";
                 thread1.Start();
                 thread2.Start();
                 thread1.Join();
                 thread2.Join();
                 break;
             default:
                 Console.WriteLine("Test for '" + args[0] + "' not implemented");
                 break;
         }
     }
     else
     {
         Console.WriteLine("No argument provided");
     }
 }
 /// <summary>
 /// 	Initializes a new instance of the 
 ///		<see cref="ConcurrencyUtils.Latch"/> class.
 /// </summary>
 public Latch()
 {
     lSemaphore = new Semaphore(0);
 }
 /// <summary>
 /// 	Initializes a new instance of the 
 ///		<see cref="ConcurrencyUtils.LightSwitch"/> class.
 /// </summary>
 /// <param name="s">S.</param>
 public LightSwitch(Semaphore s)
 {
     lSemaphore = s;
 }
 /// <summary>
 /// Initializes a new instance of this class.
 /// </summary>
 /// <param name="barrierStartSize">Barrier start size.</param>
 public Barrier(UInt32 barrierStartSize)
 {
     ReleaseSemaphore = new Semaphore();
     TS = new Mutex();
     barrierSize = barrierStartSize;
 }