package threadcso
The standard threadCSO
API. Most modules using CSO
will need only the
declaration:
import io.threadcso._
The present version of the ThreadCSO library API is 1.2R
r (for some number r)
The revision number (R
r) will change if bugs are corrected but the
code remains consistent with the previous API. Its minor
version number will change if there is a correction to the
code that breaks consistency with the previous API. Its major
version will change if there is a substantial change in the semantics
of an important CSO construct.
August 2017: changes 1.1 => 1.2
- renaming of very many internal classes and packages
- basic channel implementations are more efficient, in some case much more so
- alternation reliability improved
- debugger registration of alternations is no longer needed
- home-grown semaphores can specify which component they are part of: this makes interpreting a stack backtrace very much easier
- there is a flexible logging system that is compatible with the debugger
April 2016: changes 1.0 => 1.1
- Extended rendezvous read operator is now ??
(was
?)
- Extended rendezvous read event notation is now
=??=>
(was=?=>>
) - The notation
is now equivalent toinport ? f
f(inport?())
This makes for a tidier layout when the functionf
is an explicit functional expression.
Feb 1 2017: changes 1.1R1 => 1.1R2
- Removed dependencies on deprecated Java->Scala functions: replaced with .asJava
@author Bernard Sufrin, Oxford $Revision: 286 $ $Date: 2017-11-18 17:41:30 +0000 (Sat, 18 Nov 2017) $
- Alphabetic
- By Inheritance
- threadcso
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Type Members
- type ![T] = OutPort[T]
- type ?[T] = InPort[T]
- type Barrier = threadcso.lock.Barrier
-
type
Chan[T] = threadcso.alternation.channel.Chan[T]
Type of an alt-capable channel as returned by the standard factory methods of the
io.threadcso
API. - type CombiningBarrier[T] = threadcso.lock.CombiningBarrier[T]
- type Condition = java.util.concurrent.locks.Condition
- type Debuggable = threadcso.debug.REGISTRY.Debuggable
-
class
DebuggerFormat
extends Debuggable
A concrete debuggable class whose
toString
method evaluates the expressiontheFormat
whenever it is called (normally by the debugger).A concrete debuggable class whose
toString
method evaluates the expressiontheFormat
whenever it is called (normally by the debugger). This is a notationally convenient way of constructing a debugger-registerable object that can be used to show (part of) the state of a running process.For example, the copy process below keeps track of the number of values it has copied, and of the last value. It registers a
DebuggerFormat
with the debugger, so that if the debugger is invoked during therepeat
, then the current state of the process will be shown when the debugger is showing its registered objects.def mycopy[T](in: ?[T], out: ![T]) = proc { var buf = in.nothing var n = 0 val format = new DebuggerFormat(s"$n: $buf") format.withDebugger(true) { repeat { buf=in?(); out!buf; n+=1 } } }
The method
withDebugger
(see below) is a convenient way of constructing and registering a debugger format to be used during the evaluation of an expression. - type FairMonitor = threadcso.monitor.FairMonitor
- type Flag = threadcso.semaphore.Flag
-
implicit
class
Guarded
extends AnyRef
This implicit class is used in the implementation of guarded I/O-event notation.
This implicit class is used in the implementation of guarded I/O-event notation. The operator
&&
replaced the operator&&&
in CSO version 1.2.- See also
- type Latch = threadcso.semaphore.Latch
- type Milliseconds = Long
- type Monitor = threadcso.monitor.Monitor
-
implicit
class
NanoTime
extends AnyRef
This implicit class provides additional methods that support the legible formatting of the
Nanoseconds
value_elapsed
(which can be negative). -
type
Nanoseconds = Long
Provides the source location to pass as
(implicit loc: SourceLocation)
parameters -
type
PROC = threadcso.process.PROC
Process type
- type Semaphore = threadcso.semaphore.Semaphore
Value Members
-
def
Alternation(events: Event)(implicit loc: SourceLocation.SourceLocation): Run
Compile an alternation.
Compile an alternation. This can be useful for making a strength-reduction optimization by taking the compilation/normalization of the body of the alternation outside a loop.
val a = Alternation(events); ... ; a.alt
(wherea
is a variable not occuring in ...) is always equivalent to... alt(events)
. Likewise forprialt
,priserve
, andserve
.- Annotations
- @inline()
-
def
Alternation(debug: Boolean, events: Event)(implicit loc: SourceLocation.SourceLocation): Run
Compile an alternation.
Compile an alternation. This can be useful for making a strength-reduction optimization by taking the compilation/normalization of the body of the alternation outside a loop.
val a = Alternation(events); ... ; a.alt
(wherea
is a variable not occuring in ...) is always equivalent to... alt(events)
. Likewise forprialt
,priserve
, andserve
.- Annotations
- @inline()
-
def
Barrier(n: Int, name: String = ""): Barrier
Factory for
Barrier
s -
val
BooleanSemaphore: threadcso.semaphore.BooleanSemaphore.type
Factory for
BooleanSemaphore
s.Factory for
BooleanSemaphore
s. @see io.threadcso.semaphore.BooleanSemaphore -
def
CombiningBarrier[T](n: Int, e: T, f: (T, T) ⇒ T, name: String = ""): CombiningBarrier[T]
Factory for
CombiningBarrier
s -
val
CountingSemaphore: threadcso.semaphore.CountingSemaphore.type
Factory for
CountingSemaphore
s.Factory for
CountingSemaphore
s. @see io.threadcso.semaphore.CountingSemaphore -
val
Day: Nanoseconds
Number of nanoseconds in a day:
n*Day
is n days expressed as nanoseconds -
val
Flag: threadcso.semaphore.Flag.type
Factory for
Flag
s. -
val
Hour: Nanoseconds
Number of nanoseconds in an hour:
n*Hour
is n hours expressed as nanoseconds -
val
Latch: threadcso.semaphore.Latch.type
Factory for
Latch
es - def ManyMany[T]: SharedAltCapableChannel[T]
-
def
ManyMany[T](name: String = null): SharedAltCapableChannel[T]
Abbreviation for N2N(0, 0, name)
- def ManyOne[T]: SharedAltCapableChannel[T]
-
def
ManyOne[T](name: String = null): SharedAltCapableChannel[T]
Abbreviation for N2N(0, 1, name)
-
val
Min: Nanoseconds
Number of nanoseconds in a minute:
n*Min
is n minutes expressed as nanoseconds -
def
Monitor(fair: Boolean, name: String = null): AbstractMonitor
A new
AbstractMonitor
object (either aFairMonitor
or aMonitor
) whose lock-acquisition policy is as specified byfair
. -
def
N2N[T](writers: Int, readers: Int, name: String = null, fairOut: Boolean = false, fairIn: Boolean = false): SharedAltCapableChannel[T]
Return a synchronous alt-capable channel (with the given
name
) designed for shared synchronous communication betweenwriters
writers, andreaders
readers.Return a synchronous alt-capable channel (with the given
name
) designed for shared synchronous communication betweenwriters
writers, andreaders
readers. When all writers have invoked the methodcloseOut
(or all readers the methodcloseIn
), the channel closes. If eitherwriters
orreaders
is nonpositive, then the channel can be closed an unbounded number of times in the associated direction. -
def
N2NBuf[T](size: Int, writers: Int, readers: Int, name: String = null, fairOut: Boolean = false, fairIn: Boolean = false): SharedAltCapableChannel[T]
Return a buffered alt-capable channel (with the given
name
) designed for shared communication betweenwriters
writers, andreaders
readers.Return a buffered alt-capable channel (with the given
name
) designed for shared communication betweenwriters
writers, andreaders
readers. When all writers have invoked the methodcloseOut
(or all readers the methodcloseIn
), the channel closes. If eitherwriters
orreaders
is nonpositive, then the channel can be closed an unbounded number of times in the associated direction. - def OneMany[T]: SharedAltCapableChannel[T]
-
def
OneMany[T](name: String = null): SharedAltCapableChannel[T]
Abbreviation for N2N(1, 0, name)
-
def
OneOne[T]: Chan[T]
Return a synchronous alt-capable channel (with an automatically-generated
name
) designed for point-to-point communication.Return a synchronous alt-capable channel (with an automatically-generated
name
) designed for point-to-point communication. There is a (weak) dynamic check against multiple processes writing/reading simultaneously. -
def
OneOne[T](name: String = null): Chan[T]
Return a synchronous alt-capable channel (with the given
name
) designed for point-to-point communication.Return a synchronous alt-capable channel (with the given
name
) designed for point-to-point communication. There is a (weak) dynamic check against multiple processes writing/reading simultaneously. -
def
OneOneBuf[T](size: Int, name: String = null): Chan[T]
Return a buffered alt-capable channel (with the given
name
) designed for communication between a writer and a reader.Return a buffered alt-capable channel (with the given
name
) designed for communication between a writer and a reader. This is functionally equivalent toN2NBuf(size, 1, 1, name)
. -
val
SKIP: threadcso.process.PROC
A process that does nothing.
-
val
Sec: Nanoseconds
Number of nanoseconds in a second:
n*Sec
is n seconds expressed as nanoseconds -
val
after: (⇒ Nanoseconds) ⇒ AfterDeadline
after syntax for 'alt' bodies
-
def
alt(debug: Boolean, events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
Execute an alt (while registered with the debugger, if
debug
) -
def
alt(events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
Execute an alternation
-
def
attempt[T](body: ⇒ T)(alternative: ⇒ T): T
Evaluate
body
and return its value unless an exception ex is thrown.Evaluate
body
and return its value unless an exception ex is thrown. If ex is aStopped
then evaluate and return the value ofalternative
, otherwise re-throw ex.- Annotations
- @inline()
-
lazy val
debugger: DEBUGGER
The debugger (if it is loaded), else null.
The debugger (if it is loaded), else null. The debugger's port is specified by the integer N set as a runtime option by
-Dio.threadcso.debugger.port=
N (the default setting is zero). If N is negative, the debugger is not loaded; if N is zero, the debugger is loaded and made available at some currently-free port on the local host; if N is positive then the debugger is loaded and made available at port N if that port is free. -
def
exit(code: Int): Unit
Close down the thread pools, and exit the program, yielding
code
.Close down the thread pools, and exit the program, yielding
code
.- Annotations
- @inline()
-
def
exit(): Unit
Close down the thread pools, and exit the program.
Close down the thread pools, and exit the program.
- Annotations
- @inline()
-
def
fork(proc: PROC): Handle
Run the given
proc
in an acquired thread, and return a handle on the running thread.Run the given
proc
in an acquired thread, and return a handle on the running thread.- Annotations
- @inline()
-
def
interrupted(): Boolean
Returns true iff the current thread has been cancelled, and clears the cancelled bit in the thread if so.
-
val
microSec: Nanoseconds
Number of nanoseconds in a microsecond:
n*microSec
is n microseconds expressed as nanoseconds -
val
milliSec: Nanoseconds
Number of nanoseconds in a millisecond:
n*milliSec
is n milliseconds expressed as nanoseconds -
def
milliTime: Milliseconds
Read the system millisecond timer
Read the system millisecond timer
- Annotations
- @inline()
-
val
nanoSec: Nanoseconds
Number of nanoseconds in a nanosecond
-
def
nanoTime: Nanoseconds
Read the system nanosecond timer
Read the system nanosecond timer
- Annotations
- @inline()
-
val
orelse: threadcso.alternation.event.orelse.type
orelse syntax for 'alt' bodies
-
def
par[T](range: Seq[T])(gen: (T) ⇒ PROC): Unit
Same as
par(range.map(gen))
Same as
par(range.map(gen))
- Annotations
- @inline()
-
def
par(procs: Seq[PROC]): Unit
Run the parallel composition of
procs
Run the parallel composition of
procs
- Annotations
- @inline()
-
def
prialt(debug: Boolean, events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
Execute a prialt (while registered with the debugger, if
debug
) -
def
prialt(events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
Execute an alternation
-
def
priserve(debug: Boolean, events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
repeatedly execute an alt (while registered with the debugger, if
debug
) -
def
priserve(events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
repeatedly execute an alternation
-
def
proc(body: ⇒ Unit): PROC
proc { body }
is a
PROC
-valued expression denoting a simple process with a made-up name.It is, in-effect, a procedure of type
()=>UNIT
.run(proc { body }) = (proc { body })() = (()=>body)()
- Annotations
- @inline()
-
def
proc(name: String)(body: ⇒ Unit): PROC
proc ("name") { body }
is a
PROC
-valued expression denoting a simple process with the given name.- Annotations
- @inline()
-
def
repeat(body: ⇒ Unit): Unit
Iterate
body
.Iterate
body
. If an exception ex is thrown, then stop the iteration, and unless ex is aStopped
re-throw ex.- Annotations
- @inline()
-
def
repeat(guard: ⇒ Boolean)(body: ⇒ Unit): Unit
Iterate
body
while the evaluation ofguard
yieldstrue
.Iterate
body
while the evaluation ofguard
yieldstrue
. If an exception ex is thrown, then stop the iteration, then unless ex is aStopped
re-throw ex.- Annotations
- @inline()
-
def
repeatFor[T](it: Iterable[T])(fn: (T) ⇒ Unit): Unit
repeatFor (it: Iterable[T]) { bv => body }
applies the function{ bv => body }
to each of the elements of an iterator formed from the iterable.repeatFor (it: Iterable[T]) { bv => body }
applies the function{ bv => body }
to each of the elements of an iterator formed from the iterable. If an exception ex is thrown, then stop the iteration, then unless ex is aStopped
re-throw ex.- Annotations
- @inline()
-
def
run(proc: PROC): Unit
Run the given
proc
in the current thread.Run the given
proc
in the current thread.- Annotations
- @inline()
-
def
seconds(secs: Double): Nanoseconds
Convert a fractional time expressed in seconds to nanoseconds
-
def
serve(debug: Boolean, events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
repeatedly execute an alt (while registered with the debugger, if
debug
) -- event choice is fair -
def
serve(events: Event)(implicit loc: SourceLocation.SourceLocation): Unit
repeatedly execute an alternation -- ready events are chosen round-robin -- approximating fairness
-
def
sleep(ns: Nanoseconds): Unit
Sleep for the given number of nanoseconds
Sleep for the given number of nanoseconds
- Annotations
- @inline()
-
def
sleepms(ms: Milliseconds): Unit
Sleep for the given number of milliseconds.
Sleep for the given number of milliseconds.
- Annotations
- @inline()
-
implicit macro
def
sourceLocation: SourceLocation.SourceLocation
Implicit parameter to various methods
-
val
startTime: Nanoseconds
The value of
nanoTime
when the entire program was started -- useful only for relative timing. -
def
stop: Nothing
Terminate the current process or the current
repeat
Terminate the current process or the current
repeat
- Annotations
- @inline()
-
def
withDebuggerFormat[T](theFormat: ⇒ String, register: Boolean = true)(body: ⇒ T): T
Constructs a
DebuggerFormat
object from the given format string expression and registers it (ifregister
is true) with the debugger during the evaluation of thebody
expression.Constructs a
DebuggerFormat
object from the given format string expression and registers it (ifregister
is true) with the debugger during the evaluation of thebody
expression.For example, the copy process below keeps track of the number of values it has copied, and of the last value. If the debugger is invoked during the
repeat
, then the current state of the process will be shown when the debugger is showing its registered objects.def mycopy[T](in: ?[T], out: ![T]) = proc { var buf = in.nothing var n = 0 withDebuggerFormat(s"$n: $buf") { repeat { buf=in?(); out!buf; n+=1 } } }
-
val
|: (Seq[ExecutableEvent]) ⇒ ExecutableEventSyntax
prefix | syntax for 'alt' bodies
-
def
||[T](range: Seq[T])(gen: (T) ⇒ PROC): PROC
Same as
||(range.map(gen))
Same as
||(range.map(gen))
- Annotations
- @inline()
-
def
||(procs: Seq[PROC]): PROC
The parallel composition of
procs
; unlessprocs
is empty, in which caseSKIP
.The parallel composition of
procs
; unlessprocs
is empty, in which caseSKIP
.- Annotations
- @inline()
-
val
μS: Nanoseconds
Number of nanoseconds in a microsecond:
n*μS
is n microseconds expressed as nanoseconds -
def
π(name: String)(body: ⇒ Unit): PROC
Same as
proc(name)(body)
Same as
proc(name)(body)
- Annotations
- @inline()
-
def
π(body: ⇒ Unit): PROC
Same as
proc(body)
Same as
proc(body)
- Annotations
- @inline()
-
object
coerce
To enable implicit coercion of unit-valued expressions to simple processes:
import io.threadcso.coerce.UnitProc
.To enable implicit coercion of unit-valued expressions to simple processes:
import io.threadcso.coerce.UnitProc
. For example, in the scope of this coercion, the following process expressions are equivalent:(println("foo") || println("bar")) (proc { println("foo") } || proc { println("bar") })
CSO neophytes are strongly discouraged from importing this implicit coercion, for it can lead to confusing error messages from the compiler, and confusing behaviour at run-time.