Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
quasar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jens Nolte
quasar
Commits
84958a10
Commit
84958a10
authored
3 years ago
by
Jens Nolte
Browse files
Options
Downloads
Patches
Plain Diff
Implement disposable for POSIX timer, implement settime and more clocks
parent
b3da1263
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Quasar/Timer/PosixTimer.hsc
+91
-48
91 additions, 48 deletions
src/Quasar/Timer/PosixTimer.hsc
with
91 additions
and
48 deletions
src/Quasar/Timer/PosixTimer.hsc
+
91
−
48
View file @
84958a10
{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE CApiFFI #-}
module Quasar.Timer.PosixTimer (
module Quasar.Timer.PosixTimer (
CTimeSpec,
ClockId(..),
CITimerSpec,
TimerSetTimeMode(..),
boottime,
CTimeSpec(..),
CITimerSpec(..),
newPosixTimer,
newUnmanagedPosixTimer,
setPosixTimer,
setPosixIntervalTimer,
) where
) where
import Control.Concurrent
import Control.Concurrent
...
@@ -11,6 +16,7 @@ import Foreign
...
@@ -11,6 +16,7 @@ import Foreign
import Foreign.C
import Foreign.C
import Quasar.Disposable
import Quasar.Disposable
import Quasar.Prelude
import Quasar.Prelude
import Quasar.ResourceManager
import System.Posix.Types
import System.Posix.Types
#include <signal.h>
#include <signal.h>
...
@@ -36,6 +42,51 @@ foreign import ccall "wrapper"
...
@@ -36,6 +42,51 @@ foreign import ccall "wrapper"
type SigevNotifyFunction = (Ptr Void -> IO ())
type SigevNotifyFunction = (Ptr Void -> IO ())
data ClockId
= Realtime
| Monotonic
| ProcessCputime
| ThreadCputime
| Boottime
| RealtimeAlarm
| BoottimeAlarm
| Tai
toCClockId :: ClockId -> CClockId
toCClockId Realtime = c_CLOCK_REALTIME
toCClockId Monotonic = c_CLOCK_MONOTONIC
toCClockId ProcessCputime = c_CLOCK_PROCESS_CPUTIME_ID
toCClockId ThreadCputime = c_CLOCK_THREAD_CPUTIME_ID
toCClockId Boottime = c_CLOCK_BOOTTIME
toCClockId RealtimeAlarm = c_CLOCK_REALTIME_ALARM
toCClockId BoottimeAlarm = c_CLOCK_BOOTTIME_ALARM
toCClockId Tai = c_CLOCK_TAI
foreign import capi "time.h value CLOCK_REALTIME"
c_CLOCK_REALTIME :: CClockId
foreign import capi "time.h value CLOCK_MONOTONIC"
c_CLOCK_MONOTONIC :: CClockId
foreign import capi "time.h value CLOCK_PROCESS_CPUTIME_ID"
c_CLOCK_PROCESS_CPUTIME_ID :: CClockId
foreign import capi "time.h value CLOCK_THREAD_CPUTIME_ID"
c_CLOCK_THREAD_CPUTIME_ID :: CClockId
foreign import capi "time.h value CLOCK_BOOTTIME"
c_CLOCK_BOOTTIME :: CClockId
foreign import capi "time.h value CLOCK_REALTIME_ALARM"
c_CLOCK_REALTIME_ALARM :: CClockId
foreign import capi "time.h value CLOCK_BOOTTIME_ALARM"
c_CLOCK_BOOTTIME_ALARM :: CClockId
foreign import capi "time.h value CLOCK_TAI"
c_CLOCK_TAI :: CClockId
data {-# CTYPE "struct timespec" #-} CTimeSpec = CTimeSpec {
data {-# CTYPE "struct timespec" #-} CTimeSpec = CTimeSpec {
tv_sec :: CTime,
tv_sec :: CTime,
...
@@ -81,9 +132,6 @@ instance Storable CITimerSpec where
...
@@ -81,9 +132,6 @@ instance Storable CITimerSpec where
defaultCITimerSpec :: CITimerSpec
defaultCITimerSpec :: CITimerSpec
defaultCITimerSpec = CITimerSpec defaultCTimeSpec defaultCTimeSpec
defaultCITimerSpec = CITimerSpec defaultCTimeSpec defaultCTimeSpec
foreign import capi "time.h value CLOCK_BOOTTIME"
c_CLOCK_BOOTTIME :: CClockId
foreign import capi "time.h timer_create"
foreign import capi "time.h timer_create"
c_timer_create :: CClockId -> Ptr CSigEvent -> Ptr CTimer -> IO CInt
c_timer_create :: CClockId -> Ptr CSigEvent -> Ptr CTimer -> IO CInt
...
@@ -94,17 +142,30 @@ foreign import capi "time.h timer_settime"
...
@@ -94,17 +142,30 @@ foreign import capi "time.h timer_settime"
foreign import capi "time.h timer_delete"
foreign import capi "time.h timer_delete"
c_timer_delete :: CTimer -> IO CInt
c_timer_delete :: CTimer -> IO CInt
foreign import capi "time.h value TIMER_ABSTIME"
c_TIMER_ABSTIME :: CInt
data TimerSetTimeMode = TimeRelative | TimeAbsolute
toCSetTimeFlags :: TimerSetTimeMode -> CInt
toCSetTimeFlags TimeRelative = 0
toCSetTimeFlags TimeAbsolute = c_TIMER_ABSTIME
data PosixTimer = PosixTimer {
data PosixTimer = PosixTimer {
ctimer :: CTimer,
ctimer :: CTimer,
callbackPtr :: (FunPtr SigevNotifyFunction)
disposable :: Disposable
}
}
instance IsDisposable PosixTimer where
instance IsDisposable PosixTimer where
toDisposable =
undefined
toDisposable =
disposable
newUnmanagedPosixTimer :: CClockId -> IO () -> IO PosixTimer
newPosixTimer :: MonadResourceManager m => ClockId -> IO () -> m PosixTimer
newPosixTimer clockId callback = registerNewResource do
liftIO $ newUnmanagedPosixTimer clockId callback
newUnmanagedPosixTimer :: ClockId -> IO () -> IO PosixTimer
newUnmanagedPosixTimer clockId callback = runInBoundThread do
newUnmanagedPosixTimer clockId callback = runInBoundThread do
callbackPtr <- mkSigevNotifyFunction (const callback)
callbackPtr <- mkSigevNotifyFunction (const callback)
...
@@ -112,51 +173,33 @@ newUnmanagedPosixTimer clockId callback = runInBoundThread do
...
@@ -112,51 +173,33 @@ newUnmanagedPosixTimer clockId callback = runInBoundThread do
alloca \sigevent -> do
alloca \sigevent -> do
poke sigevent $ CSigEventThreadCallback callbackPtr
poke sigevent $ CSigEventThreadCallback callbackPtr
throwErrnoIfMinus1_ "timer_create" do
throwErrnoIfMinus1_ "timer_create" do
c_timer_create
c_CLOCK_BOOTTIME
sigevent ctimerPtr
c_timer_create
(toCClockId clockId)
sigevent ctimerPtr
peek ctimerPtr
peek ctimerPtr
pure $ PosixTimer {
ctimer
,
callbackPtr
}
disposable <- newDisposable (delete
ctimer callbackPtr
)
setPosixTimer :: PosixTimer -> Maybe CTimeSpec -> IO ()
pure $ PosixTimer { ctimer, disposable }
setPosixTimer PosixTimer{ctimer} timeSpec = do
where
alloca \newValue -> do
delete :: CTimer -> FunPtr SigevNotifyFunction -> IO ()
poke newValue $ defaultCITimerSpec {
delete ctimer callbackPtr = do
it_value = fromMaybe defaultCTimeSpec timeSpec
c_timer_delete ctimer
-- "The treatment of any pending signal generated by the deleted timer is unspecified."
freeHaskellFunPtr callbackPtr
setPosixTimer :: PosixTimer -> TimerSetTimeMode -> CTimeSpec -> IO ()
setPosixTimer timer mode timeSpec = setPosixIntervalTimer timer mode itspec
where
itspec = defaultCITimerSpec {
it_value = timeSpec
}
}
throwErrnoIfMinus1_ "timer_settime" do
c_timer_settime ctimer 0 newValue nullPtr
setPosixIntervalTimer :: PosixTimer -> CITimerSpec -> IO ()
setPosixIntervalTimer :: PosixTimer ->
TimerSetTimeMode ->
CITimerSpec -> IO ()
setPosixIntervalTimer PosixTimer{ctimer} iTimerSpec = do
setPosixIntervalTimer PosixTimer{ctimer}
mode
iTimerSpec = do
alloca \newValue -> do
alloca \newValue -> do
poke newValue iTimerSpec
poke newValue iTimerSpec
throwErrnoIfMinus1_ "timer_settime" do
throwErrnoIfMinus1_ "timer_settime" do
c_timer_settime ctimer 0 newValue nullPtr
c_timer_settime ctimer (toCSetTimeFlags mode) newValue nullPtr
boottime :: IO ()
boottime = runInBoundThread do
callbackPtr <- mkSigevNotifyFunction callback
ctimer <- alloca \ctimerPtr -> do
disarmPosixTimer :: PosixTimer -> IO ()
alloca \sigevent -> do
disarmPosixTimer timer = setPosixIntervalTimer timer TimeRelative defaultCITimerSpec
poke sigevent $ CSigEventThreadCallback callbackPtr
throwErrnoIfMinus1_ "timer_create" do
c_timer_create c_CLOCK_BOOTTIME sigevent ctimerPtr
peek ctimerPtr
alloca \newValue -> do
poke newValue oneSecond
throwErrnoIfMinus1_ "timer_settime" do
c_timer_settime ctimer 0 newValue nullPtr
where
oneSecond = defaultCITimerSpec {
it_value = defaultCTimeSpec {
tv_sec = 1
}
}
callback :: Ptr Void -> IO ()
callback _ = traceIO "callback"
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment