% flag to use fancy fonts / graphics
\newif\ifjnf\jnftrue

\documentclass[11pt]{article}

\usepackage{tikz}
\usetikzlibrary{arrows}
\usepackage{cmtt}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{url}
\usepackage[margin=1in]{geometry}
\usepackage{mathpartir}
\usepackage{listings}

\usepackage{csnotes}
\newtheorem{proposition}{Proposition}

% local definitions for this lecture
%\newcommand{\lam}[2]{\ensuremath{\lambda #1.\,#2}}
%\newcommand{\definedas}{\ensuremath{\triangleq}}
\newcommand{\subst}[3]{\ensuremath{#1[#2/#3]}}
\newcommand{\bnf}{\ensuremath{\; \mid \;}}

\newcommand{\defeq}{\ensuremath{\overset{\Delta}{=}}}
\newcommand{\defiff}{\ensuremath{\overset{\Delta}{\Leftrightarrow}}}

\newcommand{\versioned}[1]{\ensuremath{\texttt{versioned}\langle#1\rangle}}
\newcommand{\cumulative}[2]{\ensuremath{\texttt{cumulative}\langle #1,#2 \rangle}}
\newcommand{\tlist}[1]{\ensuremath{\texttt{list}\langle#1\rangle}}
\newcommand{\pair}[2]{\ensuremath{\texttt{pair}\langle#1\rangle}}

\newcommand{\intreg}{\texttt{IntReg}}
\newcommand{\intregadd}{\texttt{IntRegAdd}}
\newcommand{\val}{\texttt{Val}}


\begin{document}

\header{15 November 2011}{Raghu Rajkumar}

\section{Introduction}
   \indent \indent
   The goal of writing parallel programs is to increase throughput by means of concurrent execution while maintaining consistency of shared data. In transactional methods, consistency is maintained by the appropriate use of synchronization primitives, such as locks. However, such programs admit multiple different interleavings of statements, resulting in nondeterministic executions.

  Burckhardt, Baldassin, and Leijen present an alternative approach, namely Revisions, to maintaining consistency of shared data, in which explicit support is provided for the programmer to specify how conflicting writes to shared data must be resolved. The major advantage of this approach is that the use of revisions does not create nondeterminism.

  
\section{Transactions vs. Revisions}

Let us consider three different variants of a very simple program.

\begin{center}
\begin{minipage}[t]{3.3in}
\begin{verbatim}
void foo() {
   if (y=0)
      x=1;
}
\end{verbatim}
\end{minipage}
\begin{minipage}[t]{1.3in}
\begin{verbatim}
void bar() {
   if (x=0)
      y=1;
}
\end{verbatim}
\end{minipage} 
\end{center}


\begin{enumerate}
 \item Sequential Execution
\begin{center}
\begin{minipage}[t]{2.5in}
  int x = 0;
\\  int y = 0;
\\  task t = fork \{ foo(); \}
\\  bar();
\\  join t;
\\ 
\end{minipage}
\begin{minipage}[t]{2in}
\begin{center}
Possible Outputs 

\begin{tabular}{c|c}
  x & y \\
  \hline
  0 & 1 \\
  1 & 0 \\
  1 & 1
\end{tabular}
\end{center}
\end{minipage} 
\end{center}

When executing sequentially, both threads operate on shared state, and all interleavings of statement are possible. As a result, there are three possible output states (as in the table above), only the first two of which are serializable

 \item Transactional Execution
\begin{center}
\begin{minipage}[t]{2.5in}
  int x = 0;
\\  int y = 0;
\\  task t = fork \{ atomic \{ foo(); \} \}
\\  atomic \{ bar(); \}
\\  join t;
\\ 
\end{minipage}
\begin{minipage}[t]{2in}
\begin{center}
Possible Outputs 

\begin{tabular}{c|c}
  x & y \\
  \hline
  0 & 1 \\
  1 & 0 
\end{tabular}
\end{center}
\end{minipage} 
\end{center}
Using transactional semantics, the program execution will be equivalent to \textit{some} serializable schedule. The possible outputs are $x=0, y=1$ and $x=1, y=0$ depending on whether foo(); or bar(); was executed first.

 \item Revisioned Execution
\begin{center}
\begin{minipage}[t]{2.5in}
    versioned$\langle$int$\rangle$ x = 0;
\\  versioned$\langle$int$\rangle$ y = 0;
\\  revision r = rfork \{ foo(); \}
\\  bar();
\\  rjoin r;
\\ 
\end{minipage}
\begin{minipage}[t]{2in}
\begin{center}
Possible Outputs 

\begin{tabular}{c|c}
  x & y \\
  \hline
  1 & 1 
\end{tabular}
\end{center}
\end{minipage} 
\end{center}
Using Revision semantics, each forked revision gets its own copy of the shared state. When two revisions are joined, the states of each are merged on a per-variable basis, resulting in the output of $x=1, y=1$. 

\end{enumerate}

\section{Revision Diagram}
Revision diagrams aid in visualizing the flow of control in a revisioned program. The following is a revision diagram for the example above.   

\begin{figure}[h]
\centerline{\tikz\node[scale=.3]{\pgfimage{revdiagram-crop}};}
\caption{A revision diagram}\label{revdiagram}
\end{figure}


  \subsection{Nested Revisions}
  The statement \verb|rfork e| returns a handle to the new revision that is forked. Any revision that has access to this handle can join with the corresponding revision, enabling the creation of nested revisions. Some nestings are not possible, as the only point at which a revision handle can be passed from one revision to another is at a join. The following figure shows possible and impossible nestings.

  \centerline{\tikz\node[scale=.65]{\pgfimage{nesting-crop}};}
  
\section{Isolation Types}
  Isolation types are datatypes that specify a merging function to reconcile updates to a shared variable across revisions. The two isolation types defined in \cite{Burckhardt:2010-OOPSLA} are versioned types (\versioned{t}) and cumulative types (\cumulative{t}{f}).
  \subsection{Versioned Types}
    During a join, a variable of a versioned type behaves the same as a shared variable in the absence of conflict. 
    If there is a conflict, i.e. if both revisions udpdate a shared variable, then the value of the variable after the join is that  of the joining revision.
  \subsection{Cumulative Types}
    Cumulative Types have a defined $merge$ function that specifies the value of a cumulative variable following a join. The $merge$ function takes the original value, the joined revision's value, and the joining revision's value, and produces the value resulting from the join. Here are some examples of cumulative types
    \begin{enumerate}
     \item \cumulative{int}{\lambda (o, m, r). m + (r-o)}: This represents an integer variable, updates to which are additive.
     \item \cumulative{int}{\lambda (o, m, r). \text{if } r = o \text{ then } m \text{ else } r}: This represents a \versioned{int} as described above.
    \end{enumerate}

  \section{Datatype Granularity}
  Revisions do not enable maintenance of correctness constraints that involve two or more variables. For example, consider two \versioned{int}'s, $x$ and $y$, that represent co-ordinates of a point. The point must satisfy the constraint that it lies within the unit circle. The program from section 2 with the corresponding revision diagram in Figure \ref{revdiagram}, invalidates the constraint although neither revision violates the constraint on its own. The proposed solution to this problem is to define a versioned type containing both variables, for example, \versioned{\pair{int}{int}}.

\section{Sequential Types}
  It is dificult to define $merge$ functions for complex datatypes. For instance, what is a good $merge$ function for \tlist{int}? To address this, sequential datatypes are introduced in \cite{Burckhardt:2011-WODET}. 
  \begin{definition}
     A sequential datatype is a six-tuple $(S, R, M, I, \rho, \mu)$ where
     \begin{itemize}
      \item $S$ is a set of states
      \item $R$ is a set of read operations
      \item $M$ is a set of modify operations
      \item $I \in S$ is the initial state
      \item $\rho \in R \times S \rightarrow \val$ is the read function
      \item $\mu \in M \times S \rightarrow S$ is the modify function
     \end{itemize}

  \noindent
  For convenience, assume $\exists \epsilon \in M.~ \mu(\epsilon, s) = s$ for all $s \in S$. \\
  For a sequence of operations $m_1 \cdot \ldots \cdot m_k \in M^*$, we write $\mu(m_1 \cdot \ldots \cdot m_k, s)$ to stand for $\mu(m_k, \ldots, \mu(m_1, s)\ldots)$
  \end{definition}

  \subsection{Examples of sequential datatypes}
  \begin{enumerate}
  \item  $\intreg = (\mathbb{Z}, \{get\}, \{set(i) \mid i \in \mathbb{Z} \}, 0, \rho, \mu)$ \\
  $\begin{array}{llcl}
    \textnormal{where } & \rho(get, i) &=& i \\
    \textnormal{and } & \mu(set(i'), i) &=& i'    
   \end{array}$

  \item $\intregadd = (\mathbb{Z}, \{get\}, \{set(i), add(i) \mid i \in \mathbb{Z} \} , 0, \rho, \mu)$ \\
   $\begin{array}{llcl}
    \textnormal{where } & \rho(get, i) &=& i \\
    \textnormal{and } & \mu(set(i'), i) &=& i' \\
    \textnormal{and } & \mu(add(i'), i) = i+i'
   \end{array}$ 
  \end{enumerate}

  \begin{definition}
     Two operations $w_1, w_2$ are equivalent for a sequential datatype $D$, written $w_1 \cong_D w_2$ if and only if
     \[ \forall s \in S.~ \mu(w_1,s) = \mu(w_2, s) \]
  Example: $set(i) \cong_{\intregadd} set(0) \cdot add(i)$
  \end{definition}

  \section{Compensations}
    Intuitively, compensations are functions that compensate for modifications done by the other revision in the join.

  \begin{definition}
   A compensation specification for a sequential datatype $D$ is a function $$c^* \in (M^* \times M^*) \rightarrow (M^* \times M^*)$$
   For convenience, we define 
   \begin{eqnarray*}
     c_l^* &\defeq \pi_1 \circ c^* \\
     c_r^* &\defeq \pi_2 \circ c^* 
   \end{eqnarray*}
  \end{definition}

 \begin{definition}
   A compensation specification $c^*$ is consistent iff 
   \[ \forall w_l, w_m \in M^*.~ w_l \cdot c_l^*(w_l, w_r) \cong_D w_r \cdot c_r^*(w_l, w_r) \]
 \end{definition}

  \subsection{Compensation Tables and Tiling}
  A compensation table is a function $c : (M \times M) \rightarrow (M \times M)$. A compensation table uniquely defines a consisent compensation specification. The figure below shows how $c^*(m_1 \cdot m_2, m_3 \cdot m_4)$ can be computed by tiling the correspoding compensation table $c$.

  \begin{center}
   \tikz\node[scale=.65]{\pgfimage{tiling-crop}};
    $v_1 = c_r (m_2 , c_l (m_1 , m_3 ))$ \\ 
    $v_2 = c_l (c_r (m_1 , m_3 ), m_4)$
  \end{center}



  \section{Concrete Implementations of Sequential Datatypes}
    A concrete implementation is a tuple $(S, R, M, I, \rho, \mu, r, f)$ 

    \begin{tabular}{lll}
    where & $(S, R, M, I, \rho, \mu)$ & is a sequential datatype \\
    and  & $r \in S \rightarrow S$ & is a replication function \\
    and  & $f \in S \times S \times S \rightarrow S$ & is a merge function \\
    \end{tabular}

\noindent
    A replication function produces a new state when a fork occurs, and the merge function is isomorphic to that of cumulative types (the order of parameters is different).
    
  \subsection{Concrete Implementation of \intregadd}
  The compensation table $\intregadd$ and the corresponding concrete implementation is given below. $R(i)$ represents a value that is relative, and $A(i)$, one that is absolute. $X(i)$ stands for either $R(i)$ or $A(i$).


\begin{center}
      \[\begin{array}{ll}
      c(add(i), add(j)) &= (add(j), add(i)) \\
      c(set(i), add(j)) &= (add(j), set(i+j)) \\
      c(add(i), set(j)) &= (set(j), \epsilon) \\
      c(set(i), set(j)) &= (set(j), \epsilon) 
      \end{array}\]
\textbf{Compensation Table for \intregadd}

  \[\begin{array}{rl}
   S &= \{A(i), R(i) \mid i \in \mathbb{Z}\} \\
   I &= A(0) \\
   R &= \{get\} \\   
   M &= \{set(i), add(i) \mid i \in Z\} \\
   \rho(get, X(i)) &= i \\
   \mu(set(i), X(j)) &= A(i) \\
   \mu(add(i), X(j)) &= X(j+i) \\
   r(X(i)) &= R(i) \\
   f(\_, A(m), \_) &= A(m) \\
   f(A(n), R(m), X(i)) &= A(n+m-i) \\
   f(R(n), R(m), X(i)) &= X(n+m-i)
  \end{array}\]
\textbf{Concrete Implementation of \intregadd}
\end{center}  

\noindent
\textbf{Acknowledgement:} The figures in these notes were taken from the references.
  
\begin{thebibliography}{9}
  \bibitem{Burckhardt:2010-OOPSLA} Sebastian Burckhardt, Alexandro Baldassin, and Daan Leijen. Concurrent programming with revisions and isolation types. In \textit{Proceedings of the ACM international conference on Object oriented programming systems and applications (OOPSLA '10).}
  \bibitem{Burckhardt:2011-WODET} Sebastian Burckhardt, Manuel Fahndrich, and Daan Leijen. Roll forward, not back - A case for deterministic conflict resolution. In \textit{The 2nd Workshop on Determinism and Correctness in Parallel Programming, 2011.}
  \bibitem{Burckhardt:2011:ESOP} Sebastian Burckhardt and Daan Leijen. Semantics of concurrent revisions. In \textit{Proceedings of the 20th European conference on Programming languages and systems: part of the joint European conferences on theory and practice of software (ESOP '11/ETAPS '11)}
\end{thebibliography}

\end{document}

