singrdk/base/Applications/Godot/Godot.cs

192 lines
6.2 KiB
C#
Raw Permalink Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note: Singularity wait primitives test program.
//
using Microsoft.Singularity.V1.Services;
using Microsoft.Singularity.V1.Threads;
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
2008-11-17 18:29:00 -05:00
namespace Microsoft.Singularity.Applications
{
[ConsoleCategory(HelpMessage="Showcase thread synchronization with Mutex/Waithandle", DefaultAction=true)]
2008-03-05 09:52:00 -05:00
internal class Parameters {
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[LongParameter( "t", Default=2, HelpMessage="Number of Waiters (threads)")]
internal long numberOfWaiters;
2008-11-17 18:29:00 -05:00
[BoolParameter( "d", Default=false, HelpMessage="Debug Mode")]
internal bool debugMode;
2008-03-05 09:52:00 -05:00
reflective internal Parameters();
internal int AppMain() {
return Godot.AppMain(this);
}
}
public class Godot
{
private static Mutex! mutex;
private static WaitHandle[]! waiters;
private static WaitHandle[]! others;
private static String[]! names;
private static WaiterThread[] threadDetails;
private static Thread[] threads;
2008-11-17 18:29:00 -05:00
private static bool debugMode;
2008-03-05 09:52:00 -05:00
private class WaiterThread {
private uint myIndex;
public WaiterThread(uint index) {
myIndex = index;
}
public void Go()
{
String myName = names[myIndex];
2008-11-17 18:29:00 -05:00
Write(String.Format("Enter Thread {0}\n", myName));
2008-03-05 09:52:00 -05:00
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: signaling auto-reset event\n", myName));
2008-03-05 09:52:00 -05:00
((AutoResetEvent!)waiters[myIndex]).Set();
for (uint Loop = 0; Loop < 5; Loop++) {
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: waiting for mutex\n", myName));
2008-03-05 09:52:00 -05:00
mutex.WaitOne();
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: got mutex\n", myName));
2008-03-05 09:52:00 -05:00
Thread.Sleep(1000);
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: releasing mutex\n", myName));
2008-03-05 09:52:00 -05:00
mutex.ReleaseMutex();
Thread.Yield();
}
//
// Tell other waiters we're done.
//
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: signaling manual-reset event\n", myName));
2008-03-05 09:52:00 -05:00
((ManualResetEvent!)others[myIndex]).Set();
//
// Wait for other waiter.
//
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: waiting for other waiters\n", myName));
2008-03-05 09:52:00 -05:00
foreach (WaitHandle! other in others) {
other.WaitOne();
}
2008-11-17 18:29:00 -05:00
Write(String.Format(" {0}: heard from other waiters\n", myName));
2008-03-05 09:52:00 -05:00
2008-11-17 18:29:00 -05:00
Write(String.Format("Exit Thread {0}\n", myName));
2008-03-05 09:52:00 -05:00
}
}
public static void Usage()
{
Console.WriteLine("\nUsage: godot [NumberOfWaitThreads]\n\n");
}
internal static int AppMain(Parameters! config)
{
uint numberOfWaiters = (uint) config.numberOfWaiters;
2008-11-17 18:29:00 -05:00
debugMode = config.debugMode;
2008-03-05 09:52:00 -05:00
2008-11-17 18:29:00 -05:00
Write(String.Format("\nStarting wait test with {0} wait threads\n\n",
numberOfWaiters));
2008-03-05 09:52:00 -05:00
names = new String[4];
names[0] = "Estragon";
names[1] = "Vladimir";
names[2] = "Lucky";
names[3] = "Pozzo";
//
// Create some synchronization primitives to test.
//
mutex = new Mutex(true);
waiters = new WaitHandle[numberOfWaiters];
others = new WaitHandle[numberOfWaiters];
for (uint Loop = 0; Loop < numberOfWaiters; Loop++) {
waiters[Loop] = new AutoResetEvent(false);
others[Loop] = new ManualResetEvent(false);
}
2008-11-17 18:29:00 -05:00
Write("Created synchronization primitives\n\n");
2008-03-05 09:52:00 -05:00
//
// Fire up the waiters.
//
threads = new Thread[numberOfWaiters];
threadDetails = new WaiterThread[numberOfWaiters];
for (uint Loop = 0; Loop < numberOfWaiters; Loop++) {
threadDetails[Loop] = new WaiterThread(Loop);
threads[Loop] = new Thread(
new ThreadStart(threadDetails[Loop].Go));
((!)threads[Loop]).Start();
}
//
// Wait for the waiters to tell us they're about to start waiting.
//
2008-11-17 18:29:00 -05:00
Write("Waiting for all waiters to start\n");
2008-03-05 09:52:00 -05:00
foreach (WaitHandle! waiter in waiters) {
waiter.WaitOne();
}
//
// Release the Mutex to the wolves.
//
2008-11-17 18:29:00 -05:00
Write("About to release mutex\n");
2008-03-05 09:52:00 -05:00
mutex.ReleaseMutex();
2008-11-17 18:29:00 -05:00
Write("Mutex released\n");
2008-03-05 09:52:00 -05:00
//
// Wait for the threads to die.
//
#if false
#if NOT_YET
2008-11-17 18:29:00 -05:00
Write("Waiting for all waiters to terminate\n");
2008-03-05 09:52:00 -05:00
for (uint Loop = 0; Loop < numberOfWaiters; Loop++) {
threads[Loop].Join();
}
#else
2008-11-17 18:29:00 -05:00
Write("Waiting for 30 sec while threads play\n");
2008-03-05 09:52:00 -05:00
Thread.Sleep(30000);
#endif
#endif
2008-11-17 18:29:00 -05:00
Write("Goodbye\n");
2008-03-05 09:52:00 -05:00
return 0;
}
2008-11-17 18:29:00 -05:00
private static void Write(string s)
{
string msg = "Godot:" + s;
Console.Write(msg);
if (debugMode) {
DebugStub.Write(msg);
}
}
2008-03-05 09:52:00 -05:00
}
}