\chapter{Ausgewählte Modulschnittstellen}
\label{Modulschnitt}
\section{Das Modul Mutex}
\label{MutexTi}

\begin{xple}
\k{interface} Mutex

\k{import} thread

\k{export}

  error, deadlock :\k{Exception} \k{end}

  T $<:$\k{Ok}

  State $<:$ \k{Ok}

  lockedMutex, gotMutex  :State

  new():T
  (* Create a new unlocked mutex *)

  newLocked():T
  (* Create a new locked mutex *)

  lock(mutex :T) :\k{Ok}
  (* Lock mutex *)

  unlock(mutex :T) :\k{Ok}
  (* Unlock mutex, release blocked threads *)

  tryLock(mutex :T) :State
  (* Asynchronous polling of mutex m. Aquires m if m is unlocked.
     Does not block if lock is held (returns locked) 
     Returns ok if locking m was successfull *)

  print(mutex :T) :thread.T(\k{Ok}) 
  (* Print out some statistics *)

\k{end}
\end{xple}
\newpage

\section{Das Modul Condition}
\label{ConditionTi}
\begin{xple}
\k{interface} Condition

\k{import} thread mutex

\k{export}

  error, deadlock :\k{Exception} \k{end}

  T $<:$ \k{Ok}

  new():T
  (* Create a new condition *)

  wait(m :mutex.T  cond :T) :\k{Ok}
  (* Calling thread must have mutex locked. Atomically unlock
     mutex and wait on cond. Then relock mutex *)

  signal(cond :T) :\k{Ok}
  (* Unblock one thread waiting on cond *)

  broadcast(cond :T) :\k{Ok}
  (* Unblock all threads waiting on cond *)

\k{end};
\end{xple}
\newpage

\section{Das Modul Rendezvous}
\label{RendezvousTi}
\begin{xple}

\k{interface} Rendezvous

\k{export}

  error, deadlock :\k{Exception} \k{end}


  T(R $<:$\k{Ok}) $<:$\k{Ok}


  SelectT   $<:$ \k{Ok}


  new(R $<:$\k{Ok}  x :R) :T(R)
  (* Create a new rendevous *)


  get(R $<:$\k{Ok}  r :T(R)) :R
  (* Block thread self on r until another thread calls put(r) *)


  put(R $<:$\k{Ok}  r :T(R)  value :R) :\k{Ok}
  (* Block thread self on r until another thread calls get(r) *)

  makeEntry(R$<:$\k{Ok}  rend :T(R)  func :\k{Fun}(:R) :\k{Ok}  guard :\k{Fun}() :Bool) :SelectT
  (* Create new entry for select.
     Function func(:R) will be called with value given by put(rend value)
  *)

  select(alt :Array(SelectT)  elseCase :optional.T(\k{Fun}():\k{Ok})) :\k{Ok}
  (* Select rendezvous from array alt or execute elseCase function (if any) *)

\k{end};
\end{xple}
\newpage

\section{Das Modul Thread}
\label{Thread}
\begin{xple}
\k{interface} Thread
   Author : Bernd Mathiske
\k{export}

  error :\k{Exception} \k{end}

  abortion :\k{Exception} \k{end}

  T(R $<:$\k{Ok}) $<:$\k{Ok}
  (* A value 'thread' of type 'T(R)' is a thread that
     computes a function with the result type 'R'. *)

  State $<:$ \k{Ok}

  runningState, blockingState, suspendedState, 
  terminatedState, exceptionState :State

  state(R $<:$\k{Ok}  thread :T(R)) :State
  (* Return the current evaluation state of 'thread'. *)

  new(R $<:$\k{Ok}  f(self :T(R)) :R) :T(R)
  (* Create a new ``suspended'' thread that is bound to evaluate 'f'.
     A handle to the new thread is provided both to the parent
     and the child: it is returned by 'new' and passed as
     an argument ('self') to 'f'. *)

  fork(R $<:$\k{Ok}  f(self :T(R)) :R) :T(R)
  (* Create a new ``running'' thread that evaluates 'f'.
     A handle to the new thread is provided both to the parent
     and the child: it is returned by 'fork' and passed as
     an argument ('self') to 'f'. *)

  launch(R $<:$\k{Ok}  f(self :T(R)) :R) :\k{Ok}
  (* Like 'suspend(thread.self())' and 'fork(f)' in parallel,
     but avoiding that the intermediate result of 'fork', a thread,
     be referentially reachable by the current thread. *)

  duplicate(R $<:$\k{Ok}  thread :T(R)) :T(R)
  (* Return a shallow copy of 'thread'. *)

  join(R $<:$\k{Ok}  thread :T(R)) :R
  (* If 'thread' is the current thread then raise 'error'.
     ``Block'' the current thread until 'thread' has terminated,
     Iff the final state of 'thread' is 'stateTerminated'
     then resume execution of the current thread 
     by returning the result of 'thread',
     else raise 'error'. *)

  joinCatch(R $<:$\k{Ok}  thread :T(R)) :R
  (* If 'thread' is the current thread then raise 'error'.
     ``Block'' the current thread until 'thread' has terminated,
     then 'catch(thread)'.
     Iff the final state of 'thread' is 'stateTerminated'
     then resume execution of the current thread 
     by returning the result of 'thread'. *)

  suspend(R $<:$\k{Ok}  thread :T(R)) :\k{Ok}
  (* Iff 'state(thread)' is one of 'runningState' and
     'blockingState' then suspend it, i.e. stop its evaluation
     and set its state to 'suspendedState'. 
     Iff 'state(thread) == suspendedState' then do nothing.
     Else raise 'error'. *)

  run(R $<:$\k{Ok}  thread :T(R)) :\k{Ok}
  (* Iff 'state(thread)' is one of 'runningState' and
     'blockingState' then do nothing.
     Iff 'state(thread) == suspendedState' then set its state to
     'runningState' and let it ``run'', i.e. perform its evaluation.
     Else raise 'error'. *)


  (**** Exception Handling: ****)
  catch(R $<:$\k{Ok}  thread :T(R)) :\k{Ok}
  (* Iff 'state(thread) == exceptionState' then raise the identical
     exception that has terminated 'thread' in the current thread,
     else do nothing. *)

  throw(R $<:$\k{Ok}  thread :T(R)  raiser() :\k{Ok}) :\k{Ok}
  (* Iff 'thread' is already finished then raise error
     in the current thread.
     Else evaluate 'raiser' in the current thread.
     Iff an exception evades from 'raiser' then pass 
     it over to 'thread', leaving the current thread unharmed.
     Iff there is no exception from 'raiser' then
     do not bother 'thread'. *)

  setThrowHandler(R $<:$\k{Ok}  thread :T(R)
                  handler(self :T(R)  catch() :\k{Ok}) :\k{Ok}) :\k{Ok}
  (* Default: 'let handler(...) = catch()'. *)


  (**** Premature termination: ****)
  abort(R $<:$\k{Ok}  thread :T(R)) :\k{Ok}
  (* 'throw(thread  fun() raise abortion'. *)

  kill(R $<:$\k{Ok}  thread :T(R)) :\k{Ok}
  (* Terminate 'thread' immediately and unconditionally -
     in 'exceptionState' with exception 'abortion'. *)


  (**** Queries: ****)
  main() :T(Int)
  (* Return the thread that has been created by the runtime system
     in order to execute a function with a signature like 'Main.main'. *)

  self() :T(\k{Ok})
  (* Return the current thread that calls this function,
     taking complete loss of the thread's return type into account. *)

  running() :Array(T(\k{Ok}))
  (* Return a vector of all currently running threads,
     neglecting their specific return types. *)


  (**** Synchronization: ****)
  atomic(R $<:$\k{Ok}  action() :R) :R
  (* Execute a ``critical section'' as an atomic 'action'. *)

  sleep(timeout :Real) :\k{Ok}
  (* Supend self() for 'timeout' seconds *)

  (**** Migration: ****)
  migrate(thread :T(\k{Ok})) :\k{Ok}
  (* Prepare thread for migration. Iff 'state(thread) == runningState'
     then suspend thread'. *)
  
  activate(thread :T(\k{Ok})) :\k{Ok}
  (* Change thread state.  Iff 'state(thread)==mig\_running' 
     then restart thread. *)

\k{end};
\end{xple}
\newpage

%\section{Das Modul Optional}
%\label{OptionalTi}
%\begin{xple}
%\k{interface} Optional
%
%\k{export}
%
%  T(A $<:$\k{Ok}) $<:$\k{Ok}
%  (* The type of an optional value of type A. *)
%
%  error :\k{Exception} \k{end}
%  (* Raised when any of the following operations cannot be carried out. *)
%
%  nil(A $<:$\k{Ok}) :T(A)
%  (* A ``null value'' of type A. *)
%  
%  new(A $<:$\k{Ok} a :A) :T(A)
%  (* Create a non-null value of type A. *)
%
%  null(A $<:$\k{Ok} optional :T(A)): Bool
%  (* Is this a null value? *)
%
%  value(A $<:$\k{Ok} optional :T(A)): A
%  (* Extract a non-null value. *)
%
%  valueDefault(A $<:$\k{Ok} optional :T(A) default :A): A
%  (* Extract a non-null value or return the default value for a
%     null-value. *)
%
%  equal(A $<:$\k{Ok} x,y :T(A)): Bool
%  (* equal(nil(:A) nil(:A))
%     equal(new(x),new(y)) iff x is y *) 
%
%  yes, no, unknown: T(Bool)
%  (* unknown = nil(:Bool)  yes = new(true)  no = new(false). *)
%
%\k{end};
%\end{xple}
\cleardoublepage

\chapter{Syntaxerweiterungen}
\section{Grammatik für Rendezvous}
\label{Rendezvoussyntax}
\begin{xple}
\k{grammar}

selectG:Value ===
 ``\k{select}''
 selectCase=selectCaseG
 selectCases=selectCasesG 
 elseCase=optSelectElseCaseG 
 ``\k{end}''
 allSelects=mkBndsCons(selectCase selectCases) 
 $=>$ \k{value} $<<|$ rendezvous.select(\k{array} allSelects \k{end}  elseCase) $|>>$

selectCasesG:Bnds ===
 ``\k{or}'' selectCase=selectCaseG selectCases=selectCasesG 
  $=>$ mkBndsCons(selectCase selectCases)
$|$ $=>$ mkBndsNil()

selectCaseG:Binding ===
 condition=optSelectCaseConditionG 
 swAlternative=swAlternativeG(condition) 
 $=>$ mkBndAnonValue(swAlternative)

optSelectElseCaseG:Value ===
 ``\k{else}'' b=bnds $=>$ \k{value} $<<|$ optional.new(\k{fun}() :\k{Ok}  \k{begin} b \k{end}) $|>>$
$|$                     $=>$ \k{value} $<<|$ optional.nil(:\k{Fun}() :\k{Ok}) $|>>$

optSelectCaseConditionG:Value ===
  ``\k{when}'' condition=\k{value} ``$\boldmath =>$'' $=>$ \k{value} $<<|$ \k{fun}() condition $|>>$
$|$                                              $=>$ \k{value} $<<|$ \k{fun}() true $|>>$

swAlternativeG(condition:Value):Value ===
 ``\k{accept}'' 
 name=identifier
 formals=optSWFormalsG
 block=optSWBlockG(formals)
  $=>$ \k{value} $<<|$ rendezvous.makeEntry(name block condition) $|>>$

optSWFormalsG:Sigs ===
  ``('' s=sigs ``)'' $=>$ s
$|$                     $=>$ mkSigsNil()

optSWBlockG(formals:Sigs):Value ===
  ``\k{do}'' b=bnds ``\k{end}'' $=>$ \k{value} $<<|$ \k{fun}(formals) \k{begin} b \k{end} $|>>$
$|$                              $=>$ \k{value} $<<|$ \k{fun}(formals) \k{ok} $|>>$


value3:Value $|==$ selectValue=selectG $=>$ selectValue

\k{end};
\end{xple}
%\newpage

%\chapter{Beispiele}
%\section{Lösung eines $m$-aus-$n$-Problems mittels Semaphoren}
%\label{M-aus-N}
%...

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "da"
%%% End: 
