úÎ]bXÕN      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMnon-portable (concurrency) experimentalhaskell@list.mightyreason.com Safe-InferedNNNnon-portable (concurrency) experimentalhaskell@list.mightyreason.com Safe-InferedZCreate a new semaphore with the given argument as the initially available quantity. This M allows new semaphores to start with a negative, zero, or positive quantity. \Try to take a unit of value from the semaphore. This succeeds when the current quantity is F positive, and then reduces the quantity by one. Otherwise this will O. This will never ` result in a negative quantity. If several threads are retying then which one succeeds next is . undefined -- an unlucky thread might starve. _Try to take the given value from the semaphore. This succeeds when the quantity is greater or a equal to the given value, and then subtracts the given value from the quantity. Otherwise this  will OS. This will never result in a negative quantity. If several threads are retrying N then which one succeeds next is undefined -- an unlucky thread might starve. ^Signal that single unit of the semaphore is available. This increases the available quantity  by one. _Signal that many units of the semaphore are available. This changes the available quantity by  adding the passed size. Non-retrying version of . ` tryWait s` is defined as `tryN s 1` UNon-retrying version of waitN. It either takes the quantity from the semaphore like  waitN and returns `Just value taken`4 or finds insufficient quantity to take and returns  Nothing ZReturn the current quantity in the semaphore. This is potentially useful in a larger STM  transaciton and less useful as ` atomically getValueSem :: IO Int` due to race conditions.   non-portable (concurrency) experimentalhaskell@list.mightyreason.com Safe-Infered ZCreate a new semaphore with the given argument as the initially available quantity. This M allows new semaphores to start with a negative, zero, or positive quantity. *It is recommended that all paired uses of   and  use the with bracketed form  to ensure exceptions safety. *It is recommended that all paired uses of   and  use the withN - bracketed form to ensure exceptions safety. \Try to take a unit of value from the semaphore. This succeeds when the current quantity is P positive, and then reduces the quantity by one. Otherwise this will block and retry until it ` succeeds or is killed. This will never result in a negative quantity. If several threads are V retying then which one succeeds next is undefined -- an unlucky thread might starve. _Try to take the given value from the semaphore. This succeeds when the quantity is greater or a equal to the given value, and then subtracts the given value from the quantity. Otherwise this  will block and retryG until it succeeds or is killed. This will never result in a negative \ quantity. If several threads are retrying then which one succeeds next is undefined -- an  unlucky thread might starve. ^Signal that single unit of the semaphore is available. This increases the available quantity  by one. _Signal that many units of the semaphore are available. This changes the available quantity by  adding the passed size. Non-waiting version of wait. ` tryWait s` is defined as ` tryWaitN s 1` TNon-waiting version of waitN. It either takes the quantity from the semaphore like  waitN and returns `Just value taken`4 or finds insufficient quantity to take and returns  Nothing fThis returns the current quantity in the semaphore. This is diffucult to use due to race conditions.      Safe-Infered eObservable state of holder(s) of lock(s). The W returns a pair of Ints where the first is number of _ read locks (at least 0) and the second is the number of write locks held (at least 1). The R M returns a map from thread id to the number of read locks held (at least 1). !Operation in which error arose, 3Exception type thrown or returned by this module. " Impossible"! conditions get the error thrown - and usage problems get the error returned.  Opaque type of the fair RWLock. &?Create a new RWLock which starts in a free and unlocked state. 'WThis is by far the preferred way to acquire a read lock. This uses bracket_ to ensure M acquireRead and releaseRead are called correctly around the passed command. `This ought to ensure releaseRead will not return a (Left error), but if it does then this error  will be thrown. *This can block and be safely interrupted. (XThis is by far the preferred way to acquire a write lock. This uses bracket_ to ensure O acquireWrite and releaseWrite are called correctly around the passed command. aThis ought to ensure releaseWrite will not return a (Left error), but if it does then this error  will be thrown. *This can block and be safely interrupted. )^Observe which threads are holding the lock and which threads are waiting (in order). This is ( particularly useful for writing tests. *]checkLocks return a pair of numbers, the first is the count of read locks this thread holds, ` the second is the number of write locks that this thread holds. This may be useful for sanity $ checking complex usage of RWLocks. *This may block and be safely interrupted. +_A thread that calls acquireRead must later call releaseRead once for each call to acquireRead. aIf this thread has not previous called acquireRead then releaseRead will do nothing and return a  (Left error). *This can block but cannot be interrupted. ,bA thread that calls acquireWrite must later call releaseWrite once for each call to acquireWrite. aIf this thread has not previous called acquireWrite then releaseWrite will do nothing and return  a (Left error). *This can block but cannot be interrupted. -XAny thread may call acquireRead (even ones holding write locks). This read lock may be N acquired multiple times, requiring an identical number of releaseRead calls. ^All previous calls to acquireWrite by other threads will have succeeded and been released (or 3 interrupted) before this acquireRead will return. `The best way to use acquireRead is to use withRead instead to ensure releaseRead will be called  exactly once. bThis may block and be safely interrupted. If interrupted then the RWLock will be left unchanged. .^Any thread may call acquireWrite (even ones holding read locks, but see below for interrupted ^ behavior). This write lock may be acquired multiple times, requiring an identical number of  releaseWrite calls. ]All previous calls to acquireRead by other threads will have succeeded and been released (or 4 interrupted) before this acquireWrite will return. \The best way to use acquireWrite is to use withWrite instead to ensure releaseWrite will be  called exactly once. _This may block and usually be safely interrupted. If interrupted then the RWLock will be left a unchanged. The exception to being able to interrupted when this blocks is very subtle: if this ` thread holds read locks and calls acquireWrite then it will release those read locks and go to ] the back of the queue to acquire the write lock (it does not get to skip the queue). While ] blocking waiting for the write lock to be available this thread may be interrupted. If not [ interrupted then the write lock will eventually be acquired, followed by re-acquiring the _ original number of read locks. But if acquireWrite is interrupted after releasing read locks c then it MUST restore those read locks on the way out. To do this the internal error handler will  use PE and a special version of acquireRead that skips to the front of the _ queue; when the current lock state is a reader this works instantly but when the current lock b state is a writer this thread will block in an UNINTERRUPTIBLE state until the current writer is _ finished. Once this other writer is finished the error handler will obtain the read locks it 3 needs to allow the error propagation to continue.  !"#$%&'()*+,-.Q !"#$%&'()*+,-." #!%$&'(-.+,)*" #!$%&'()*+,-.Q Safe-Infered/6Sample variables are slightly different from a normal R:  Reading an empty / causes the reader to block.  (same as S on empty R)  Reading a filled / empties it and returns value.  (same as S)  Try reading a filled / returns a Maybe value.  (same as T)  Writing to an empty / fills it with a value, and 8 potentially, wakes up a blocked reader (same as for U on  empty R).  Writing to a filled / overwrites the current value.  (different from U on full R.) MThe readers queue in FIFO order, with the lead reader joining the writers in L a second FIFO queue to access the stored value. Thus writers can jump the H queue of non-leading waiting readers to update the value, but the lead N reader has to wait on all previous writes to finish before taking the value. HThis design choice emphasises that each reader sees the most up-to-date 3 value possible while still guaranteeing progress. 00: allocates a new MSampleVar in an empty state. No futher # allocation is done when using the /. 11D allocates a new MSampleVar containing the passed value. The value M is not evalated or forced, but stored lazily. No futher allocation is done  when using the /. 22> can block and be interrupted, in which case it does nothing.  If 22 returns then it reports the momentary status the  /?. Using this value without producing unwanted race conditions  is left up to the programmer. 3If the // is full, forget the value and leave it empty. C Otherwise, do nothing. This avoids any the FIFO queue of blocked 4  threads. 3B can block and be interrupted, in which case it does nothing. If  3 returns then it left the / in an empty state. 4JWait for a value to become available, then take it and return. The queue  of blocked 4 threads is a fair FIFO queue. 4C can block and be interrupted, in which case it takes nothing. If  '3readSV returns normally then it has taken a value. 5Write a value into the /&, overwriting any previous value that  was there. 5> can block and be interrupted, in which case it does nothing. /012345V/012345/013452/012345Vnon-portable (concurrency) experimentalhaskell@list.mightyreason.com Safe-Infered 6A 6N is a quantity semaphore, in which the available quantity may be signalled or " waited for in arbitrary amounts. 77Z allows positive, zero, and negative initial values. The initial value is forced here to  better localize errors. 88R takes a quantity of the semaphore to take and hold while performing the provided  operation. 8O ensures the quantity of the sempahore cannot be lost if there are exceptions.  This uses W to ensure : and < get called correctly. 99S takes a pure function and an operation. The pure function converts the available a quantity to a pair of the wanted quantity and a returned value. The operation takes the result  of the pure function. 9? ensures the quantity of the sempahore cannot be lost if there  are exceptions. This uses W to ensure ; and < get called correctly. FNote: A long running pure function will block all other access to the 6 while it is  evaluated. ::[ allow positive, zero, and negative wanted values. Waiters may block, and will be handled  fairly in FIFO order. If :/ returns without interruption then it left the 6$ with a remaining quantity that was $ greater than or equal to zero. If :. is interrupted then no quantity is lost. If : c returns without interruption then it is known that each earlier waiter has definitely either been 2 interrupted or has retured without interruption. ;waitWith takes the 6H and a pure function that takes the available quantity and computes the b amount wanted and a second value. The value wanted is stricly evaluated but the second value is  returned lazily. ;[ allow positive, zero, and negative wanted values. Waiters may block, and will be handled  fairly in FIFO order. If ;/ returns without interruption then it left the 6$ with a remaining quantity that was $ greater than or equal to zero. If ;2 or the provided function are interrupted then no  quantity is lost. If ;B returns without interruption then it is known that each previous Y waiter has each definitely either been interrupted or has retured without interruption. FNote: A long running pure function will block all other access to the 6 while it is  evaluated. <<V allows positive, zero, and negative values, thus this is also way to remove quantity  that skips any threads in the 'wait'/'waitF'3 queue. If the new total is greater than the next b value being waited for (if present) then the first waiter is woken. If there are queued waiters a then the next one will wake after a waiter has proceeded and notice the remaining value; thus a  single <L may result in several waiters obtaining values. Waking waiting threads is  asynchronous. <Y may block, but it cannot be interrupted, which allows it to dependably restore value to  the 6. All <, =, >1, and the head waiter may momentarily block in a  fair FIFO manner. =?Instead of providing a fixed change to the available quantity, = applies a provided X pure function to the available quantity to compute the change and a second value. The e requested change is stricly evaluated but the second value is returned lazily. If the new total is c greater than the next value being waited for then the first waiter is woken. If there are queued b waiters then the next one will wake after a waiter has proceeded and notice the remaining value;  thus a single =I may result in several waiters obtaining values. Waking waiting threads  is asynchronous. =X may block, and it can be safely interrupted. If the provided function throws an error & or is interrupted then it leaves the 6 unchanged. All <, =, >, and > the head waiter may momentarily block in a fair FIFO manner. FNote: A long running pure function will block all other access to the 6 while it is  evaluated. >> skips the queue of any blocked : and ; threads, but may momentarily  block on <, =, other >2, and the head waiter. This returns the amount of c value available to be taken. Using this value without producing unwanted race conditions is left  up to the programmer. > is an optimized form of " signalF m (x -> (0,x))". \Quantity that has been passed to a blocked waiter but not picked up is not counted. If the a blocked waiter is killed before picking it up then the passed quantity will be recovered by the \ next waiter. In this exceptional case this next waiter may see an available total that is ' different than returned by peekAvail.  A version of > that joins the FIFO queue of : and ; can be acheived by  " waitF m (x -> (0,x))"F but this will block if x is negative. On the other hand this method 6 will see the total including any recovered quantity. 6789:;<=> 6789:;<=> 678:<9;=> 6789:;<=>non-portable (concurrency) experimentalhaskell@list.mightyreason.com Safe-Infered ?A ?N is a quantity semaphore, in which the available quantity may be signalled or " waited for in arbitrary amounts. @@Z allows positive, zero, and negative initial values. The initial value is forced here to  better localize errors. AAR takes a quantity of the semaphore to take and hold while performing the provided  operation. AO ensures the quantity of the sempahore cannot be lost if there are exceptions.  This uses W to ensure C and E get called correctly. BBS takes a pure function and an operation. The pure function converts the available a quantity to a pair of the wanted quantity and a returned value. The operation takes the result  of the pure function. B? ensures the quantity of the sempahore cannot be lost if there  are exceptions. This uses W to ensure D and E get called correctly. FNote: A long running pure function will block all other access to the ? while it is  evaluated. CC[ allow positive, zero, and negative wanted values. Waiters may block, and will be handled ` fairly in FIFO order. Waiters will succeed when the wanted value is less than or equal to the / available value. The FIFO order means that a C5 for a large quantity that blocks will prevent later r requests from being considered even if the later requests would be for a small quantity that could be fulfilled. If C/ returns without interruption then it left the ?$ with a remaining quantity that was $ greater than or equal to zero. If C. is interrupted then no quantity is lost. If C c returns without interruption then it is known that each earlier waiter has definitely either been 2 interrupted or has retured without interruption. DwaitWith takes the ?H and a pure function that takes the available quantity and computes the b amount wanted and a second value. The value wanted is stricly evaluated but the second value is  returned lazily. D[ allow positive, zero, and negative wanted values. Waiters may block, and will be handled ` fairly in FIFO order. Waiters will succeed when the wanted value is less than or equal to the / available value. The FIFO order means that a D5 for a large quantity that blocks will prevent later r requests from being considered even if the later requests would be for a small quantity that could be fulfilled. If D/ returns without interruption then it left the ?$ with a remaining quantity that was $ greater than or equal to zero. If D2 or the provided function are interrupted then no  quantity is lost. If DB returns without interruption then it is known that each previous Y waiter has each definitely either been interrupted or has retured without interruption. FNote: A long running pure function will block all other access to the ? while it is  evaluated. EEV allows positive, zero, and negative values, thus this is also way to remove quantity  that skips any threads in the 'wait'/'waitF'3 queue. If the new total is greater than the next b value being waited for (if present) then the first waiter is woken. If there are queued waiters a then the next one will wake after a waiter has proceeded and notice the remaining value; thus a  single EL may result in several waiters obtaining values. Waking waiting threads is  asynchronous. EY may block, but it cannot be interrupted, which allows it to dependably restore value to  the ?. All E, F, G1, and the head waiter may momentarily block in a  fair FIFO manner. F?Instead of providing a fixed change to the available quantity, F applies a provided X pure function to the available quantity to compute the change and a second value. The e requested change is stricly evaluated but the second value is returned lazily. If the new total is c greater than the next value being waited for then the first waiter is woken. If there are queued b waiters then the next one will wake after a waiter has proceeded and notice the remaining value;  thus a single FI may result in several waiters obtaining values. Waking waiting threads  is asynchronous. FX may block, and it can be safely interrupted. If the provided function throws an error & or is interrupted then it leaves the ? unchanged. All E, F, G, and > the head waiter may momentarily block in a fair FIFO manner. FNote: A long running pure function will block all other access to the ? while it is  evaluated. GG skips the queue of any blocked C and D threads, but may momentarily  block on E, F, other G2, and the head waiter. This returns the amount of c value available to be taken. Using this value without producing unwanted race conditions is left  up to the programmer. G is an optimized form of " signalF m (x -> (0,x))".  A version of G that joins the FIFO queue of C and D can be acheived by  " waitF m (x -> (0,x))" ?@ABCDEFG ?@ABCDEFG ?@ACEBDFG ?@ABCDEFGnon-portable (concurrency) experimentalhaskell@list.mightyreason.com Safe-InferedHA HS is a semaphore in which the available quantity can be added and removed in single E units, and which can start with positive, zero, or negative value. IIZ allows positive, zero, and negative initial values. The initial value is forced here to  better localize errors. MThe only way to achieve a negative value with MSem is to start negative with I1. Once a negative quantity becomes non-negative  by use of L" it will never later be negative. JJP takes a unit of value from the semaphore to hold while performing the provided  operation. JQ ensures the quantity of the sempahore cannot be lost if there are exceptions or  if killThread is used. J uses X to ensure K and L get called correctly. KKZ will take one unit of value from the sempahore, but will block if the quantity available  is not positive. If K5 returns normally (not interrupted) then it left the H$ with a remaining quantity that was $ greater than or equal to zero. If K. is interrupted then no quantity is lost. If K c returns without interruption then it is known that each earlier waiter has definitely either been G interrupted or has retured without interruption (the FIFO guarantee). LL; adds one unit to the sempahore. Overflow is not checked. LY may block, but it cannot be interrupted, which allows it to dependably restore value to  the H. All L, M;, and the head waiter may momentarily block in a fair FIFO  manner. MM skips the queue of any blocked K' threads, but may momentarily block on  L, other ME, and the head waiter. This returns the amount of value available to Z be taken. Using this value without producing unwanted race conditions is left up to the  programmer.  Note that Control.Concurrent.MSemN> offers a more powerful API for making decisions based on the  available amount. HIJKLMHIJKLMHIJKLMHIJKLMY          !"#$% &'()*+,-./012345 67 8 9:5 67 8 9:; 6  : <=><?@A<BC<BD<BE<BFG<HI<HJKSafeSemaphore-0.9.0Control.Concurrent.STM.SSemControl.Concurrent.SSemControl.Concurrent.FairRWLockControl.Concurrent.MSampleVarControl.Concurrent.MSemN2Control.Concurrent.MSemNControl.Concurrent.MSem$Control.Concurrent.STM.SSemInternalsSSemnewwaitwaitNsignalsignalNtryWaittryWaitNgetValuewithSemwithSemNFRWWRFRWLockExceptionKindRWLock'releaseReadRWLock'acquireReadRWLock'releaseWriteRWLock'acquireWriteRWLockExceptionRWLockLockKind WriterKindunWK ReaderKindunRKTSetTMapwithRead withWritepeekLock checkLock releaseRead releaseWrite acquireRead acquireWrite MSampleVar newEmptySVnewSV isEmptySVemptySVreadSVwriteSVMSemNwithwithFwaitFsignalF peekAvailMSembase GHC.Conc.SyncretryGHC.IOuninterruptibleMask_$fExceptionRWLockExceptionGHC.MVarMVartakeMVar tryTakeMVarputMVar$fTypeable1MSampleVarControl.Exception.Basebracketbracket_