stdio-0.2.0.0: A simple and high performance IO toolkit for Haskell

Std.IO.LowResTimer

Description

This module provide low resolution (0.1s) timers using a timing wheel of size 128 per capability, each timer thread will automatically started or stopped based on demannd. register or cancel a timeout is O(1), and each step only need scan n/128 items given timers are registered in an even fashion.

This timer is particularly suitable for high concurrent approximated IO timeout scheduling. You should not rely on it to provide timing information since it's very inaccurate.

Reference:

Synopsis

# low resolution timers

Arguments

 :: Int timeout in unit of 0.1s -> IO () the action you want to perform, it should not block -> IO LowResTimer

Register a new timer on current capability's timer manager, start the timing wheel if it's not turning.

If the action could block, you may want to run it in another thread. Example to kill a thread after 10s:

  registerLowResTimer 100 (forkIO \$ killThread tid)


Arguments

 :: Int timeout in unit of 0.1s -> IO () the action you want to perform, it should not block -> IO ()

void (registerLowResTimer t action)

Arguments

 :: LowResTimerManager a low resolution timer manager -> Int timeout in unit of 0.1s -> IO () the action you want to perform, it should not block -> IO LowResTimer

Same as registerLowResTimer, but allow you choose timer manager.

Timer registered by registerLowResTimer or registerLowResTimerOn.

Query how many seconds remain before timer firing.

A return value <= 0 indictate the timer is firing or fired.

Cancel a timer, return the remaining ticks.

This function have no effect after the timer is fired.

void . cancelLowResTimer

Arguments

 :: Int timeout in unit of 0.1s -> IO a -> IO (Maybe a)

similar to timeout, this function put a limit on time which an IO can consume.

Note timeoutLowRes is also implemented with Exception underhood, which can have some surprising effects on some devices, e.g. use timeoutLowRes with reading or writing on UVStreams will close the UVStream once a reading or writing is not able to be done in time.

Arguments

 :: HasCallStack => Int timeout in unit of 0.1s -> IO a -> IO a

similar to timeoutLowRes, but raise a TimeOutException instead of return Nothing if timeout.

Arguments

 :: Int cache time in unit of 0.1s -> IO a the original IO action -> IO (IO a) throttled IO action

Cache result of an IO action for give time t.

This combinator is useful when you want to share IO result within a period, the action will be called on demand, and the result will be cached for t milliseconds.

One common way to get a shared periodical updated value is to start a seperate thread and do calculation periodically, but doing that will stop system from being idle, which stop idle GC from running, and in turn disable deadlock detection, which is too bad. This function solves that.

Arguments

 :: Int cache time in unit of 0.1s -> IO () the original IO action -> IO (IO ()) throttled IO action

Throttle an IO action without caching result.

The IO action will run at leading edge. i.e. once run, during following (t/10)s throttled action will no-ops.

Note the action will run in the calling thread.

Arguments

 :: Int -> IO () the original IO action -> IO (IO ()) throttled IO action

Similar to throttle_ but run action in trailing edge

The IO action will run at trailing edge. i.e. no matter how many times throttled action are called, original action will run only once after (t/10)s.

Note the action will be run in a new created thread.

# low resolution timer manager

Get a LowResTimerManager for current thread.

Check if a timer manager's wheel is turning

This is mostly for testing purpose.

Create new low resolution timer manager on capability change.

Since low resolution timer manager is not hooked into RTS, you're responsible to call this function after you call setNumCapabilities to match timer manager array size with new capability number.

This is not a must though, when we fetch timer manager we always take a modulo.