diff options
Diffstat (limited to 'rts/posix/Select.c')
-rw-r--r-- | rts/posix/Select.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/rts/posix/Select.c b/rts/posix/Select.c index dc40b706d8..a2a66a6b8a 100644 --- a/rts/posix/Select.c +++ b/rts/posix/Select.c @@ -2,7 +2,10 @@ * * (c) The GHC Team 1995-2002 * - * Support for concurrent non-blocking I/O and thread waiting. + * Support for concurrent non-blocking I/O and thread waiting in the + * non-threaded RTS. In the threded RTS, this file is not used at + * all, instead we use the IO manager thread implemented in Haskell in + * the base package. * * ---------------------------------------------------------------------------*/ @@ -39,21 +42,39 @@ #if !defined(THREADED_RTS) -/* - * The threaded RTS uses an IO-manager thread in Haskell instead (see GHC.Conc) - */ - -#define LowResTimeToTime(t) (USToTime((t) * 10000)) +// The target time for a threadDelay is stored in a one-word quantity +// in the TSO (tso->block_info.target). On a 32-bit machine we +// therefore can't afford to use nanosecond resolution because it +// would overflow too quickly, so instead we use millisecond +// resolution. + +#if SIZEOF_VOID_P == 4 +#define LowResTimeToTime(t) (USToTime((t) * 1000)) +#define TimeToLowResTimeRoundDown(t) (TimeToUS(t) / 1000) +#define TimeToLowResTimeRoundUp(t) ((TimeToUS(t) + 1000-1) / 1000) +#else +#define LowResTimeToTime(t) (t) +#define TimeToLowResTimeRoundDown(t) (t) +#define TimeToLowResTimeRoundUp(t) (t) +#endif /* * Return the time since the program started, in LowResTime, * rounded down. - * - * This is only used by posix/Select.c. It should probably go away. */ -LowResTime getourtimeofday(void) +static LowResTime getLowResTimeOfDay(void) +{ + return TimeToLowResTimeRoundDown(stat_getElapsedTime()); +} + +/* + * For a given microsecond delay, return the target time in LowResTime. + */ +LowResTime getDelayTarget (HsInt us) { - return TimeToUS(stat_getElapsedTime()) / 10000; + // round up the target time, because we never want to sleep *less* + // than the desired amount. + return TimeToLowResTimeRoundUp(stat_getElapsedTime() + USToTime(us)); } /* There's a clever trick here to avoid problems when the time wraps @@ -136,7 +157,7 @@ awaitEvent(rtsBool wait) */ do { - now = getourtimeofday(); + now = getLowResTimeOfDay(); if (wakeUpSleepingThreads(now)) { return; } @@ -255,7 +276,7 @@ awaitEvent(rtsBool wait) /* check for threads that need waking up */ - wakeUpSleepingThreads(getourtimeofday()); + wakeUpSleepingThreads(getLowResTimeOfDay()); /* If new runnable threads have arrived, stop waiting for * I/O and run them. |