Inheritance: IDisposable
Esempio n. 1
0
        static void Main(string[] args)
        {
            if (args.Length == 0 || args[0] == "server")
            {
                MicroThread pt = new MicroThread(ServerPrintRun);
                pt.Start();

                Server.s_bufferSize = s_blockSize;
                MicroThread t = new MicroThread(Server.ListenRun);
                t.Start();
                Scheduler.Run();
            }
            else
            {
                Console.WriteLine("Starting {0} threads, sending {1} {2} byte blocks", s_threads, s_blocks, s_blockSize);

                MicroThread pt = new MicroThread(ClientPrintRun);
                pt.Start();

                for (int i = 0; i < s_threads; i++)
                {
                    Client c = new Client(s_blocks, s_blockSize);
                    MicroThread t = new MicroThread(c.Run);
                    t.Start();
                }

                DateTime t1 = DateTime.Now;
                Scheduler.Run();
                DateTime t2 = DateTime.Now;

                Console.WriteLine();
                Console.WriteLine("TOTAL {0} MB/s", (Client.s_totalBlocksSent / 1000.0 / 1000.0 * s_blockSize) / ((TimeSpan)(t2 - t1)).TotalSeconds);
            }
        }
        // Yields the current thread and schedules next one
        void YieldInternal()
        {
            Print("Yield() on thread {0}", m_currentThread);

            if (m_currentThread.m_continuation.Store(0) == 0)
            {
#if MT_TIMING
                m_stopWatch.Stop();
                m_currentThread.m_ticks += m_stopWatch.ElapsedTicks;
#endif
                m_currentThread.m_state = MicroThreadState.Scheduled;

                m_previousThread = m_currentThread;
                m_currentThread  = m_currentThread.m_next;

                ScheduleNext();
            }
            else
            {
                // We come here when the thread has resumed
                //Print("Yield() returned, resuming thread {0}", m_currentThread);

                if (m_currentThread.m_error != null)
                {
                    throw m_currentThread.m_error;
                }
            }
        }
Esempio n. 3
0
        static void Main()
        {
            DateTime time1 = DateTime.Now;

            s_channel = new Channel<int>();

            MicroThread t2 = new MicroThread(run2);
            t2.Start();

            MicroThread t3 = new MicroThread(run2);
            t3.Start();

            MicroThread t1 = new MicroThread(run1);
            t1.Start();

            Console.WriteLine("Starting producer/consumer test, loops {0}", s_loops);

            Scheduler.Run();

            DateTime time2 = DateTime.Now;

            Console.WriteLine("total {0}", res);
            Console.WriteLine("time {0}ms", (time2 - time1).TotalMilliseconds);
            Console.WriteLine("END");
        }
Esempio n. 4
0
        public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error)
        {
            int sent = 0;

            while (true)
            {
                sent += m_socket.Send(buffer, offset + sent, size - sent, socketFlags, out error);

                if (error == SocketError.WouldBlock)
                {
                    error = SocketError.Success;
                }

                if (error != SocketError.Success)
                {
                    return(sent);
                }

                if (sent < size)
                {
                    m_writeCS.Enter();
                    m_writingThread = MicroThread.CurrentThread;
                    m_writingThread.Wait();
                    m_writingThread = null;
                    m_writeCS.Exit();
                }
                else
                {
                    return(sent);
                }
            }
        }
Esempio n. 5
0
        //static long s_totalYields = 0;
        static int Main(string[] args)
        {
            if(args.Length != 2)
            {
                Console.WriteLine("usage: YieldTest <numthreads> <numloops>");
                return 1;
            }

            s_threads = Int32.Parse(args[0]);
            s_loops = Int32.Parse(args[1]);

            for (int i = 0; i < s_threads; i++)
            {
                MicroThread t = new MicroThread(Run);
                t.Start();
            }

            DateTime t1 = DateTime.Now;

            Scheduler.Run();

            DateTime t2 = DateTime.Now;
            TimeSpan ts = t2 - t1;

            //Console.WriteLine("Total yields {0}", s_totalYields);
            Console.WriteLine("{0} threads * {1} loops = {2} yields in {3:F2}s, {4:F0} yields/s", s_threads, s_loops, s_threads * s_loops,
                ts.TotalSeconds, (s_threads * s_loops)/ts.TotalSeconds);
            /*
            long mem = System.GC.GetTotalMemory(false);
            Console.WriteLine("Mem {0:F2}M", mem / 1000000.0);
            */
            return 0;
        }
        void AddInternal(MicroThread thread)
        {
            if (m_currentThread == null)
            {
#if EXTRA_CHECKS
                if (m_previousThread != null || m_scheduledThreadCount != 0)
                {
                    throw new Exception();
                }
#endif
                m_currentThread  = thread;
                m_previousThread = thread;
                thread.m_next    = thread;
            }
            else
            {
#if EXTRA_CHECKS
                if (m_previousThread == null || m_scheduledThreadCount == 0)
                {
                    throw new Exception();
                }
#endif

                m_previousThread.m_next = thread;
                m_previousThread        = thread;
                thread.m_next           = m_currentThread;
            }

            m_scheduledThreadCount++;
        }
Esempio n. 7
0
        static void Main()
        {
            MicroThread t = new MicroThread(MainRun);
            t.Start();

            Scheduler.Run();
        }
Esempio n. 8
0
 static void Main()
 {
     MicroThread t1 = new MicroThread(Run1);
     MicroThread t2 = new MicroThread(Run2);
     t1.Start();
     t2.Start();
     Scheduler.Run();
 }
 public void Exit()
 {
     if (m_suspendedThreads.Count > 0)
     {
         MicroThread t = m_suspendedThreads.Dequeue();
         t.WakeUp();
     }
     m_locked = false;
 }
Esempio n. 10
0
        void SleepInternal(int milliseconds)
        {
            Print("Putting thread {0} to sleep for {1} ms", m_currentThread, milliseconds);

            if (m_currentThread.m_continuation.Store(0) == 0)
            {
#if MT_TIMING
                m_stopWatch.Stop();
                m_currentThread.m_ticks += m_stopWatch.ElapsedTicks;
#endif
                MicroThread thread = m_currentThread;

                RemoveCurrentThread();

                thread.m_state = MicroThreadState.Sleeping;


                DateTime wakeDateTime = DateTime.UtcNow + TimeSpan.FromMilliseconds(milliseconds);
                long     wakeTime     = wakeDateTime.Ticks;
                thread.m_wakeTime = wakeTime;

                if (m_firstSleepingThread == null)
                {
                    m_firstSleepingThread = thread;
                }
                else if (wakeTime <= m_firstSleepingThread.m_wakeTime)
                {
                    thread.m_next         = m_firstSleepingThread;
                    m_firstSleepingThread = thread;
                }
                else
                {
                    MicroThread t = m_firstSleepingThread;

                    while (t.m_next != null && wakeTime >= t.m_next.m_wakeTime)
                    {
                        t = t.m_next;
                    }

                    thread.m_next = t.m_next;
                    t.m_next      = thread;
                }

                m_sleepingThreadCount++;

                ScheduleNext();
            }
            else
            {
                Print("Thread {0} woke up from sleep", m_currentThread);

                if (m_currentThread.m_error != null)
                {
                    throw m_currentThread.m_error;
                }
            }
        }
Esempio n. 11
0
        void WakeUpInternal(MicroThread thread)
        {
            Print("Waking up thread {0}", thread);

            m_waitingThreadCount--;

            thread.m_state = MicroThreadState.Scheduled;

            AddInternal(thread);
        }
Esempio n. 12
0
        public void Increase()
        {
            Console.WriteLine("Semaphore:Increase {0} -> {1}", m_value, m_value + 1);

            m_value++;

            if (m_value <= 0)
            {
                MicroThread t = m_suspendedThreads.Dequeue();
                t.WakeUp();
            }
        }
Esempio n. 13
0
        public void Decrease()
        {
            Console.WriteLine("Semaphore:Decrease {0} -> {1}", m_value, m_value - 1);

            m_value--;

            if (m_value < 0)
            {
                MicroThread t = MicroThread.CurrentThread;
                m_suspendedThreads.Enqueue(t);
                t.Wait();
            }
        }
Esempio n. 14
0
        public T Receive()
        {
            MicroThread t = MicroThread.CurrentThread;

            if (m_senders.Count == 0)
            {
                m_receivers.Enqueue(t);
                t.Wait();
            }
            else
            {
                MicroThread sender = m_senders.Dequeue();
                sender.WakeUp();
            }

            return(m_dataQueue.Dequeue());
        }
Esempio n. 15
0
        public MicroSocket Accept()
        {
            Print("Begin accepting");

            m_readCS.Enter();
            m_readingThread = MicroThread.CurrentThread;
            m_readingThread.Wait();
            m_readingThread = null;
            m_readCS.Exit();

            Print("Accept returned");

            Socket      newSocket = m_socket.Accept();
            MicroSocket s         = new MicroSocket(newSocket);

            return(s);
        }
Esempio n. 16
0
        public void Send(T data)
        {
            MicroThread t = MicroThread.CurrentThread;

            m_dataQueue.Enqueue(data);

            if (m_receivers.Count == 0)
            {
                m_senders.Enqueue(t);
                t.Wait();
            }
            else
            {
                MicroThread receiver = m_receivers.Dequeue();
                receiver.WakeUp();
                t.Yield();
            }
        }
Esempio n. 17
0
        static void MainRun()
        {
            int started = 0;

            while (true)
            {
                if (Scheduler.ThreadCount < 100)
                {
                    MicroThread t = new MicroThread(Work);
                    t.Start();
                    started++;
                }

                Console.WriteLine("Threads {0}, started {1}", Scheduler.ThreadCount, started);

                Scheduler.Yield();
            }
        }
Esempio n. 18
0
        static void Main()
        {
            DateTime time1 = DateTime.Now;

            MicroThread t = new MicroThread(loop);
            t.Start();

            Console.WriteLine("Starting yield test, loops {0}", s_loops);

            Scheduler.Run();

            DateTime time2 = DateTime.Now;

            Console.WriteLine("END {0}", res);

            TimeSpan ts = time2 - time1;

            Console.WriteLine("time {0}ms", ts.TotalMilliseconds);
        }
Esempio n. 19
0
        int ManageSleepers()
        {
            if (m_sleepingThreadCount == 0)
            {
#if EXTRA_CHECKS
                if (m_firstSleepingThread != null)
                {
                    throw new Exception();
                }
#endif
                return(-1);
            }

            long now = DateTime.UtcNow.Ticks;

            MicroThread t = m_firstSleepingThread;

            while (t != null && t.m_wakeTime < now)
            {
                MicroThread next = t.m_next;

                t.m_state = MicroThreadState.Scheduled;
                m_sleepingThreadCount--;

                AddInternal(t);

                t = next;
            }

            m_firstSleepingThread = t;

            if (m_firstSleepingThread == null)
            {
                return(-1);
            }
            else
            {
                long wait = m_firstSleepingThread.m_wakeTime - now;
                return((int)TimeSpan.FromTicks(wait).TotalMilliseconds);
            }
        }
Esempio n. 20
0
        static int Main(string[] args)
        {
            if(args.Length != 1)
            {
                Console.WriteLine("usage: SleepTest <numthreads>");
                return 1;
            }

            s_threads = Int32.Parse(args[0]);

            for (int i = 0; i < s_threads; i++)
            {
                Sleeper s = new Sleeper();
                MicroThread t = new MicroThread(s.Run);
                t.Start();
            }

            Scheduler.Run();

            return 0;
        }
Esempio n. 21
0
        public static void ListenRun()
        {
            MicroSocket listenSocket = new MicroSocket();

            IPEndPoint ep = new IPEndPoint(IPAddress.Any, 12345);
            listenSocket.Bind(ep);
            listenSocket.Listen(10);

            while (true)
            {
                MicroSocket socket = listenSocket.Accept();

                //Console.WriteLine("Accepted a new socket");
                //Console.Write(".");

                s_connectedSockets++;

                Server server = new Server(socket);
                MicroThread t = new MicroThread(server.SocketRun);
                t.Start();
            }
        }
Esempio n. 22
0
        void RemoveCurrentThread()
        {
            if (m_currentThread == m_previousThread)
            {
#if EXTRA_CHECKS
                if (m_scheduledThreadCount != 1)
                {
                    throw new Exception();
                }
#endif
                m_currentThread.m_next = null;
                m_currentThread        = null;
                m_previousThread       = null;
            }
            else
            {
                m_previousThread.m_next = m_currentThread.m_next;
                m_currentThread.m_next  = null;
                m_currentThread         = m_previousThread.m_next;
            }

            m_scheduledThreadCount--;
        }
Esempio n. 23
0
        public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error)
        {
            while (true)
            {
                int received = m_socket.Receive(buffer, offset, size, socketFlags, out error);

                if (error == SocketError.Success)
                {
                    return(received);
                }

                if (error != SocketError.WouldBlock)
                {
                    return(received);
                }

                m_readCS.Enter();
                m_readingThread = MicroThread.CurrentThread;
                m_readingThread.Wait();
                m_readingThread = null;
                m_readCS.Exit();
            }
        }
Esempio n. 24
0
        public bool Connect(IPAddress address, int port)
        {
            Print("Begin connecting to {0}:{1}", address, port);

            try
            {
                m_socket.Connect(new IPEndPoint(address, port));
            }
            catch (SocketException)
            {
                // ignore blocking connect exception. shouldn't there be some other way to do this...
                //Console.WriteLine("exc cont");
            }

            m_writeCS.Enter();
            m_writingThread = MicroThread.CurrentThread;
            m_writingThread.Wait();
            m_writingThread = null;
            m_writeCS.Exit();

            //Console.WriteLine("STATE {0}", m_waitState);

            if ((m_selectStatus & MicroSocketSelectStatus.Error) != 0)
            {
                Console.WriteLine("Connect failed");
                return(false);
            }
            else if ((m_selectStatus & MicroSocketSelectStatus.Write) != 0)
            {
                //Console.WriteLine("Connected!");
                return(true);
            }
            else
            {
                throw new Exception("illegal state");
            }
        }
Esempio n. 25
0
 public static void Add(MicroThread thread)
 {
     s_scheduler.AddInternal(thread);
 }
Esempio n. 26
0
        void SleepInternal(int milliseconds)
        {
            Print("Putting thread {0} to sleep for {1} ms", m_currentThread, milliseconds);

            if (m_currentThread.m_continuation.Store(0) == 0)
            {
            #if MT_TIMING
                m_stopWatch.Stop();
                m_currentThread.m_ticks += m_stopWatch.ElapsedTicks;
            #endif
                MicroThread thread = m_currentThread;

                RemoveCurrentThread();

                thread.m_state = MicroThreadState.Sleeping;

                DateTime wakeDateTime = DateTime.UtcNow + TimeSpan.FromMilliseconds(milliseconds);
                long wakeTime = wakeDateTime.Ticks;
                thread.m_wakeTime = wakeTime;

                if (m_firstSleepingThread == null)
                {
                    m_firstSleepingThread = thread;
                }
                else if (wakeTime <= m_firstSleepingThread.m_wakeTime)
                {
                    thread.m_next = m_firstSleepingThread;
                    m_firstSleepingThread = thread;
                }
                else
                {
                    MicroThread t = m_firstSleepingThread;

                    while (t.m_next != null && wakeTime >= t.m_next.m_wakeTime)
                        t = t.m_next;

                    thread.m_next = t.m_next;
                    t.m_next = thread;
                }

                m_sleepingThreadCount++;

                ScheduleNext();
            }
            else
            {
                Print("Thread {0} woke up from sleep", m_currentThread);

                if (m_currentThread.m_error != null)
                    throw m_currentThread.m_error;
            }
        }
Esempio n. 27
0
        void AddInternal(MicroThread thread)
        {
            if (m_currentThread == null)
            {
            #if EXTRA_CHECKS
                if(m_previousThread != null || m_scheduledThreadCount != 0)
                    throw new Exception();
            #endif
                m_currentThread = thread;
                m_previousThread = thread;
                thread.m_next = thread;
            }
            else
            {
            #if EXTRA_CHECKS
                if(m_previousThread == null || m_scheduledThreadCount == 0)
                    throw new Exception();
            #endif

                m_previousThread.m_next = thread;
                m_previousThread = thread;
                thread.m_next = m_currentThread;
            }

            m_scheduledThreadCount++;
        }
Esempio n. 28
0
 public static void WakeUp(MicroThread thread)
 {
     s_scheduler.WakeUpInternal(thread);
 }
Esempio n. 29
0
 public static void Add(MicroThread thread)
 {
     s_scheduler.AddInternal(thread);
 }
Esempio n. 30
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            MyForm f = new MyForm();
            f.Show();

            new MicroThread(WindowRun).Start();

            for (int i = 0; i < 200; i++)
            {
                Dot d = new Dot(i, 0, Color.Red, f);
                MicroThread t = new MicroThread(d.Run);
                t.Start();
            }

            Scheduler.Run();

            //			Application.Run(f);
        }
Esempio n. 31
0
 public static void WakeUp(MicroThread thread)
 {
     s_scheduler.WakeUpInternal(thread);
 }
Esempio n. 32
0
        public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error)
        {
            int sent = 0;

            while (true)
            {
                sent += m_socket.Send(buffer, offset + sent, size - sent, socketFlags, out error);

                if (error == SocketError.WouldBlock)
                {
                    error = SocketError.Success;
                }

                if (error != SocketError.Success)
                {
                    return sent;
                }

                if (sent < size)
                {
                    m_writeCS.Enter();
                    m_writingThread = MicroThread.CurrentThread;
                    m_writingThread.Wait();
                    m_writingThread = null;
                    m_writeCS.Exit();
                }
                else
                {
                    return sent;
                }
            }
        }
Esempio n. 33
0
        public bool Connect(IPAddress address, int port)
        {
            Print("Begin connecting to {0}:{1}", address, port);

            try
            {
                m_socket.Connect(new IPEndPoint(address, port));
            }
            catch (SocketException)
            {
                // ignore blocking connect exception. shouldn't there be some other way to do this...
                //Console.WriteLine("exc cont");
            }

            m_writeCS.Enter();
            m_writingThread = MicroThread.CurrentThread;
            m_writingThread.Wait();
            m_writingThread = null;
            m_writeCS.Exit();

            //Console.WriteLine("STATE {0}", m_waitState);

            if ((m_selectStatus & MicroSocketSelectStatus.Error) != 0)
            {
                Console.WriteLine("Connect failed");
                return false;
            }
            else if ((m_selectStatus & MicroSocketSelectStatus.Write) != 0)
            {
                //Console.WriteLine("Connected!");
                return true;
            }
            else
            {
                throw new Exception("illegal state");
            }
        }
Esempio n. 34
0
        void WakeUpInternal(MicroThread thread)
        {
            Print("Waking up thread {0}", thread);

            m_waitingThreadCount--;

            thread.m_state = MicroThreadState.Scheduled;

            AddInternal(thread);
        }
Esempio n. 35
0
        // Yields the current thread and schedules next one
        void YieldInternal()
        {
            Print("Yield() on thread {0}", m_currentThread);

            if (m_currentThread.m_continuation.Store(0) == 0)
            {
            #if MT_TIMING
                m_stopWatch.Stop();
                m_currentThread.m_ticks += m_stopWatch.ElapsedTicks;
            #endif
                m_currentThread.m_state = MicroThreadState.Scheduled;

                m_previousThread = m_currentThread;
                m_currentThread = m_currentThread.m_next;

                ScheduleNext();
            }
            else
            {
                // We come here when the thread has resumed
                //Print("Yield() returned, resuming thread {0}", m_currentThread);

                if (m_currentThread.m_error != null)
                    throw m_currentThread.m_error;
            }
        }
Esempio n. 36
0
        public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error)
        {
            while (true)
            {
                int received = m_socket.Receive(buffer, offset, size, socketFlags, out error);

                if (error == SocketError.Success)
                {
                    return received;
                }

                if (error != SocketError.WouldBlock)
                {
                    return received;
                }

                m_readCS.Enter();
                m_readingThread = MicroThread.CurrentThread;
                m_readingThread.Wait();
                m_readingThread = null;
                m_readCS.Exit();
            }
        }
Esempio n. 37
0
        void RunInternal()
        {
            if (m_running == true)
            {
                throw new Exception("Scheduler already running");
            }

            if (m_scheduledThreadCount == 0)
            {
                return;
            }

            m_running = true;

            m_continuation.Mark();

            // status 1 = new thread to be started, m_currentThread has been set
            // status 2 = exiting
            int status = m_continuation.Store(1);

            if (status == 1)
            {
                // status 1 = new thread to be started, m_currentThread has been set

                if (m_currentThread.m_state != MicroThreadState.Starting)
                {
                    throw new Exception(String.Format("illegal state {0}", m_currentThread.m_state));
                }

                try
                {
                    Print("Starting new thread {0}", m_currentThread);
                    m_currentThread.m_state = MicroThreadState.Running;

            #if MT_TIMING
                    m_stopWatch.Reset();
                    m_stopWatch.Start();
            #endif
                    m_currentThread.Run();
            #if MT_TIMING
                    m_stopWatch.Stop();
                    m_currentThread.m_ticks += m_stopWatch.ElapsedTicks;
            #endif

                    // When we are here the thread has finished

                    Print("Thread {0} finished", m_currentThread);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unhandled Exception in thread {0}", m_currentThread);
                    Console.WriteLine("Thread terminated");
                    Console.WriteLine(e.ToString());
                }

                m_currentThread.m_state = MicroThreadState.Stopped;
                m_currentThread.Dispose();

                RemoveCurrentThread();

                ScheduleNext();

                // Never reached
                throw new Exception();
            }
            else if (status == 2)
            {
                m_currentThread = null;
                m_previousThread = null;
                m_scheduledThreadCount = 0;
                m_waitingThreadCount = 0;

                Print("Scheduler exiting");
                return;
            }
            else
            {
                throw new Exception("Urrgh illegal restore status");
            }

            // never reached
            //throw new Exception();
        }
Esempio n. 38
0
        public MicroSocket Accept()
        {
            Print("Begin accepting");

            m_readCS.Enter();
            m_readingThread = MicroThread.CurrentThread;
            m_readingThread.Wait();
            m_readingThread = null;
            m_readCS.Exit();

            Print("Accept returned");

            Socket newSocket = m_socket.Accept();
            MicroSocket s = new MicroSocket(newSocket);
            return s;
        }
Esempio n. 39
0
        void RemoveCurrentThread()
        {
            if (m_currentThread == m_previousThread)
            {
            #if EXTRA_CHECKS
                if(m_scheduledThreadCount != 1)
                    throw new Exception();
            #endif
                m_currentThread.m_next = null;
                m_currentThread = null;
                m_previousThread = null;
            }
            else
            {
                m_previousThread.m_next = m_currentThread.m_next;
                m_currentThread.m_next = null;
                m_currentThread = m_previousThread.m_next;
            }

            m_scheduledThreadCount--;
        }
Esempio n. 40
0
        int ManageSleepers()
        {
            if (m_sleepingThreadCount == 0)
            {
            #if EXTRA_CHECKS
                if(m_firstSleepingThread != null)
                    throw new Exception();
            #endif
                return -1;
            }

            long now = DateTime.UtcNow.Ticks;

            MicroThread t = m_firstSleepingThread;

            while(t != null && t.m_wakeTime < now)
            {
                MicroThread next = t.m_next;

                t.m_state = MicroThreadState.Scheduled;
                m_sleepingThreadCount--;

                AddInternal(t);

                t = next;
            }

            m_firstSleepingThread = t;

            if (m_firstSleepingThread == null)
                return -1;
            else
            {
                long wait = m_firstSleepingThread.m_wakeTime - now;
                return (int)TimeSpan.FromTicks(wait).TotalMilliseconds;
            }
        }
Esempio n. 41
0
        void RunInternal()
        {
            if (m_running == true)
            {
                throw new Exception("Scheduler already running");
            }

            if (m_scheduledThreadCount == 0)
            {
                return;
            }

            m_running = true;

            m_continuation.Mark();

            // status 1 = new thread to be started, m_currentThread has been set
            // status 2 = exiting
            int status = m_continuation.Store(1);

            if (status == 1)
            {
                // status 1 = new thread to be started, m_currentThread has been set

                if (m_currentThread.m_state != MicroThreadState.Starting)
                {
                    throw new Exception(String.Format("illegal state {0}", m_currentThread.m_state));
                }

                try
                {
                    Print("Starting new thread {0}", m_currentThread);
                    m_currentThread.m_state = MicroThreadState.Running;

#if MT_TIMING
                    m_stopWatch.Reset();
                    m_stopWatch.Start();
#endif
                    m_currentThread.Run();
#if MT_TIMING
                    m_stopWatch.Stop();
                    m_currentThread.m_ticks += m_stopWatch.ElapsedTicks;
#endif

                    // When we are here the thread has finished

                    Print("Thread {0} finished", m_currentThread);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unhandled Exception in thread {0}", m_currentThread);
                    Console.WriteLine("Thread terminated");
                    Console.WriteLine(e.ToString());
                }

                m_currentThread.m_state = MicroThreadState.Stopped;
                m_currentThread.Dispose();

                RemoveCurrentThread();

                ScheduleNext();

                // Never reached
                throw new Exception();
            }
            else if (status == 2)
            {
                m_currentThread        = null;
                m_previousThread       = null;
                m_scheduledThreadCount = 0;
                m_waitingThreadCount   = 0;

                Print("Scheduler exiting");
                return;
            }
            else
            {
                throw new Exception("Urrgh illegal restore status");
            }

            // never reached
            //throw new Exception();
        }