packages feed

priority-sync 0.1.0.0 → 0.1.0.1

raw patch · 2 files changed

+33/−50 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Tests.hs view
@@ -140,26 +140,26 @@        atomically $ flip unless retry . (== 0) =<< activity pool        withMVar counter $ putStrLn . show -_example1 :: IO ()-_example1 =-    do (pool :: TaskPool () ()) <- simpleTaskPool-       forkIO $ claim Acquire pool $ putStrLn "Hello world!"-       forkIO $ claim Acquire pool $ putStrLn "Goodbye world!"+example :: IO ()+example =+    do let expensiveTask = threadDelay 1000000+       pool <- simpleTaskPool+       forkIO $ claim Acquire (schedule pool 1) $ putStrLn "Task 1 started . . ." >> expensiveTask >> putStrLn "Task 1 completed."+       forkIO $ claim Acquire (schedule pool 3) $ putStrLn "Task 3 started . . ." >> expensiveTask >> putStrLn "Task 3 completed."+       forkIO $ claim Acquire (schedule pool 2) $ putStrLn "Task 2 started . . ." >> expensiveTask >> putStrLn "Task 2 completed."+       threadDelay 100000  -- contrive to wait for all tasks to become enqueued+       putStrLn "Starting pool: "        startQueue pool-       -_example2 :: IO ()-_example2 =-    do prio_pool <- simpleTaskPool-       forkIO $ claim Acquire (schedule prio_pool 1) $ putStrLn "Hello world!"-       forkIO $ claim Acquire (schedule prio_pool 2) $ putStrLn "Goodbye world!"-       startQueue prio_pool+       threadDelay 4000000 -- contrive to wait for all tasks to become dequeued  main :: IO () main =     do args <- liftM (\args -> if Prelude.null args then ["help"] else args) getArgs        let shouldRun s@('s':'t':'r':'e':'s':'s':_) = s `elem` args+           shouldRun "example" = "example" `elem` args            shouldRun s = s `elem` args || "all" `elem` args        when (shouldRun "help") $ putStrLn "tests: all, testRoom, testMaxThreads, testQueue, testTaskPool, stressInt, stressIntFair, stressInt2, stressUnit, stressUnitFILO, stressUnitFair"+       when (shouldRun "example") $ example        when (shouldRun "testRoom") testRoom        when (shouldRun "testMaxThreads") testMaxThreads        when (shouldRun "testQueue") testQueue
priority-sync.cabal view
@@ -1,5 +1,5 @@ name:                priority-sync-version:             0.1.0.0+version:             0.1.0.1 license:             BSD3 license-file:        LICENSE author:              Christopher Lane Hinson@@ -7,54 +7,37 @@ stability:           Unstable  category:            Concurrency-synopsis:            Task prioritization.-description:         Implements cooperative task prioritization with room synchronization.-                     .-                     In the simplest usage, for an unprioritized FILO queue, only three operations are needed: 'simpleTaskPool', 'claim', and 'startQueue'.+synopsis:            Cooperative task prioritization.+description:         In a simple use case, we want to run some expensive tasks in prioritized order, so that only one task is running on each+                     CPU (or hardware thread) at any time.   For this simple case, four operations are needed: 'simpleTaskPool', +                     'schedule', 'claim', and 'startQueue'.                      .                      @-                     (pool :: TaskPool () ()) <- simpleTaskPool-                     forkIO $ claim Acquire pool $ putStrLn "Hello world!"-                     forkIO $ claim Acquire pool $ putStrLn "Goodbye world!"+                     let expensiveTask = threadDelay 1000000+                     pool <- simpleTaskPool+                     forkIO $ claim Acquire (schedule pool 1) $ putStrLn \"Task 1 started . . .\" >> expensiveTask >> putStrLn \"Task 1 completed.\"+                     forkIO $ claim Acquire (schedule pool 3) $ putStrLn \"Task 3 started . . .\" >> expensiveTask >> putStrLn \"Task 3 completed.\"+                     forkIO $ claim Acquire (schedule pool 2) $ putStrLn \"Task 2 started . . .\" >> expensiveTask >> putStrLn \"Task 2 completed.\"+                     threadDelay 100000  -- contrive to wait for all tasks to become enqueued+                     putStrLn \"Starting pool: \"                      startQueue pool+                     threadDelay 4000000 -- contrive to wait for all tasks to become dequeued                      @                      .-                     For a simple prioritized queue, the 'schedule' operation introduces the priority.  Prioritization is always least-first.+                     A 'TaskPool' combines 'Room's and 'Queue's in an efficient easy-to-use-interface.                      .-                     @-                     prio_pool <- simpleTaskPool-                     forkIO $ claim Acquire (schedule prio_pool 1) $ putStrLn "Hello world!"-                     forkIO $ claim Acquire (schedule prio_pool 2) $ putStrLn "Goodbye world!"-                     startQueue prio_pool-                     @+                     'Room's provide fully reentrant synchronization to any number of threads based on arbitrary resource constraints.+                     For example, the 'Room' from a 'simpleTaskPool' is constrained by 'GHC.numCapabilities'.                      .-                     Note that if you run these programs with @+RTS -N2@ or greater, the 'claim' operations may be processed in any order, since 'simpleTaskQueue' detects-                     the number of capabilities and schedules tasks on each.+                     'Queue's provide task prioritization.  A 'Queue' systematically examines (to a configurable depth) all waiting threads with their+                     priorities and resource constraints and wakes the most eagerly prioritized thread whose constraints can be satisfied.                      .                      'TaskPool's are not thread pools.  The concept is similar to IO Completion Ports.  There are no worker threads.  If a number of threads are waiting,-                     the thread that is most likely to be processed next is woken and temporarily serves as a working thread.  'TaskPool's are backed by carefully-                     written STM (software transactional memory) transactions.-                     .-                     A salient feature is that, because any thread can participate, a 'TaskPool' supports both bound threads and threads created with 'forkOnIO'.-                     .-                     For applications that have complex resource constraints, it is possible to create a 'Room' to model each constraint.  'Room's are fully reentrant,-                     and an arbitrary number of threads can 'claim' a 'Room' according to arbitrary rules, or 'RoomConstraint's.  In the simple usage above,-                     a single room represents the number of capabilities available to the GHC runtime.-                     .-                     Whenever a thread attempts to acquire a 'Room', a 'Claim' is generated that represents that attempt.  The 'Claim' can be approved immediately,-                     or it can be approved at the whim of another thread that has access to that 'Claim'.  This means that 'Room's can be constructed in such-                     a way that 'Claim's are approved only when a third party thread sees that the resource constraint modeled by that 'Room' has been satisfied.-                     .-                     The rules for generating and approving 'Claim's are described by a 'RoomContext'.  By default, 'Claim's are approved immediately if their-                     associated 'RoomConstraint's have been satisfied, but when a 'TaskPool' is introduced approval is deferred for prioritization.-                     .-                     'Room' constraints are completely advisory: any task may claim any 'Room' without restriction at any time by using the 'UnconstrainedRoomContext'.+                     the thread that is most likely to be processed next is woken and temporarily serves as a working thread.                        .-                     'Queue's are used to prioritize tasks.  Even if you have no need for prioritization, a 'Queue' ensures that only one thread is woken up-                     when a 'Room' becomes available.  A 'Queue' systematically examines to a configurable depth all waiting threads with their priorities-                     and constraints and wakes the most eagerly prioritized thread whose constraints can be satisfied.+                     'Room's, 'Queue's, and 'TaskPool's are backed by carefully written STM (software transactional memory) transactions.                      .-                     A 'TaskPool' combines 'Room's and 'Queue's in an efficient, easy-to-use interface.+                     A salient feature is that, because any thread can participate, a 'TaskPool' supports both bound threads and threads created with 'forkOnIO'.                      .                      The git repository is available at <http://www.downstairspeople.org/git/priority-sync.git>.