{-# LANGUAGE FlexibleInstances
, BangPatterns
, MagicHash
, ScopedTypeVariables
, DeriveDataTypeable
, MultiParamTypeClasses
, CPP
#-}
-- State monad transformer is needed for both step & graph:
#ifndef MODNAME
#define MODNAME Intel.Cnc5
#endif
#define CNC_SCHEDULER 5
#define STEPLIFT S.lift$
#define GRAPHLIFT S.lift$
#define SUPPRESS_runGraph
#include "Cnc.Header.hs"
------------------------------------------------------------
-- Version 5a: A global work queue.
-- (This version has been disabled/removed.)
-- This version uses a global work-queue.
-- Here laziness comes in handy, we queue the thunks.
#include "shared_5_6.hs"
------------------------------------------------------------
-- Version 5: Thread spammer -- fork a permanent worker every time we block.
-- TODO: we should do a better job here by using a monad transformer on top of IO:
-- But if we must keep the same CnC interface... This is expedient:
get col tag = ver5_6_core_get (return ()) col tag
-- At finalize time we set up the workers and run them.
finalize finalAction =
do joiner <- S.lift$ newChan
let worker =
do x <- S.lift$ tryPop global_stack
case x of
Nothing -> S.lift$ writeChan joiner ()
Just action -> do action
worker
ver5_6_core_finalize joiner finalAction worker
------------------------------------------------------------
quiescence_support = True
type Item = MVar
newItem = STEPLIFT newEmptyMVar
readItem = grabWithBackup (return ())
putItem mv x =
do b <- STEPLIFT tryPutMVar mv x
if b then return ()
else error "Violation of single assignment rule; second put on Item!"