1
infinite number of active processes x(y).P running in parallel. Identifiers x and
y are taken from a denumerable set of names. Symbol T is the type of a value:
int represents integer values and (T ) denotes a channel type carrying values of
type T . The operational semantics and the type system for the π-calculus are
the standard and can be easily found in the literature [15].
registers r ::= r1 | . . . | rR
integer values n ::= . . . | -1 | 0 | 1 | . . .
lock values b ::= -1 | 0 | 1 | 2 | . . .
values v ::= r | n | b | l | pack τ, v as τ | packL α, v as τ |
v[τ ] | ?τ
instructions ι ::= r := v | r := r + v | if r = v jump v |
r := malloc [~τ ] guarded by α | r := v[n] | r[n] := v |
α, r := newLock b | α := newLockLinear
r := tslE v | r := tslS v | unlockE v | unlockS v |
α, r := unpack v | fork v
basic blocks I ::= ι; I | jump v | yield
heaps H ::= {l1 : h1 , . . . , ln : hn }
heap values h ::= hv1 . . . vn iα | τ {I}
New to typed assembly languages is the inclusion of threads and the use of
locks to discipline shared-memory access by multiple threads running in parallel.
Threads are started using the fork instruction and execute until the processor
is (voluntarily) released with a yield instruction. Lock value 0 designates an
open lock; values 1, 2, . . . , n denote a lock held by n threads with reading
capabilities (shared reading); and value -1 indicates a lock held exclusively.
Lock manipulation is performed by newLock, newLockLinear for lock creation,
tslE, tslS for lock acquisition, and unlockE, unlockS for lock disposal (suffix E for
exclusive, S for shared).
The syntax for types is generated by the following grammar.
2
the processor. We follow [4] and represent locks by singleton types (lock(α),
where α is a type variable), splitting locks usage into shared, lockS(α), and
exclusive, lockE(α), thus allowing us to implement multiple readers for the same
heap tuple. (Notice that we require every single tuple to be protected by a lock.)
Code blocks are of type ∀[~ α].(Γ requires Λ), where the universal abstraction
∀[~
α] affects the register file Γ and the triple of required permissions Λ, which
corresponds, respectively, to the required exclusive, shared, and linear locks.
The type system enforces that well-typed programs are free from race conditions.
Details can be found in references [2, 16].
Channel queue types are parametric on the type of the messages τ and on the
lock β that enforces mutual exclusion on channel queue operations.
A channel packs together a channel queue and a lock specific for each channel
(i.e., we implement channels as monitors [7]). Notice the usage of the existential
quantifier over locks ∃l in the channel type.
def
Channel(τ ) = ∃l β.hChannelQueue(τ, β), hlock(β)iβ iγ
Channel types are parametric on the type of the messages τ . Henceforth, we use
a global shared lock γ to protect Channels, and local shared locks α to protect
the different environments. Notice that the run-time API encapsulates lock
usage, keeping API clients from manipulating locks directly.
The API makes available two operations for sending and receiving messages
through channels. Operation send transmits a message (in register r1 of type τ )
through a channel (in register r4 ). In case there are no receptors waiting on the
channel queue, the message is enqueued. The send code block signature is as
follows:
send ∀[τ ](r1 : τ, r4 : Channel(τ ))
Operation receive places a process, described by its closure (continuation in
register r1 , environment in register r2 , and environment’s lock α in register r3 ),
in a channel (in register r4 ). Register r6 contains a flag indicating whether the
input process is replicated. As for the case of message sending, input processes
are blocked when there is no pending message for the channel. The code block
signature follows.
3
Compiling π into MIL. The translation from the π-calculus into MIL
comprises the translation of types T [[·]], of values V[[·]](~x, r), and of processes
P[[·]](~x, l, Γ). The translation of types is straightforward.
def def
T [[int]] = int T [[(T )]] = Channel(T [[T ]])
The translation of values follows, where r is the register holding the values
x1 . . . xn in the environment.
(
def v if v is an integer value
V[[v]](x1 . . . xi . . . xn , r) =
r[i] if v = xi
For the output process, we prepare the registers as expected by code block
send, by moving message v into register r1 and fetching the channel from the
environment into register r4 . When translating the parallel process, we fork the
execution of the process on the left, and, because we loose the permission α to
use the environment, we have to acquire it before continue executing the process
4
on the right. Finally, we show the translation of the input process.
def
P[[xi (y).P ]](~x, l, Γ) = l1 Cont(τ, τe ) {
l ProcBlock(Γ, ~x) { CreateEnvironment(~xy, r2 , r4 )
r4 := r2 [i] r2 := r4
unlockS r3 jump l2 [α]
r1 := l1 }
r6 := 0 P[[P ]](~xy, l2 , Γ)
jump receive[τe ][τ ][α] where τ = T [[Γ(y)]],
} τe = Env(~x, Γ, α),
l1 and l2 are fresh labels
In code block l we prepare the parameters for the receive operation, by moving
the channel xi into register r4 and setting the continuation as l1 . In the contin-
uation l1 , we create the environment for P and, after that, we jump to the body
of the input in l2 . The interested reader may refer to the companion technical
report for details [2].
Related and future work. All related work we are aware off is geared to-
wards sequential machines. Pict [14] translates the π-calculus into the C pro-
gramming language. Lopes et al. [9] present a framework for compiling process
calculi; contrary to MIL, the target language is untyped. Morrisett et al. [13]
present a translation from the System F into a typed assembly language, two
sequential languages.
We are currently working on a translation from the π-calculus into MIL
equipped with compare and swap rather than locks. Our aim is to obtain a
wait-free implementation of the π-calculus.
References
[1] G. Boudol. Asynchrony and the π-calculus (note). Rapport de Recherche
1702, INRIA Sophia-Antipolis, 1992.
5
[2] T. Cogumbreiro, F. Martins, and V. T. Vasconcelos. Compiling the π-
calculus into a Multithreaded Typed Assembly Language. DI/FCUL TR
08–13, Department of Computer Science, University of Lisbon, 2008.