diff options
author | Simon Marlow <simonmar@microsoft.com> | 2006-04-07 02:05:11 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2006-04-07 02:05:11 +0000 |
commit | 0065d5ab628975892cea1ec7303f968c3338cbe1 (patch) | |
tree | 8e2afe0ab48ee33cf95009809d67c9649573ef92 /rts/win32/Ticker.c | |
parent | 28a464a75e14cece5db40f2765a29348273ff2d2 (diff) | |
download | haskell-0065d5ab628975892cea1ec7303f968c3338cbe1.tar.gz |
Reorganisation of the source tree
Most of the other users of the fptools build system have migrated to
Cabal, and with the move to darcs we can now flatten the source tree
without losing history, so here goes.
The main change is that the ghc/ subdir is gone, and most of what it
contained is now at the top level. The build system now makes no
pretense at being multi-project, it is just the GHC build system.
No doubt this will break many things, and there will be a period of
instability while we fix the dependencies. A straightforward build
should work, but I haven't yet fixed binary/source distributions.
Changes to the Building Guide will follow, too.
Diffstat (limited to 'rts/win32/Ticker.c')
-rw-r--r-- | rts/win32/Ticker.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/rts/win32/Ticker.c b/rts/win32/Ticker.c new file mode 100644 index 0000000000..ab791d8dc7 --- /dev/null +++ b/rts/win32/Ticker.c @@ -0,0 +1,124 @@ +/* + * RTS periodic timers. + * + */ +#include "Rts.h" +#include "Timer.h" +#include "Ticker.h" +#include <windows.h> +#include <stdio.h> +#include <process.h> +#include "OSThreads.h" + +/* + * Provide a timer service for the RTS, periodically + * notifying it that a number of 'ticks' has passed. + * + */ + +/* To signal shutdown of the timer service, we use a local + * event which the timer thread listens to (and stopVirtTimer() + * signals.) + */ +static HANDLE hStopEvent = INVALID_HANDLE_VALUE; +static HANDLE tickThread = INVALID_HANDLE_VALUE; + +static TickProc tickProc = NULL; + +/* + * Ticking is done by a separate thread which periodically + * wakes up to handle a tick. + * + * This is the portable way of providing a timer service under + * Win32; features like waitable timers or timer queues are only + * supported by a subset of the Win32 platforms (notably not + * under Win9x.) + * + */ +static +unsigned +WINAPI +TimerProc(PVOID param) +{ + int ms = (int)param; + DWORD waitRes; + + /* interpret a < 0 timeout period as 'instantaneous' */ + if (ms < 0) ms = 0; + + while (1) { + waitRes = WaitForSingleObject(hStopEvent, ms); + + switch (waitRes) { + case WAIT_OBJECT_0: + /* event has become signalled */ + tickProc = NULL; + CloseHandle(hStopEvent); + return 0; + case WAIT_TIMEOUT: + /* tick */ + tickProc(0); + break; + case WAIT_FAILED: { + DWORD dw = GetLastError(); + fprintf(stderr, "TimerProc: wait failed -- error code: %lu\n", dw); fflush(stderr); + break; + } + default: + fprintf(stderr, "TimerProc: unexpected result %lu\n", waitRes); fflush(stderr); + break; + } + } + return 0; +} + + +int +startTicker(nat ms, TickProc handle_tick) +{ + unsigned threadId; + /* 'hStopEvent' is a manual-reset event that's signalled upon + * shutdown of timer service (=> timer thread.) + */ + hStopEvent = CreateEvent ( NULL, + TRUE, + FALSE, + NULL); + if (hStopEvent == INVALID_HANDLE_VALUE) { + return 0; + } + tickProc = handle_tick; + tickThread = (HANDLE)(long)_beginthreadex( NULL, + 0, + TimerProc, + (LPVOID)ms, + 0, + &threadId); + return (tickThread != 0); +} + +int +stopTicker(void) +{ + // We must wait for the ticker thread to terminate, since if we + // are in a DLL that is about to be unloaded, the ticker thread + // cannot be allowed to return to a missing DLL. + + if (hStopEvent != INVALID_HANDLE_VALUE && + tickThread != INVALID_HANDLE_VALUE) { + DWORD exitCode; + SetEvent(hStopEvent); + while (1) { + WaitForSingleObject(tickThread, 20); + if (!GetExitCodeThread(tickThread, &exitCode)) { + return 1; + } + if (exitCode != STILL_ACTIVE) { + tickThread = INVALID_HANDLE_VALUE; + return 0; + } + TerminateThread(tickThread, 0); + } + } + return 0; +} |