Skip to content

Commit

Permalink
fix(runtime): make benchmark pass (still doesn't do much though)
Browse files Browse the repository at this point in the history
  • Loading branch information
symbiont-stevan-andjelkovic committed Jun 30, 2021
1 parent bcbc854 commit f9ee761
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 34 deletions.
6 changes: 5 additions & 1 deletion src/runtime-prototype/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,8 @@ cabal test

#### How to run benchmarks

`cabal bench`
```bash
cabal configure bench \
--ghc-options='-threaded -rtsopts -with-rtsopts=-N'
cabal bench
```
86 changes: 54 additions & 32 deletions src/runtime-prototype/bench/Main.hs
Original file line number Diff line number Diff line change
@@ -1,53 +1,75 @@
module Main where

import Control.Monad
import Control.Exception
import Control.Concurrent
import Control.Concurrent.Async
import Data.Atomics.Counter
import Data.IORef

import StuntDouble

------------------------------------------------------------------------

client :: AtomicCounter -> IORef Bool -> IO ()
client total shutdown = go
client :: AtomicCounter -> IO ()
client total = forever go
where
go :: IO ()
go = do
b <- readIORef shutdown
if b then return ()
else do
-- generate client req
-- execute client req
incrCounter_ 1 total
-- generate client req
-- execute client req
-- XXX: remove
threadDelay 100000 -- 100ms
incrCounter_ 1 total

reporter :: AtomicCounter -> IO ()
reporter total = go 0
where
go :: Int -> IO ()
go last = do
threadDelay 1000000 -- 1s
tot <- readCounter total
putStrLn (concat ["did ", show (tot - last), " ops"])
go tot

before :: Int -> AtomicCounter -> IO [Async ()]
before numberOfClients total =
mapM (\i -> async ((if i == 0 then reporter else client) total))
[0..numberOfClients]

data StoppingCriteria
= MaxDurationInSecs Int
| MaxOperations Int
| WaitForCtrlCSignal

run :: AtomicCounter -> StoppingCriteria -> IO ()
run _total (MaxDurationInSecs s) = threadDelay (s * 1000000)
run total (MaxOperations maxOps) = go
where
go :: IO ()
go = do
c <- readCounter total
if c < maxOps
then do
threadDelay (50 * 1000) -- 50 ms
go
else return ()
run _total WaitForCtrlCSignal = threadDelay maxBound

reporter :: IO ()
reporter = return ()
after :: AtomicCounter -> [Async ()] -> IO ()
after total pids = do
mapM_ cancel pids
tot <- readCounter total
putStrLn ""
putStrLn ("total ops: " ++ show tot ++ " ops")

main :: IO ()
main = do
-- spawn event loop
-- deploy SUT
let n = 4
maxOps = 100
let numberOfClients = 4
stop = MaxOperations 100
total <- newCounter 0
shutdown <- newIORef False
pids <- mapM (\i -> async (if i == 0 then reporter else client total shutdown)) [0..n]
go total maxOps shutdown
mapM_ wait pids
-- print stats
where
go :: AtomicCounter -> Int -> IORef Bool -> IO ()
go total maxOps shutdown = go'
where
go' :: IO ()
go' = do
c <- readCounter total
if c < maxOps
then do
threadDelay (50 * 1000) -- 50 ms
go'
-- else if maxDuration has elapsed, flip shutdown
else do
writeIORef shutdown True
bracket
(before numberOfClients total)
(after total)
(const (run total stop))
3 changes: 2 additions & 1 deletion src/runtime-prototype/stunt-double.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,6 @@ benchmark bench
, stunt-double

-- https://ghc.gitlab.haskell.org/ghc/doc/users_guide/using-concurrent.html
ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-qa -with-rtsopts=-qm
-- -with-rtsopts=-qa -with-rtsopts=-qm
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010

0 comments on commit f9ee761

Please sign in to comment.