This manual is meant to provide an informal introduction to Reglock.
Obviously, Reglock is a work in progress and we expect to make
substantial changes to the design and implementation. Your feedback
(and patience) is greatly appreciated.
This section describes the compilation steps required to build reglock.
svn co svn+ssh://svn.softlab.ntua.gr/var/lib/svnrepos/svn-pl/internal/ reglock/branches/mlock_impl
cd $RECLOCK_ROOT/mlock_impl/src
make
./f ../tests/testtype.x
or you could run test cases that should fail :
./f ../tests/testtype_fail.x
This section describes the Reglock compiler options.Make sure you have completed Section 2 before proceeding.
[pgerakios@localhost src]$ ./f --help Parsing args ... -I Append a directory to the search path -s Specify compilation stage: 0 = Parse , 1 = Binding , 2 = Type-checking , 3 = Interpret -v Specify verbosity level: 0 = None , 1 = Some , 2 = More , 3 = Lots -help Display this list of options --help Display this list of options
[pgerakios@localhost src]$ ./f -s 1 ../tests/testtype.5 Parsing args ... Parsing file ../tests/testtype.5 [OK] Binding ... [OK] Compilation successful.
Example:
[pgerakios@localhost src]$ ./f -s 2 -v 2 ../tests/testtype.5 Parsing args ... Parsing file ../tests/testtype.5 [OK] Binding ... [OK] Type-checking ... Checking --> printInt = \ x. () as {} int -> unit {} Ascripted type: {} int -> unit {} Checking --> printRgn = \ 'r. \ x. () as {} rgn('r) -> unit {} Ascripted type: Forall 'r. {} rgn('r) -> unit {} Checking --> printIntRef = \ 'r. \ x. () as {} ref(int,'r) -> unit {} Ascripted type: Forall 'r. {} ref(int,'r) -> unit {} Checking --> main = \ 'H. \ hrgn. newrgn 'r,x @ hrgn in ((thread1 ['r]) x $);rcapdec hrgn as {('H,1,bot,)} rgn('H) -> unit {('H,0,bot,)} Ascripted type: Forall 'H. {('H,1,bot,)} rgn('H) -> unit {('H,0,bot,)} Checking --> thread1 = \ 'r. \ x. rcapdec x as {('r,1,bot,)} rgn('r) -> unit {('r,0,bot,)} Ascripted type: Forall 'r. {('r,1,bot,)} rgn('r) -> unit {('r,0,bot,)} [OK]
Example:
---------------------------------- Last tid=2 Last rid = 1 Last lid = 6 Heap : (R0,1,-1,0)= {}||{(R1,1,0,2)= {L6 |-> null,L5 |-> (10,loc2), L4 |-> null,L3 |-> (10,loc2),L2 |-> (7,loc1), L1 |-> (5,null)}||{}}
A region header is denoted as (Rx,n1,n2,n3) where x is the region id, n1 is the region reference count , n2 is the lock count for this region and n3 is the thread owner id (it may be ignored when n2 = 0. Region contents are displayed and within curly brackets which are delimited by two consequtive vertical bars. A region consists of a private heap (the first set of curly brackets in the example above), which is a list of locations (Lx, where x ∈ 1...n) mapped to program values. The remaining contents denote subregions which have the same recursive structure.
Example:
Scheduling thread 1.
Note that 1 is not the thread id but the first thread in the scheduler’s list.
Example:
@@@@@@@@ Cann't free rgn0 (thread 0)
This message implies that thread id 0 is about to deallocate region 0 (main region) but it has detected that other threads own this/child regions so it busy-waits until it is possible to deallocate region 0.
Sideffects: Thread[2] ==> 5
Thread id = 0 rcapdec rgn0 Thread id = 2 rcapdec (rgn1,(10,loc2)).1
Program I/O: Thread[1] ==> 10 Thread[1] ==> 7 Thread[1] ==> 5 Thread[2] ==> 10 Thread[2] ==> 7 Thread[2] ==> 5
toplevel : EOF | def ID = TopFunc ; toplevel | def TVarList = TopType ; toplevel TVarList: 'ID | 'ID , TVarList TopType: Type | \ ( TVarList ).Type TopFunc: \ ID . Term as Type | \ TVarList . TopFunc Capability: bar(n) | * | bot | n Effect: ( 'ID , Capability , Capability , TVarList ) | ( 'ID , Capability , Capability ) | ( TVarList ) EffectList: | Effect EffectList TypeDef: | LBRACKET TVarList RBRACKET AtomicType: int | () | rgn ( 'ID ) | ref ( Type , 'ID ) | ref ( Type , 'NULL ) | { EffectList } Type -> Type { EffectList } | \ 'ID . Type | exists 'ID ( 'ID , TVarList ) . Type | 'ID TypeDef TypeX: AtomicType | AtomicType * TypeX | ( TypeX ) Type: TypeX Term: AppTerm | !Term | -Term | not Term | if Term then Term else Term | while Term do Term | open Term 'ID , ID in Term | pack 'ID, Term as Type | new Term @ Term | newrgn 'ID,ID @ Term in Term | rcapi Term | rcapd Term | lcapi Term | lcapd Term | let ID = Term in Term | Term binop Term Scope: | $ Assign: | COLON := Term AppTerm : PathTerm Assign | AppTerm PathTerm Scope | AppTerm [ 'ID ] PathTerm: PathTerm.n | AtomicTerm TermSeq : Term | Term , TermSeq | Term ; TermSeq ParenSeq: | TermSeq AtomicTerm: ( ParenSeq ) | ID | n | null
def 'List = \ ('r). ref (int * 'List ['r], 'r);
Answer: We only allow top-level region polymorphism in user-defined types. Therefore, when there exist several region names (a list of names) then the parenthesis aid in delimiting those regions. Consider a List whose nodes are allocated at different regions:
def 'List = \ ('r1,'r2). ref (int * 'List ['r2], 'r1);
This document was translated from LATEX by HEVEA.