<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://cs.hubfs.net/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Hell Is Other Languages</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Concurrency on a single thread</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/08/03/6506.aspx</link><pubDate>Mon, 04 Aug 2008 03:40:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:6506</guid><dc:creator>gneverov</dc:creator><slash:comments>6</slash:comments><comments>http://cs.hubfs.net/blogs/hell_is_other_languages/comments/6506.aspx</comments><wfw:commentRss>http://cs.hubfs.net/blogs/hell_is_other_languages/commentrss.aspx?PostID=6506</wfw:commentRss><description>&lt;H3&gt;Introduction&lt;/H3&gt;
&lt;P&gt;F# has the async computation expression for writing parallel programs. Async achieves concurrency by using the CLR ThreadPool to queue work items for each logical thread created in an async expression (e.g., through Async.spawn or Async.parallel). Using the thread pool is good because it reuses existing threads instead of creating and destroying new threads. However the thread pool has limitations when a large number of threads are created that may result in deadlock (if queued work items don't execute because of blocked threads), increased memory usage, and poorer performance due to excessive context switching.&lt;/P&gt;
&lt;P&gt;Suppose we want to write a parallel application that creates a large number of concurrently executing threads. Threads are good because they present a sequential control flow model that is easy to understand and reason about, and having a large number of threads facilitates better resource utilization. To do this we would like to implement our own scalable concurrent threading system for our application that uses virtual threads not backed by the CLR thread pool or OS threads. To enable scalability, the creation of virtual threads in the system will be cheap (about the cost of a newobj instruction) and not consume OS-level resources (and similarly for synchronization primitives also). &lt;/P&gt;
&lt;P&gt;The implementation of this system will be based on the standard F# async: it will be a computation expression based on the continuation monad and the users' code will look similar and be functionally the same. However operationally it will be different from the standard async because it will use a fixed number of threads instead of the thread pool. (For version 1 in this post it will use only 1 thread, but a version 2 might extend that to 1 thread per CPU.) &lt;/P&gt;
&lt;P&gt;You can download the F# code for this post &lt;A href="/blogs/hell_is_other_languages/attachment/6506.ashx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;Scheduler&lt;/H3&gt;
&lt;P&gt;At the core of this new async monad is the thread scheduler. The scheduler makes multiple threads of execution and multiplexes them together to give the illusion of concurrency. The scheduler is entirely managed code and uses continuations to manipulate control flow. The state of the scheduler consists of three parts:&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Scheduler () = &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; ready : LinkedList&amp;lt;unit -&amp;gt; unit&amp;gt;; &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; pending : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; ref &lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The ready queue is a list of continuations that represent threads ready to run. It is a LinkedList from the BCL to allow fast insertion/removal from the beginning and end of the list. The basic operation of the one real OS thread in the system is this loop below.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;rec&lt;/span&gt; loop () =&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; ready.Count &amp;gt; 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; k = ready.Dequeue ()&lt;br /&gt;    k ()&lt;br /&gt;    loop ()&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;It checks to see if the ready queue is non-empty. If so, it removes the first continuation, executes it (which may modify the ready queue) and repeats. However asynchronous I/O operations complicate this simple algorithm.&lt;/P&gt;
&lt;H3&gt;Asynchronous I/O&lt;/H3&gt;
&lt;P&gt;An I/O operation (like reading or writing to a disk or network) can take a long time and during this time the CPU is idle. If we performed a blocking I/O operation on our one real thread then all virtual threads would be suspended – not good. Therefore it is imperative that the programmer using this async monad never uses blocking operations and always uses non-blocking I/O. Win32 supports non-blocking I/O called 'overlapped' I/O. The basic principle is that a thread makes a system call to start an I/O operation. The system call returns immediately before the operation is completed. The operation is performed by the OS and not on the process's thread. When the operation is complete, a callback is executed on one of the threads in the process. The key point here is that the non-blocking I/O operation didn't create or consume an OS thread, thereby by using this we can stick to our one-thread budget. Non-blocking I/O is exposed in the BCL through Begin/End methods on various I/O objects (FileStream, etc.) and on Windows these methods are probably implemented using Win32 overlapped I/O.&lt;/P&gt;
&lt;P&gt;The pending field in the state of the scheduler contains the number of logical threads currently in an asynchronous I/O operation. So when ready.Count = 0 and !pending = 0 the computation has terminated.&lt;/P&gt;
&lt;H3&gt;The Monad&lt;/H3&gt;
&lt;P&gt;So let's get started looking at the code. Additionally this will also serve as a guide to writing (not-necessarily-concurrency-related) computation expression builders in F#. The monad used in this code is based on the papers by &lt;A href="http://citeseer.ist.psu.edu/claessen99functional.html"&gt;Classen&lt;/A&gt;&amp;nbsp;and &lt;A href="http://www.cis.upenn.edu/~stevez/papers/LZ07.ps"&gt;Li and Zdancewic&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The type of the monad used here is&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Async&amp;lt;'a&amp;gt; = Async of (Scheduler * ('a -&amp;gt; unit) * (exn -&amp;gt; unit) -&amp;gt; unit)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;In general all F# monad types need to be function types to achieve the delayed evaluation implicit in a computation expression block. Furthermore you'd typically want to wrap this type in a discriminated union tag to aid type inference. Hence making the general form of a monad type&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; M&amp;lt;'a&amp;gt; = M of (… -&amp;gt; …)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;In the Async type the left of the function arrow takes three arguments: the state of the scheduler of type Scheduler, a success continuation of type ('a -&amp;gt; unit) and an exception continuation of type (exn -&amp;gt; unit).&lt;/P&gt;
&lt;P&gt;The Scheduler type was mentioned above. The Scheduler state supports the following operations.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; QueueFirst : (unit -&amp;gt; unit) -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; QueueLast : (unit -&amp;gt; unit) -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; Dequeue : unit -&amp;gt; Lock&amp;lt;(unit -&amp;gt; unit) option&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; IncrPending : unit -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; DecrPending : unit -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; Run : Lock&amp;lt;'a&amp;gt; -&amp;gt; 'a&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Since the Scheduler state will be accessed by two threads: the single application thread and the CLR IO completion thread, access to the data structure needs to be synchronized. This is done using the &lt;A href="/blogs/hell_is_other_languages/archive/2008/02/17/4892.aspx"&gt;lock monad&lt;/A&gt; from my previous blog post. &lt;/P&gt;
&lt;H3&gt;Return &amp;amp; Bind&lt;/H3&gt;
&lt;P&gt;We now implement the standard return and bind operations for a continuation monad.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; mreturn x = Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; sk x)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; apply (Async m) (sched, sk, ek) = m (sched, sk, ek)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; bind m f =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    apply m (sched, (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; x -&amp;gt; apply (f x) (sched, sk, ek))&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; ek))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The implementation of return is fine; however there is a problem with the implementation of bind because it does not take into account the possibility of exceptions. If the function f throws and exception then this must be caught somewhere and execution diverted to the exception continuation.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Result&amp;lt;'a&amp;gt; = Success of 'a &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error of exn&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryApply f x = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; Success (f x) &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt; e -&amp;gt; Error e&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; apply2 f x (sched, sk, ek) = &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; tryApply f x &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success m -&amp;gt; apply m (sched, sk, ek)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e -&amp;gt; ek e&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; bind m f =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    apply m (sched, (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; x -&amp;gt; apply2 f x (sched, sk, ek))&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; ek))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The tryApply function will always be used whenever applying an "outside" function (a function defined outside the async library) so that any exceptions thrown by this function can be reified as values and control flow handled appropriately.&lt;/P&gt;
&lt;H3&gt;Mzero &amp;amp; Mplus&lt;/H3&gt;
&lt;P&gt;Two primitive operations for the async monad are stop and fork. The stop operation terminates the current thread. The fork operation duplicates the current thread and returns different values on each. For example, if there is a thread executing the expression "bind (fork m1 m2) f" then after the evaluation of fork there will be two threads executing: one executing the expression "bind m1 f" and the other executing "bind m2 f". Fork is the primitive method for creating new threads in the async monad. The implementation for stop and fork are as follows.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; stop =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; ())&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; fork m1 m2 = &lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    sched.QueueLast (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; apply m2 (sched, sk, ek)) |&amp;gt; sched.Run&lt;br /&gt;    apply m1 (sched, sk, ek))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Unfortunately calling stop stops the current thread without running any finally handlers that are in scope. Ideally there should be a third continuation (called the finally continuation) that is executed by stop, but we'll ignore this issue for now. The fork operation works by queuing the second branch of the fork at the end of the scheduler's ready queue and executing the first branch immediately. Stop and fork form the mzero and mplus operations of a MonadPlus type class instance for the async monad.&lt;/P&gt;
&lt;H3&gt;Yield&lt;/H3&gt;
&lt;P&gt;The yield operation forces the thread to give up its execution and re-queues itself at the end of the ready queue.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; myield =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;     sched.QueueLast sk |&amp;gt; sched.Run)&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Callback&lt;/H3&gt;
&lt;P&gt;The callback operation is used to invoke asynchronous IO operations. In the CLR base class library, asynchronous IO operations are defined by two methods: a Begin method and an End method (e.g. for reading from a stream BeginRead and EndRead). These two methods are passed to the callback function below. This function first increments the schedulers pending count to mark the start of a new asynchronous IO operation. It then calls the Begin method passing the function cb as the callback. If the Begin method was successful then this thread yields, otherwise the pending count is decremented and the exception continuation invoked. When the system has performed the IO operation it calls cb on some special thread (not the scheduler's thread). Therefore cb cannot continue execution of the continuation monad; instead it must marshal a continuation back onto the scheduler's ready queue. So it first calls the End method to get the result of the IO operation. If the IO operation failed for some reason then can exception will be thrown in this call. Depending on the success of End, either the success or exception continuation is chosen and queued at the front of the ready queue. The pending count is decremented and the lock is pulsed to wake up the scheduler thread which may be blocking waiting for new continuations to execute.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; callback : (AsyncCallback -&amp;gt; IAsyncResult) -&amp;gt; (IAsyncResult -&amp;gt; 'a) -&amp;gt; Async&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; callback (beginFunc : _ -&amp;gt; IAsyncResult) endFunc =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; cb (ar : IAsyncResult) = &lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; k = &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; tryApply endFunc ar &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success x -&amp;gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; sk x &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e -&amp;gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; ek e&lt;br /&gt;      lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! sched.QueueFirst k&lt;br /&gt;             &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! sched.DecrPending ()&lt;br /&gt;             return! Lock.pulseAll } |&amp;gt; sched.Run&lt;br /&gt;    sched.IncrPending () |&amp;gt; sched.Run&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; tryApply beginFunc (AsyncCallback(cb)) &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success ar -&amp;gt; ()          &lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e -&amp;gt; sched.DecrPending () |&amp;gt; sched.Run&lt;br /&gt;                   ek e)&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Run&lt;/H3&gt;
&lt;P&gt;Finally, we need to run function to execute the async monad. The run function creates a new scheduler and a place to store results. When executing, an async computation may create multiple threads that terminate successfully (viz. without calling stop) and thereby producing multiple results (and exceptions). Therefore the result of executing an async computation is a list of Result values. An initial continuation is added to the ready queue that runs the target monad with success and exception continuations that add respectively to the result list. Continuations are then dequeued and run iteratively until there is no more work to do.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; run m = &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; sched = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; Scheduler()&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; result = ref []&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; init () = apply m (sched, (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; x -&amp;gt; result &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; Success x :: !result)&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; e -&amp;gt; result &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; Error e :: !result))&lt;br /&gt;  sched.QueueFirst init |&amp;gt; sched.Run&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; f () = sched.Dequeue () |&amp;gt; sched.Run&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;for&lt;/span&gt; k &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; Seq.unfold0 f &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; k ()&lt;br /&gt;  !result&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Many applications however will expect a single result from an async computation, so the runOne function is also created to only return the first result.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; runOne m =&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; run m &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; [] -&amp;gt; failwith &lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;"no value"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success x::_ -&amp;gt; x&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e::_ -&amp;gt; raise e&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Synchronization&lt;/H3&gt;
&lt;P&gt;There needs to be some way for threads within an async computation to synchronize with each other. We can't use the CLR's synchronization primitives because they will block the scheduler thread; therefore we need to create our own. So we will create a manual reset event (and leave an auto reset event as an exercise for the reader).&lt;/P&gt;
&lt;P&gt;A manual reset event will be represented as an optional list of continuations. A value of None means that the event is in the signalled state. A value of Some ws means that the event is in the non-signalled state and the list ws contains the continuations waiting for the event to become signalled. Hence a value of Some [] means that the event is not signalled but no one is waiting on it. The type of a manual reset event is&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; MRE = MRE of (unit -&amp;gt; unit) list option ref&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;To create a new MRE in the specified state &lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; newMRE state = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; state &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; MRE (ref None) &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; MRE (ref (Some []))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Waiting on a MRE causes its state to be analysed. Access to the MRE's internal mutable state does not need to be synchronized because there is only one real thread in the system. If it is signalled then the success continuation can be invoke immediately. If it is not signalled then the success continuation is added to the wait list and the thread yields.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; waitMRE (MRE mre) =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; !mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; sk ()&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some wait -&amp;gt; mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; Some (sk :: wait))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;When setting an MRE, its state is again analysed. If it is already signalled then do nothing. Otherwise set the state to signalled and add each of the continuations in the wait list to the ready queue. Finally, regardless of the initial state, the success continuations in executed since setting an MRE is a non-blocking operation.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; setMRE (MRE mre) =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; !mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; ()&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some wait -&amp;gt; mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; None&lt;br /&gt;                     Lock.iter (sched.QueueFirst) wait |&amp;gt; sched.Run&lt;br /&gt;    sk ())&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;As well as auto reset events, other synchronization primitives can also be defined, such as MVars.&lt;/P&gt;
&lt;H3&gt;Creating threads&lt;/H3&gt;
&lt;P&gt;In many applications fork is not a particularly intuitive operation. A spawn operation that takes an async computation executes it on a new thread and then ends that thread is more intuitive in many scenarios. We can write a spawn operation in terms of the primitives we have already defined.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; spawn m = &lt;br /&gt;  async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; join = newMRE &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;false&lt;/span&gt;&lt;br /&gt;          return! fork (mreturn join) &lt;br /&gt;                       (async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! tryWith m (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; _ -&amp;gt; mreturn ())&lt;br /&gt;                                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! setMRE join&lt;br /&gt;                                return! stop }) }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;spawn starts by creating a new MRE that will be used signal the end of the spawned thread. It then forks. To one thread it returns the MRE so the caller can synchronize on the completion of the spawned computation. The other thread executes the target computation expression, ignoring any exceptions raised, signals the MRE and terminates.&lt;/P&gt;
&lt;P&gt;One of the most useful async operations is parallel which takes a list of computations, executes them all in parallel and returns a list of their results.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; parallel ms =&lt;br /&gt;  async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; results = Array.zero_create (List.length ms)&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; task = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; i m -&amp;gt; &lt;br /&gt;            async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! x = m &lt;br /&gt;                    return results.[ i ] &amp;lt;- x } |&amp;gt; spawn&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! joins = mapi task ms &lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! iter waitMRE joins&lt;br /&gt;          return results |&amp;gt; Array.to_list }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;parallel first finds the length of the list and allocates an array to hold all the results. It then creates a task for each element in the list that executes the async computation and stores its result in the corresponding position in the results array. Spawning all these tasks produces a list of MREs which are used to wait for all the tasks to complete. When all the MREs have been signalled the function returns the list of results.&lt;/P&gt;
&lt;P&gt;Another useful control flow operation is first that evaluates a target computation (which may fork) but continues only with the first thread that completes. It creates a new ARE in the signalled state. The first thread that completes the computation will reset the ARE and return the result. Other threads will see the non-signalled ARE and terminate.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; first m =&lt;br /&gt;  async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; once = newARE &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;true&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! x = m&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! b = tryWaitARE once&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; b &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return x&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; return! stop }&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Conclusion&lt;/H3&gt;
&lt;P&gt;This blog post is already long enough so I'll stop it here before covering applications. In the &lt;A href="/blogs/hell_is_other_languages/attachment/6506.ashx"&gt;code download&lt;/A&gt; you can find examples of a web crawler, image resizer and the concurrency example from this paper by &lt;A href="http://lampwww.epfl.ch/~odersky/papers/jmlc06.html"&gt;Haller and Odersky&lt;/A&gt;. Two natural extensions to the system presented here are making the scheduler (1) multi-threaded and (2) distributed. Using &lt;A href="http://msdn.microsoft.com/en-us/library/72hyey7b(VS.80).aspx)"&gt;.NET binary serialization&lt;/A&gt;&amp;nbsp;it should be possible to serialize the continuations as delegates and send them to a different process/host. Additionally the &lt;A href="/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx"&gt;STM monad&lt;/A&gt; could be built-in under the continuation monad as the primitive means for blocking, synchronization and inter-process communication.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=6506" width="1" height="1"&gt;</description><enclosure url="http://cs.hubfs.net/blogs/hell_is_other_languages/attachment/6506.ashx" length="8359" type="application/x-zip-compressed" /></item><item><title>Using computation expressions to control monitor locks</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/02/17/4892.aspx</link><pubDate>Mon, 18 Feb 2008 07:40:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:4892</guid><dc:creator>gneverov</dc:creator><slash:comments>3</slash:comments><comments>http://cs.hubfs.net/blogs/hell_is_other_languages/comments/4892.aspx</comments><wfw:commentRss>http://cs.hubfs.net/blogs/hell_is_other_languages/commentrss.aspx?PostID=4892</wfw:commentRss><description>&lt;P&gt;Using computation expressions to control monitor locks&lt;/P&gt;
&lt;P&gt;C# has the lock statement to support the use of .NET monitor synchronization. &lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;) { x--; }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;This curly-brace delimited block of atomic statements is easily identified in code. However having to call Wait or Pulse inside the block is less appealing because this previously hidden &lt;A href="http://msdn2.microsoft.com/en-us/library/system.threading.monitor.aspx"&gt;Monitor&lt;/A&gt; class now comes to your attention and you have to make sure you wait/pulse on the same object that was locked.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;) { x--; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt;(x==0) Monitor.Pulse(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;); }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;F# has the lock function which is basically a higher-order function version of C#'s lock statement. It has the same un-niceness with wait/pulse, plus you have to construct the body of the block into a function, and to me braces &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;{…}&lt;/span&gt; look better than the verbose &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; …)&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock this (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; decr x; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; x=0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; Monitor.Pulse(this))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;We can solve all these issues and more with computation expressions in F#. We start by defining the Lock monad, which is actually just an instance of the &lt;A href="http://www.haskell.org/all_about_monads/html/readermonad.html"&gt;reader monad&lt;/A&gt;. A value of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Lock&amp;lt;'a&amp;gt;&lt;/span&gt; is a computation that will execute under the context of a lock and return a result of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;'a&lt;/span&gt;. The type of the Lock monad is a function that accepts the locked object and returns the result of the computation. The following return and bind functions are the standard implementation of the reader monad.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Lock&amp;lt;'a&amp;gt; = Lock of (obj -&amp;gt; 'a)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; apply (Lock f) lock = f lock&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; mreturn x = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; x)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; bind m f = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; apply (f (apply m lock)) lock)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Next we need a function to run a Lock computation. This function takes as arguments an object to lock and the computation to run. It acquires a lock on the object, runs the computation and then releases the lock.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val run : 'a -&amp;gt; Lock&amp;lt;'b&amp;gt; -&amp;gt; 'b *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; run lock m =&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; lock = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;box&lt;/span&gt; lock&lt;br /&gt;  Monitor.Enter(lock)&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; apply m lock&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;finally&lt;/span&gt; Monitor.Exit(lock)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Next we'll define some monadic actions for wait and pulse.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val wait : Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; wait = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.Wait(lock) |&amp;gt; ignore)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val tryWait : int -&amp;gt; Lock&amp;lt;bool&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryWait (timeout : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;) = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.Wait(lock, timeout))&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val pulse : Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; pulse = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.Pulse(lock))&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val pulseAll : Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; pulseAll = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.PulseAll(lock))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Finally we need a builder class to enable computation expression syntax on the Lock type. This code is omitted here but can be downloaded in the &lt;A href="/blogs/hell_is_other_languages/attachment/4565.ashx"&gt;full example&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Now at last we can write lock code in F# with curly braces, without seeing the Monitor class, and without reproducing the locked object to call wait and pulse.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; decr x&lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; x = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return! pulse } |&amp;gt; run this&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Or a more complex example&lt;BR&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; ready.Count = 0 &amp;amp;&amp;amp; !pending &amp;gt; 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; return! wait&lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; ready.Count &amp;gt; 0 &lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return Some (ready.Dequeue())&lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; return None } |&amp;gt; run myLock&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;You can even have an alternate run function that takes a timeout on acquiring the lock.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val tryRun : 'a -&amp;gt; int -&amp;gt; Lock&amp;lt;'b&amp;gt; -&amp;gt; 'b option *)&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryRun lock (timeout : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;) m =&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; lock = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;box&lt;/span&gt; lock&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; Monitor.TryEnter(lock, timeout)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; Some (apply m lock)&lt;br /&gt;         &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;finally&lt;/span&gt; Monitor.Exit(lock)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; None&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Additionally the Lock monad can be used to make synchronized code more composable. Say you have method that always needs to execute under a lock but either you don't know which lock or the lock needs to be entered at an outer scope. You can write this method so that it returns a Lock computation, which can be composed with other Lock computations. Consider functions to synchronously access items in a System.Collections.Generic.&lt;A href="http://msdn2.microsoft.com/en-us/library/7977ey2c.aspx"&gt;Queue&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val enqueue : Queue&amp;lt;’a&amp;gt; -&amp;gt; ‘a -&amp;gt; Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; enqueue (q : Queue&amp;lt;_&amp;gt;) x = &lt;br /&gt;  lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; q.Count = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return! pulseAll&lt;br /&gt;         &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; q.Enqueue(x) }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val dequeue : Queue&amp;lt;’a&amp;gt; -&amp;gt; Lock&amp;lt;’a&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; dequeue (q : Queue&amp;lt;_&amp;gt;) = &lt;br /&gt;  lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; q.Count = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; return! wait&lt;br /&gt;         return q.Dequeue() }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Because these functions return a &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Lock&amp;lt;_&amp;gt;&lt;/span&gt; value the caller can never forget to acquire the lock and this will be enforced by the type system (of course the programmer can still acquire the &lt;EM&gt;wrong&lt;/EM&gt; lock). Secondly these functions can naturally call pulse and wait without knowing the object the lock is acquired on. &lt;/P&gt;
&lt;P&gt;With these functions you can easily write code that atomically moves an item between queues and returns the item.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; move q1 q2 = &lt;br /&gt;  lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! x = dequeue q1 &lt;br /&gt;         &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! enqueue q2 x&lt;br /&gt;         return x } |&amp;gt; run myLock&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;So if you &lt;EM&gt;have&lt;/EM&gt; to use locks because you don't like &lt;A href="/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx"&gt;STM&lt;/A&gt; or its performance isn't good enough or for legacy reasons, the lock monad could improve readability and abstraction.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=4892" width="1" height="1"&gt;</description><enclosure url="http://cs.hubfs.net/blogs/hell_is_other_languages/attachment/4892.ashx" length="878" type="application/x-zip-compressed" /></item><item><title>Software Transactional Memory for F#</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx</link><pubDate>Wed, 16 Jan 2008 08:11:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:4565</guid><dc:creator>gneverov</dc:creator><slash:comments>18</slash:comments><comments>http://cs.hubfs.net/blogs/hell_is_other_languages/comments/4565.aspx</comments><wfw:commentRss>http://cs.hubfs.net/blogs/hell_is_other_languages/commentrss.aspx?PostID=4565</wfw:commentRss><description>&lt;P&gt;I have written a library for using software transactional memory in F#. The library exposes memory transactions as a monad using F#’s new &lt;A href="http://blogs.msdn.com/dsyme/archive/2007/09/22/some-details-on-f-computation-expressions-aka-monadic-or-workflow-syntax.aspx"&gt;computation expression&lt;/A&gt; feature. It can be downloaded &lt;A href="/blogs/hell_is_other_languages/attachment/4565.ashx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Software transactional memory (STM) is an approach to concurrent programming that avoids the use of traditional, error-prone locks to control access to shared memory. Instead of using locks a programmer specifies sections of code that will make atomic changes to shared memory. &lt;/P&gt;
&lt;P&gt;The design and implementation of this F# library is blatantly copied from the paper &lt;A href="http://research.microsoft.com/~simonpj/papers/stm/index.htm#composble"&gt;Composable Memory Transactions&lt;/A&gt;. I am enormously grateful to the authors of this paper whose clear and precise explanation made the implementation of this complicated piece of software almost trivial.&lt;/P&gt;
&lt;P&gt;The low-level STM machinery is implemented in the file stm.cs. It is written in C# mainly because I was working off existing code I’d written some time ago, but there’s no reason why it could not be written in F#. It is all managed code and internally uses monitors for synchronization. It currently uses a very coarse grained lock meaning that only one transaction can commit at once and every waiting thread is resumed when a transaction completes, but this can be improved with more work. The implementation follows the description in the paper.&lt;/P&gt;
&lt;P&gt;The F# monadic interface is in the file stm.fs. It imports definitions from the C# assembly and defines the monad type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Stm&amp;lt;'a&amp;gt;&lt;/span&gt; with corresponding builder class to enable computation expression syntax. An issue with the implementation of STM systems is how to access the transaction log to make reads and writes during a transaction. Two common approachs are to use thread-local storage which is slow, or implicitly pass the transaction log as an extra parameter to every function, which requires code generation. The advantage of using computation expressions (or monadic do notation) is that the transaction log is explicitly passed between functions by the programmer’s code, thereby avoiding compiler modification, but also avoiding the need for the programmer to manually manage the transaction log parameter passing scheme&amp;nbsp;as well.&lt;/P&gt;
&lt;P&gt;With these two layers in place one can write STM code in F#. Transacted memory locations have the type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;TVar&amp;lt;'a&amp;gt;&lt;/span&gt;. This is a reference cell like &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Ref&amp;lt;'a&amp;gt;&lt;/span&gt; in F# but its value can only be read and written from inside a transaction. A TVar is created using the &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;newTVar&lt;/span&gt; function.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; x = newTVar 0&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; x : TVar&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This code is similar to &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; x = ref 0&lt;/span&gt;, but being a TVar instead of a Ref, the location &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;x&lt;/span&gt; can be safely shared between multiple threads. &lt;/P&gt;
&lt;P&gt;A transaction is defined using a computation expression. A transaction is a value of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Stm&amp;lt;'a&amp;gt;&lt;/span&gt; which represents a computation that when executed will make an atomic change to the values of zero or more TVars and then return a value of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;'a&lt;/span&gt;. The type system ensures at compile-time that all reads and writes to a TVar only take place inside a transaction. The functions &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;readTVar&lt;/span&gt; and &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;writeTVar&lt;/span&gt; read and write a TVar respectively. They are analogous to &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; v = !x&lt;/span&gt; and &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;x &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; v&lt;/span&gt; for regular reference cells.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; readTVar : TVar&amp;lt;'a&amp;gt; -&amp;gt; Stm&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; writeTVar : TVar&amp;lt;'a&amp;gt; -&amp;gt; 'a -&amp;gt; Stm&amp;lt;unit&amp;gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Let’s define a function that increments the value stored in a TVar.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; incr x = &lt;br /&gt;  stm {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = readTVar x&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! writeTVar x (v+1)&lt;br /&gt;    return v }&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; incr : TVar&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; -&amp;gt; Stm&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The syntax &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;stm { … }&lt;/span&gt; is an F# computation expression using the 'stm' monad, which means that this is a memory transaction (as opposed to an &lt;A href="http://blogs.msdn.com/dsyme/archive/2007/10/11/introducing-f-asynchronous-workflows.aspx"&gt;async work unit&lt;/A&gt; or something). The value of the location is read and stored in &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;v&lt;/span&gt;. The incremented value is then written back to the location and &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;v&lt;/span&gt; is returned as the result of the computation. When executed the read and write happen as an atomic block which means logically that an interleaving thread won’t access the location between the read and write.&lt;/P&gt;
&lt;P&gt;A transaction is executed by the &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;atomically&lt;/span&gt; function. &lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; : atomically : Stm&amp;lt;'a&amp;gt; -&amp;gt; 'a&lt;/span&gt;&lt;/P&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr x |&amp;gt; atomically&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; it : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; = 0&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr x |&amp;gt; atomically&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; it : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; = 1&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The composability of STM can be seen by the ability to compose &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr&lt;/span&gt; into a larger transaction that increments a location twice.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; incr2 x =&lt;br /&gt;  stm { &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! _ = incr x&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = incr x&lt;br /&gt;    return v }&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; incr2 : TVar&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; -&amp;gt; Stm&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr2 x |&amp;gt; atomically&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; it : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; = 3&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Imagine that &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr&lt;/span&gt; was part of the public interface of a module. If &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr&lt;/span&gt; used a lock to perform the read and write atomically then it would be impossible for users of the library to write &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr2&lt;/span&gt; unless the module also exposed its locks through a public interface, which would make programming intricate for the user.&lt;/P&gt;
&lt;P&gt;If you see any Haskell STM code, it is straightforward to translate this into F#. For example the paper gives the implementation of an MVar as a code example. The paper describes an MVar as&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;EM&gt;An MVar is a mutable location like a TVar, except that it may be either empty, or full with a value. The takeMVar function leaves a full MVar empty, and blocks on an empty MVar. A putMVar on an empty MVar leaves it full, and blocks on a full MVar. So MVars are, in effect, a one-place channel.&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;MVars can be implemented in F# STM like so.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; MVar&amp;lt;'a&amp;gt; = TVar&amp;lt;option&amp;lt;'a&amp;gt; &amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; newEmptyMVar () = newTVar None&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; newFullMVar v = newTVar (Some v)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; takeMVar mv = &lt;br /&gt;  stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = readTVar mv&lt;br /&gt;        return! &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; v &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some a -&amp;gt; &lt;br /&gt;                    stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! writeTVar mv None&lt;br /&gt;                          return a }&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; retry () }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; putMVar mv a =&lt;br /&gt;  stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = readTVar mv&lt;br /&gt;        return! &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; v &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; writeTVar mv (Some a)&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some _ -&amp;gt; retry () }&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; newEmptyMVar : unit -&amp;gt; MVar&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; newFullMVar : 'a -&amp;gt; MVar&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; takeMVar : MVar&amp;lt;'a&amp;gt; -&amp;gt; Stm&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; putMVar : MVar&amp;lt;'a&amp;gt; -&amp;gt; 'a -&amp;gt; Stm&amp;lt;unit&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;retry&lt;/span&gt; operation is used to re-execute a transaction from the beginning. There is no point re-executing the transaction immediately because no memory locations will have changed. So the retry operation blocks until some memory changes that might allow the transaction to make further progress. This is how blocking is implemented with STM.&lt;/P&gt;
&lt;P&gt;Another feature of STM that makes it more composable than locks is how it handles blocking. The get/put MVar operations above are blocking operations. If an MVar library was written using locks and non-blocking versions of these operations were required then they would have to be implemented by the library developer and exposed as part of the library’s public interface. Not so with STM: if the MVar interface only exposes blocking get/put operations then it is possible for the user of the library to write the non-blocking versions, and vice-versa.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryTakeMVar mv = &lt;br /&gt;  orElse &lt;br /&gt;    (stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = takeMVar mv&lt;br /&gt;           return Some v })&lt;br /&gt;    (stm { return None })&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; tryTakeMVar mv : MVar&amp;lt;'a&amp;gt; -&amp;gt; Stm&amp;lt;'a option&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The function &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;tryTakeMVar&lt;/span&gt; is the non-blocking version of &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;takeMVar&lt;/span&gt;; it returns an option value depending on whether a value was available. The key here is the &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;orElse&lt;/span&gt; operation. This function takes two transactions and tries to execute the first. If the first fails with a retry/block then it executes the second. So in this example if &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;takeMVar&lt;/span&gt; retries/blocks then it will return &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;None&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;Also included in the code download is the &lt;A href="http://research.microsoft.com/~simonpj/papers/stm/index.htm#beautiful"&gt;Santa program&lt;/A&gt;, a singly-linked list queue, and a fixed-length array queue.&lt;/P&gt;
&lt;P&gt;Of course all these great benefits of STM come at a price, and that price is performance. An STM program is probably always going to be slower than a lock-based program. This STM implementation was engineered for correctness and design of the monadic interface and so probably has really bad performance.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=4565" width="1" height="1"&gt;</description><enclosure url="http://cs.hubfs.net/blogs/hell_is_other_languages/attachment/4565.ashx" length="9791" type="application/x-zip-compressed" /></item></channel></rss>