@@ -46,8 +46,8 @@ Features and properties:
4646  read-only compare (CMP) operations that can be performed on overlapping
4747  locations in parallel without interference.
4848
49- -  ** _ Blocking await_ ** : The algorithm supports timeouts  and awaiting for changes 
50-   to any number of shared memory locations.
49+ -  ** _ Blocking await_ ** : The algorithm supports cancelation  and awaiting for
50+   changes  to any number of shared memory locations.
5151
5252-  ** _ Composable_ ** : Independently developed transactions can be composed with
5353  ease sequentially, conjunctively, conditionally, and disjunctively.
@@ -75,7 +75,7 @@ is distributed under the [ISC license](LICENSE.md).
7575    -  [ A transactional lock-free queue] ( #a-transactional-lock-free-queue ) 
7676    -  [ Composing transactions] ( #composing-transactions ) 
7777    -  [ Blocking transactions] ( #blocking-transactions ) 
78-     -  [ Timeouts] ( #timeouts ) 
78+     -  [ Cancelation and  Timeouts] ( #cancelation-and- timeouts ) 
7979    -  [ A transactional lock-free leftist heap] ( #a-transactional-lock-free-leftist-heap ) 
8080  -  [ Programming with transactional data structures] ( #programming-with-transactional-data-structures ) 
8181    -  [ The dining philosophers problem] ( #the-dining-philosophers-problem ) 
@@ -100,14 +100,7 @@ is distributed under the [ISC license](LICENSE.md).
100100
101101To use the library
102102
103- <!-- 
104103``` ocaml 
105- # #thread 
106- ``` 
107- --> 
108- 
109- ``` ocaml 
110- # #require "kcas" 
111104# open Kcas 
112105``` 
113106
@@ -142,6 +135,7 @@ Block waiting for changes to locations:
142135
143136``` ocaml 
144137# let a_domain = Domain.spawn @@ fun () -> 
138+     Scheduler.run @@ fun () -> 
145139    let x = Loc.get_as (fun x -> Retry.unless (x <> 0); x) x in 
146140    Printf.sprintf "The answer is %d!" x 
147141val a_domain : string Domain.t = <abstr> 
@@ -550,13 +544,28 @@ and then spawn a domain that tries to atomically both pop and dequeue:
550544
551545``` ocaml 
552546# let a_domain = Domain.spawn @@ fun () -> 
547+     Scheduler.run @@ fun () -> 
553548    let tx ~xt = (pop ~xt a_stack, dequeue ~xt a_queue) in 
554549    let (popped, dequeued) = Xt.commit { tx } in 
555550    Printf.sprintf "I popped %d and dequeued %d!" 
556551      popped dequeued 
557552val a_domain : string Domain.t = <abstr> 
558553``` 
559554
555+ ** Kcas**  uses the [ Picos] ( https://github.com/ocaml-multicore/picos/ )  interface
556+ to implement blocking. Above ` Scheduler.run `  starts an effects based
557+ [ Picos compatible] ( https://ocaml-multicore.github.io/picos/doc/picos/index.html#interoperability ) 
558+ scheduler, which allows ** Kcas**  to block in a scheduler friendly manner.
559+ 
560+ >  ** _ Note_ ** : Typically your entire program would run inside a scheduler and you
561+ >  should
562+ >  [ fork fibers] ( https://ocaml-multicore.github.io/picos/doc/picos_mux/index.html#examples ) 
563+ >  rather than spawn domains and start schedulers. The
564+ >  [ MDX] ( https://github.com/realworldocaml/mdx )  tool used for checking this
565+ >  document does not allow one to start a scheduler once and run individual code
566+ >  snippets within the scheduler, which is why individual examples spawn domains
567+ >  and start schedulers.
568+ 
560569The domain is now blocked waiting for changes to the stack and the queue. As
561570long as we don't populate both at the same time
562571
@@ -584,7 +593,7 @@ The retry mechanism essentially allows a transaction to wait for an arbitrary
584593condition and can function as a fairly expressive communication and
585594synchronization mechanism.
586595
587- #### Timeouts  
596+ #### Cancelation and  Timeouts 
588597
589598>  If you block, will they come?
590599
@@ -604,43 +613,30 @@ val pop_or_raise_if :
604613  xt:'a Xt.t -> bool Loc.t -> 'b list Loc.t -> xt:'c Xt.t -> 'b = <fun> 
605614``` 
606615
607- This works, but creating, checking, and canceling timeouts properly can be a lot
608- of work. Therefore ** Kcas**  also directly supports an optional ` timeoutf ` 
609- argument for potentially blocking operations. For example, to perform a blocking
610- pop with a timeout, one can simply explicitly pass the desired timeout in
611- seconds:
612- 
613- ``` ocaml 
614- # let an_empty_stack = stack () in 
615-   Xt.commit ~timeoutf:0.1 { tx = pop an_empty_stack } 
616- Exception: Failure "Domain_local_timeout.set_timeoutf not implemented". 
617- ``` 
618- 
619- Oops! What happened above is that the
620- [ _ domain local timeout_ ] ( https://github.com/ocaml-multicore/domain-local-timeout ) 
621- mechanism used by ** Kcas**  was not implemented on the current domain. The idea
622- is that, in the future, concurrent schedulers provide the mechanism out of the
623- box, but there is also a default implementation using the Stdlib ` Thread `  and
624- ` Unix `  modules that works on most platforms. However, to avoid direct
625- dependencies to ` Thread `  and ` Unix ` , we need to explicitly tell the library that
626- it can use those modules:
616+ This works, but creating, checking, and canceling timeouts properly in this
617+ manner can be a lot of work. Therefore ** Kcas**  also directly supports
618+ [ cancelation] ( https://ocaml-multicore.github.io/picos/doc/picos_std/Picos_std_structured/index.html#understanding-cancelation ) 
619+ through the [ Picos] ( https://github.com/ocaml-multicore/picos/ )  interface. This
620+ both allows ** Kcas**  transactions to be cleanly terminated in case the program
621+ has encountered an error and also allows one to simply use a timeout mechanism
622+ provided by the scheduler. For example, the sample
623+ [ structured concurrency library] ( https://ocaml-multicore.github.io/picos/doc/picos_std/Picos_std_structured/index.html ) 
627624
628625``` ocaml 
629- # Domain_local_timeout.set_system (module Thread) (module Unix) 
630- - : unit = () 
626+ # open Picos_std_structured 
631627``` 
632628
633- This initialization, if needed, should be done by application code rather than
634- by libraries.
635- 
636- If we now retry the previous example we will get a
637- [ ` Timeout ` ] ( https://ocaml-multicore.github.io/kcas/doc/kcas/Kcas/Timeout/index.html#exception-Timeout ) 
638- exception as expected:
629+ for Picos provides the
630+ [ ` Control.terminate_after ` ] ( https://ocaml-multicore.github.io/picos/doc/picos_std/Picos_std_structured/Control/index.html#val-terminate_after ) 
631+ operation, which allows one to easily run an operation with a timeout on the
632+ current fiber:
639633
640634``` ocaml 
641635# let an_empty_stack = stack () in 
642-   Xt.commit ~timeoutf:0.1 { tx = pop an_empty_stack } 
643- Exception: Kcas.Timeout.Timeout. 
636+   Scheduler.run @@ fun () -> 
637+   Control.terminate_after ~seconds:0.1 @@ fun () -> 
638+   Xt.commit { tx = pop an_empty_stack } 
639+ Exception: Picos_std_structured__Control.Terminate. 
644640``` 
645641
646642Besides
@@ -650,7 +646,7 @@ potentially blocking single location operations such as
650646[ ` update ` ] ( https://ocaml-multicore.github.io/kcas/doc/kcas/Kcas/Loc/index.html#val-update ) ,
651647and
652648[ ` modify ` ] ( https://ocaml-multicore.github.io/kcas/doc/kcas/Kcas/Loc/index.html#val-modify ) 
653- support the optional  ` timeoutf `  argument .
649+ support cancelation .
654650
655651#### A transactional lock-free leftist heap  
656652
@@ -838,10 +834,9 @@ structures.
838834One source of ready-made data structures is
839835[ ** Kcas_data** ] ( https://ocaml-multicore.github.io/kcas/doc/kcas_data/Kcas_data/index.html ) .
840836Let's explore how we can leverage those data structures. Of course, first we
841- need to  ` #require `  the package and we'll also open it  for convenience:
837+ open  ` Kcas_data `  for convenience:
842838
843839``` ocaml 
844- # #require "kcas_data" 
845840# open Kcas_data 
846841``` 
847842
@@ -914,6 +909,7 @@ the philosophers:
914909    in 
915910    Array.iter Domain.join @@ Array.init philosophers @@ fun i -> 
916911      Domain.spawn @@ fun () -> 
912+       Scheduler.run @@ fun () -> 
917913      let fork_lhs = forks.(i) 
918914      and fork_rhs = forks.((i + 1) mod philosophers) 
919915      and eaten = eaten.(i) in 
0 commit comments