#include <stdio.h>Go to the source code of this file.
Defines | |
| #define | mytrace |
| #define | instrCnt |
| #define | _BEGIN do { |
| Begin/end a macro. | |
| #define | _END } while (0) |
| #define | _idMax 8*sizeof(threadvector) |
| Number of threads. | |
| #define | clearPC(id) |
| #define | initPC(p, label) |
| #define | setPC(id, label) |
| #define | _declState |
| Dispatcher. | |
| #define | _BEGIN_SWITCH |
| #define | _END_SWITCH |
| #define | _ |
| #define | _break |
| #define | _SC_LABEL(label) label |
| #define | _goto_init(label) goto label |
| #define | _goto(label) goto label |
| #define | _goto_disp(label) goto label |
| #define | _deref(label) *label |
| #define | _ref(label) &&label |
| #define | _setStateInit |
| #define | _while(cond) while (cond) |
| #define | selectCid_() selectCid() |
| #define | dispatch_init() selectCid_(); _goto_init(_deref(_pc[_cid])) |
| #define | dispatch() selectCid_(); _goto_disp(_deref(_pc[_cid])) |
| #define | u2b(u) (1 << u) |
| Encoding of signal/thread 'u' (some non-negative int) in bitvector. | |
| #define | enable(id) |
| Thread enabling/disabling. | |
| #define | enableInit(id) |
| #define | disable(id) enabled &= ~u2b(id) |
| #define | disableSet(idset) enabled &= ~idset |
| #define | isEnabled(id) (enabled & u2b(id)) |
| #define | isEnabledNotOnly(id) (enabled != u2b(id)) |
| #define | isEnabledNoneOf(idset) ((enabled & idset) == 0) |
| #define | activate(id) active |= u2b(id) |
| Thread (de-)activation. | |
| #define | deactivate(id) active &= ~u2b(id) |
| #define | deactivateSet(idset) active &= ~idset |
| #define | isActive(id) (active & u2b(id)) |
| #define | _TickEnd 0 |
| #define | TICKSTART(isIni, p) |
| Start a tick (an instant). 'p' denotes the main thread. | |
| #define | TICKEND |
| Complete a tick. | |
| #define | dispatch_ _goto(_L_dispatch) |
| #define | dispatch_init_ _goto_init(_L_dispatch) |
| #define | mergedDispatch |
| #define | _CONCAT_helper(a, b) a ## b |
| Construct a label, of the form "_L'line in source file'". | |
| #define | _CONCAT(a, b) _CONCAT_helper(a, b) |
| #define | __LABEL__ _CONCAT(_L, __LINE__) |
| #define | __LABELL__ _CONCAT(_LL, __LINE__) |
| #define | PAUSE |
| Pause a thread, resume at subsequent statement. | |
| #define | PAUSEG(label) |
| Shorthand for 'PAUSE; GOTO(label)'. | |
| #define | PAUSEG_(label) |
| Helper function (if/else-unsafe). | |
| #define | HALT |
| Shorthand for 'label: PAUSE; GOTO(label)'. | |
| #define | SUSPEND(cond) |
| Suspend current thread if 'cond' is true. | |
| #define | SUSPENDG(label) |
| Suspend current thread, goto 'label'. | |
| #define | TRANS(label) |
| Transition to 'label', kill descendant threads (implements abortion). | |
| #define | ABORT |
| Abort (terminate) descendant threads. | |
| #define | ABORT_ |
| Helper function (if/else-unsafe). | |
| #define | TERM |
| Terminate a thread. | |
| #define | TERM_ _goto(_L_TERM) |
| Helper function (if/else-unsafe). | |
| #define | FORK(label, p) |
| Spawn a thread at 'label', with priority 'p'. | |
| #define | FORK_(label, p) |
| Helper function (if/else-unsafe). | |
| #define | FORKE(label) |
| Denote parent thread, starting at 'label'. | |
| #define | FORKE_(label) |
| Helper function (if/else-unsafe). | |
| #define | JOINELSE(elselabel) |
| Join completed child threads. | |
| #define | JOINELSEG(thenlabel, elselabel) |
| Shorthand for 'JOINELSE(elselabel); GOTO(thenlabel)'. | |
| #define | JOINELSEG_(thenlabel, elselabel) |
| Helper function (if/else-unsafe). | |
| #define | JOIN |
| Shorthand for 'elselabel: JOINELSE(elselabel)'. Join completed child threads. | |
| #define | PRIO(p) |
| Set priority of a thread. | |
| #define | PRIOG(p, label) |
| Shorthand for 'PRIO(p); GOTO(label)'. | |
| #define | PRIO_(p) |
| Helper function (if/else-unsafe). | |
| #define | PRIOG_(p, label) |
| Helper function (if/else-unsafe). | |
| #define | PPAUSEG(p, label) |
| Efficient shorthand for 'PRIO(p); PAUSE; GOTO(label)'. | |
| #define | PPAUSEG_(p, label) |
| Helper function (if/else-unsafe). | |
| #define | PPAUSE(p) |
| Efficient shorthand for 'PRIO(p); PAUSE'. | |
| #define | JPPAUSEG(p, thenlabel, elselabel) |
| Efficient shorthand for 'JOINELSE(label); GOTO thenlabel; label: PRIO(p); PAUSE; GOTO(elselabel)'. | |
| #define | JPPAUSEG_(p, thenlabel, elselabel) |
| Helper function (if/else-unsafe). | |
| #define | JPPAUSE(p, elselabel) |
| Shorthand for 'JOINELSE(label); GOTO thenlabel; label: PRIO(p); PAUSE; GOTO(elselabel); thenlabel:'. | |
| #define | SIGNAL(s) |
| Initialize a local signal (handles reincarnation). | |
| #define | EMIT(s) |
| Emission of a pure signal 's'. | |
| #define | SUSTAIN(s) |
| Sustain a pure signal 's'. | |
| #define | PRESENT(s) |
| Test for presence of signal 's'. | |
| #define | PRESENTELSE(s, label) |
| Test for presence of signal 's'. | |
| #define | PRESENTEMIT(s, t) |
| If signal 's' is present, emit 't'. | |
| #define | AWAITI(s) |
| Await (immediately) signal 's'. | |
| #define | AWAIT(s) |
| Await (non-immediately) signal 's'. | |
| #define | _declindex |
| #define | _setValInit |
| #define | EMITINT(s, val) |
| Emission of a valued signal 's', type integer. | |
| #define | EMITINTMUL(s, val) |
| Emission of a valued signal 's', type integer, combined with * . | |
| #define | VAL(s) |
| Retrieve value of signal 's'. | |
| #define | VALREG(s, reg) |
| Retrieve value of signal 's' into 'reg'. | |
| #define | _setPreInit |
| #define | setPre |
| #define | freezePre |
| #define | freezePreClear |
| #define | PRESENTPRE(s) |
| Test for presence of signal in previous tick. | |
| #define | PRESENTPREELSE(s, label) |
| Test for presence of signal in previous tick. | |
| #define | VALPRE(s) |
| Retrieve previous value of signal 's'. | |
| #define | VALPREREG(s, reg) |
| Retrieve previous value of signal 's' into 'reg'. | |
| #define | GOTO(label) |
| Just a goto that also gets counted as instruction. | |
| #define | ISAT(id, statelabel, label) |
| Test whether an Exit Action has to be performed. | |
| #define | CALL(label) |
| Call a function at 'label'. | |
| #define | RET |
| Return from a function call. | |
| #define | ISATCALL(id, statelabel, label) |
| Conditionally call a function. | |
| #define | instrCntIncr tickInstrCnt++; |
| Instruction counting/Tracing. | |
| #define | instrCntIncrc tickInstrCnt++, |
| #define | instrCntDecr tickInstrCnt--; |
| #define | trace0(f) printf(f); |
| If tracing is turned on, print trace string. | |
| #define | trace1(f, a) printf(f, a); |
| #define | trace2(f, a, b) printf(f, a, b); |
| #define | trace3(f, a, b, c) printf(f, a, b, c); |
| #define | trace4(f, a, b, c, d) printf(f, a, b, c, d); |
| #define | trace5(f, a, b, c, d, e) printf(f, a, b, c, d, e); |
| #define | trace6(f, a, b, c, d, e, g) printf(f, a, b, c, d, e, g); |
| #define | trace7(f, a, b, c, d, e, g, h) printf(f, a, b, c, d, e, g, h); |
| #define | trace8(f, a, b, c, d, e, g, h, i) printf(f, a, b, c, d, e, g, h, i); |
| #define | trace0c(f) printf(f), |
| #define | trace1c(f, a) printf(f, a), |
| #define | trace2c(f, a, b) printf(f, a, b), |
| #define | trace3c(f, a, b, c) printf(f, a, b, c), |
| #define | elsetrace else { |
| #define | elsetraceend } |
| #define | traceThread(s) |
| Count instruction (optionally), print trace string prefix (optionally). | |
| #define | traceThreadc(s) |
| #define | trace0t(s, f) traceThread(s) trace0(f) |
| Print trace prefix + suffix. | |
| #define | trace1t(s, f, a) traceThread(s) trace1(f, a) |
| #define | trace2t(s, f, a, b) traceThread(s) trace2(f, a, b) |
| #define | trace3t(s, f, a, b, c) traceThread(s) trace3(f, a, b, c) |
| #define | trace4t(s, f, a, b, c, d) traceThread(s) trace4(f, a, b, c, d) |
| #define | trace5t(s, f, a, b, c, d, e) traceThread(s) trace5(f, a, b, c, d, e) |
| #define | trace6t(s, f, a, b, c, d, e, f1) traceThread(s) trace6(f, a, b, c, d, e, f1) |
| #define | trace7t(s, f, a, b, c, d, e, f1, g) traceThread(s) trace7(f, a, b, c, d, e, f1, g) |
| #define | trace8t(s, f, a, b, c, d, e, f1, g, h) traceThread(s) trace7(f, a, b, c, d, e, f1, g, h) |
| #define | trace0tc(s, f) traceThreadc(s) trace0c(f) |
| #define | trace1tc(s, f, a) traceThreadc(s) trace1c(f, a) |
| #define | trace2tc(s, f, a, b) traceThreadc(s) trace2c(f, a, b) |
| #define | trace3tc(s, f, a, b, c) traceThreadc(s) trace3c(f, a, b, c) |
Typedefs | |
| typedef void * | labeltype |
| Computed goto - a la gcc. | |
| typedef unsigned int | bitvector |
| 32 bits on IA32 | |
| typedef bitvector | signalvector |
| 32 signals on IA32 | |
| typedef int | threadtype |
| Thread id/priority. | |
| typedef bitvector | threadvector |
| 32 threads on IA32 | |
Functions | |
| void | getInputs () |
| Initialize signals to inputs for one tick. | |
| int | checkOutputs (signalvector *tickOutputs) |
| Set reference outputs and check valued signals, if there are any. | |
| void | printVal (int id) |
| Print value of a signal, if it has one. | |
| int | tick (int isInit) |
| Compute one tick. | |
| void | selectCid () |
| Functions defined in sc.c. | |
Variables | |
| signalvector | signals |
| Bit mask for signals. | |
| threadvector | enabled |
| Bit mask for enabled threads. | |
| threadvector | active |
| Bit mask for active threads. | |
| int | runCnt |
| Counts program runs. | |
| int | tickCnt |
| Counts program ticks. | |
| int | tickInstrCnt |
| Instructions in one tick. | |
| threadtype | _cid |
| Id of current thread. | |
| labeltype | _pc [_idMax] |
| Pseudo program counters. | |
| threadvector | _descs [_idMax] |
| Descendants of thread. | |
| threadtype | _parent [_idMax] |
| Parent of thread. | |
| labeltype | _returnAddress |
| For function calls (eg Exit Actions). | |
| char * | statePrev [_idMax] |
| State where thread resumed previous tick. | |
| char * | state [_idMax] |
| State where thread resumed current tick. | |
| int | runMax |
| # of runs to execute | |
| int | tickMax |
| # of ticks to execute | |
| const char * | s2signame [] |
| Names of signals. | |
See README.txt for general information. See LICENSE.txt for licensing information. For further information, see http://www.informatik.uni-kiel.de/rtsys/sc/ .
| #define _BEGIN do { |
Begin/end a macro.
To make macros then/else safe (ie, to allow using it in a then-branch, followed by a semicolon and an else, without resulting in an isolated else), enclose it in a "do ... while (0)".
However, when using switch logic, this additional while loop nullifies the "break" used in _goto, hence we unfortunately have to turn it off then; a Java-style labeled break statement would help here. This may require adding some braces in the source code, eg "if (...) then { PAUSE; } else ..." instead of just "if (...) then PAUSE; else ...".
| #define _CONCAT_helper | ( | a, | |||
| b | ) | a ## b |
Construct a label, of the form "_L'line in source file'".
Origindally contributed by Nicolas Berthier (nicolas.berthier@imag.fr)
To avoid label clashes, one must
Note that goto labels have function scope, hence it is ok to have identical labels in different files, as long as they belong to different functions.
Note also that the ## preprocessing macro, which concatenates strings, prevents macro expansion of it arguments. Thus the construction using _CONCAT and _CONCAT_helper.
| #define _declState |
Dispatcher.
When using switch-case logic, embed the tick function into a switch statement, in turn embedded in an infinite while loop.
| #define ABORT |
| #define ABORT_ |
| #define AWAIT | ( | s | ) |
Value:
_BEGIN \ trace0t("AWAIT:", "initial pause\n") \ _goto(__LABELL__); \ _SC_LABEL(__LABEL__): if (!(signals & u2b(s))) { \ trace2t("AWAIT:", "determines %s/%d as absent, waits\n", \ s2signame[s], s) \ _SC_LABEL(__LABELL__): PAUSEG_(__LABEL__); \ } \ trace2t("AWAIT:", "determines %s/%d as present, proceeds\n", s2signame[s], s) \ _END
Pause; Then, IF 's' is present, THEN proceed to next instruction, ELSE pause.
Shorthand for 'PAUSE; AWAITI(s)', or, alternatively: 'elselabel: PAUSE; PRESENT(s, elselabel)'.
| #define AWAITI | ( | s | ) |
Value:
_BEGIN \ _SC_LABEL(__LABEL__): if (!(signals & u2b(s))) { \ trace2t("AWAITI:", "determines %s/%d as absent, waits\n", \ s2signame[s], s) \ PAUSEG_(__LABEL__); \ } \ trace2t("AWAITI:", "determines %s/%d as present, proceeds\n", s2signame[s], s) \ _END
IF 's' is present, THEN proceed to next instruction, ELSE pause.
Shorthand for 'GOTO(label); elselabel: PAUSE; label: PRESENT(s, elselabel)'.
| #define CALL | ( | label | ) |
Value:
_BEGIN \ trace1t("CALL:", "calls %s\n", #label) \ _returnAddress = _ref(__LABEL__); \ _goto(label); \ _SC_LABEL(__LABEL__): (void) 0; \ _END
Use this if an Exit Action _must_ be performed.
| #define dispatch_ _goto(_L_dispatch) |
If inlineDispatch is defined, call dispatcher at each operator that needs it. Otherwise, create shared code block for TERM/PAUSE/dispatch.
This can be included by TICKEND
| #define EMIT | ( | s | ) |
| #define EMITINT | ( | s, | |||
| val | ) |
| #define EMITINTMUL | ( | s, | |||
| val | ) |
| #define FORK | ( | label, | |||
| p | ) |
| #define FORK_ | ( | label, | |||
| p | ) |
| #define FORKE | ( | label | ) |
| #define FORKE_ | ( | label | ) |
| #define GOTO | ( | label | ) |
Value:
_BEGIN \ trace1t("GOTO:", "transfer to %s\n", #label) \ instrCntIncr \ _goto(label); \ _END
| #define HALT |
Value:
_BEGIN \ _SC_LABEL(__LABEL__): trace1t("HALT:", "pauses, active = 0%o\n", active) \ PAUSEG_(__LABEL__); \ _END
| #define initPC | ( | p, | |||
| label | ) |
| #define instrCntIncr tickInstrCnt++; |
Instruction counting/Tracing.
Increment/decrement SC instruction counter.
Decrement is needed in some places to avoid duplicate counting.
| #define ISAT | ( | id, | |||
| statelabel, | |||||
| label | ) |
Value:
{ \
if (isEnabled(id) && (_pc[id] == _ref(statelabel))) { \
trace1t("ISAT:", "_is_ at %s\n", #statelabel) \
} else { \
trace2t("ISAT:", "is _not_ at %s, transfer to %s\n", \
#statelabel, #label) \
_goto(label); \
}}
IF thread 'id' is active and at state 'statelabel', THEN proceed to next instruction, ELSE jump to 'label'
| #define ISATCALL | ( | id, | |||
| statelabel, | |||||
| label | ) |
Value:
_BEGIN \ if (isEnabled(id) && (_pc[id] == _ref(statelabel))) { \ trace1t("ISATCALL:", "calls %s\n", #label) \ _returnAddress = _ref(__LABEL__); \ _goto(label); \ } \ trace1t("ISATCALL:", "does _not_ call %s\n", #label) \ _SC_LABEL(__LABEL__): (void) 0; \ _END
IF thread 'id' is active and at state 'statelabel', THEN call function at 'label'; Return to 'retlabel' Use this if an Exit Action _may_ have to be performed Shorthand for ISAT(id, statelabel, retlabel); CALL(label, retlabel);
| #define JOIN |
Value:
_BEGIN \ _SC_LABEL(__LABEL__): JOINELSEG_(__LABELL__, __LABEL__); \ _SC_LABEL(__LABELL__): (void) 0; \ _END
IF all descendants have terminated, THEN proceed, ELSE pause, resume at JOIN.
| #define JOINELSE | ( | elselabel | ) |
Value:
_BEGIN \ JOINELSEG_(__LABEL__, elselabel); \ _SC_LABEL(__LABEL__): (void) 0; \ _END
IF all descendants have terminated, THEN proceed after JOINELSE, ELSE pause, resume at 'elselabel'.
Semantically, this is the primitive Join-operator, from which the others can be derived; hence JOINELSE appears first, and the other operators are considered shorthands.
In terms of implementation, the operators are built from JOINELSEG, which semantically corresponds to JOINELSE + GOTO.
| #define JOINELSEG | ( | thenlabel, | |||
| elselabel | ) |
Value:
_BEGIN \ JOINELSEG_(thenlabel, elselabel); \ _END
IF all descendants have terminated, THEN jump to 'thenlabel', ELSE pause, resume at 'elselabel'
| #define JOINELSEG_ | ( | thenlabel, | |||
| elselabel | ) |
| #define JPPAUSE | ( | p, | |||
| elselabel | ) |
Value:
_BEGIN \ trace2t("JPPAUSE:", "%s, prio = %d\n", \ isEnabledNoneOf(_descs[_cid]) ? "joins" : "does not join", p) \ JPPAUSEG_(p, __LABEL__, elselabel); \ _SC_LABEL(__LABEL__): (void) 0; \ _END
IF all descendants have terminated, THEN proceed, ELSE set priority, pause, and continue at 'elselabel'.
This shorthand avoids the context switch immediately before the PAUSE.
| #define JPPAUSEG | ( | p, | |||
| thenlabel, | |||||
| elselabel | ) |
Value:
_BEGIN \ trace2t("JPPAUSEG:", "%s, prio = %d\n", \ isEnabledNoneOf(_descs[_cid]) ? "joins" : "does not join", p) \ JPPAUSEG_(p, thenlabel, elselabel); \ _END
IF all descendants have terminated, THEN jump to 'thenlabel', ELSE set priority, pause, and continue at 'elselabel'.
This shorthand avoids the context switch immediately before the PAUSE.
| #define JPPAUSEG_ | ( | p, | |||
| thenlabel, | |||||
| elselabel | ) |
| #define mergedDispatch |
| #define mytrace |
Check whether externflags has been defined (eg from gcc command line). If so, suppress tracing and instruction counting. This then results in compact macro-expanded source code and executable.
| #define PAUSE |
| #define PAUSEG | ( | label | ) |
| #define PAUSEG_ | ( | label | ) |
| #define PPAUSE | ( | p | ) |
| #define PPAUSEG | ( | p, | |||
| label | ) |
Value:
_BEGIN \ trace2t("PPAUSEG:", "sets prio to %d, pauses, resumes at %s\n", p, #label) \ PPAUSEG_(p, label); \ _END
Set a priority, then pause (this sets "prionext"), resume at 'label'.
This shorthand avoids the context switch immediately before the PAUSE.
| #define PPAUSEG_ | ( | p, | |||
| label | ) |
| #define PRESENT | ( | s | ) |
| #define PRESENTELSE | ( | s, | |||
| label | ) |
Value:
_BEGIN \ if (!(signals & u2b(s))) { \ trace3t("PRESENTELSE:", "determines %s/%d as absent, transfers to %s\n", \ s2signame[s], s, #label) \ _goto(label); \ } \ trace2t("PRESENTELSE:", "determines %s/%d as present\n", s2signame[s], s) \ _END
IF 's' is present, THEN proceed to next instruction, ELSE jump to 'label'
| #define PRESENTEMIT | ( | s, | |||
| t | ) |
Value:
_BEGIN \ if (signals & u2b(s)) { \ trace4t("PRESENTEMIT:", "determines %s/%d as present, emits %s/%d\n", \ s2signame[s], s, s2signame[t], t) \ signals |= u2b(t); \ } \ elsetrace \ trace2t("PRESENTEMIT:", "determines %s/%d as absent\n", s2signame[s], s) \ elsetraceend \ _END
Shorthand for 'PRESENTELSE(s, label); EMIT(t); label:'
| #define PRESENTPRE | ( | s | ) |
| #define PRESENTPREELSE | ( | s, | |||
| label | ) |
Value:
_BEGIN \ if (!(sigsPre & u2b(s))) { \ trace3t("PRESENTPRE:", "determines previous %s/%d as absent, transfers to %s\n", \ s2signame[s], s, #label) \ _goto(label); \ } \ trace2t("PRESENTPRE:", "determines previous %s/%d as present\n", \ s2signame[s], s) \ _END
IF 's' was present in previous tick, THEN proceed to next instruction, ELSE jump to 'label'
| #define PRIO | ( | p | ) |
| #define PRIO_ | ( | p | ) |
| #define PRIOG | ( | p, | |||
| label | ) |
| #define PRIOG_ | ( | p, | |||
| label | ) |
| #define RET |
Value:
_BEGIN \ trace0t("RET:", "returns\n") \ _goto(_deref(_returnAddress)); \ _END
| #define setPC | ( | id, | |||
| label | ) |
| #define SIGNAL | ( | s | ) |
| #define SUSPEND | ( | cond | ) |
Value:
_BEGIN \ _SC_LABEL(__LABEL__): if (cond) { \ trace1t("SUSPEND:", "suspends itself and descendants 0%o\n", _descs[_cid]) \ active &= ~_descs[_cid]; \ freezePre \ instrCntDecr \ PAUSEG_(__LABEL__); \ } \ _END
Note: suspension is implemented by deactivating the current thread as well as its descendants. This exploits that the PCs of the descendants must reside at tick boundaries.
| #define SUSPENDG | ( | label | ) |
Value:
_BEGIN \ trace1t("SUSPENDGOT:", "suspends itself and descendants 0%o\n", _descs[_cid]) \ active &= ~_descs[_cid]; \ freezePre \ instrCntDecr \ PAUSEG_(label); \ _END
Note: suspension is implemented by deactivating the current thread as well as its descendants. This exploits that the PCs of the descendants must reside at tick boundaries.
| #define SUSTAIN | ( | s | ) |
| #define TERM |
| #define TICKEND |
Value:
_SC_LABEL(_L_TICKEND): setPre \ return isEnabledNotOnly(_TickEnd); \ mergedDispatch \ _END_SWITCH
Return 0 iff computation has terminated
| #define TICKSTART | ( | isIni, | |||
| p | ) |
Value:
static threadtype _pid, _ppid; \ static threadvector _forkdescs = 0; \ _declindex \ _declState \ freezePreClear \ if (isIni) { \ tickCnt = 0; \ initPC(_TickEnd, _L_TICKEND); \ enableInit(_TickEnd); \ _cid = p; \ _parent[_cid] = _TickEnd; \ clearPC(_cid); \ enable(_cid); \ _setStateInit \ _setPreInit \ _setValInit \ } else { \ active = enabled; \ dispatch_init_; \ } \ _BEGIN_SWITCH
IF this is the initial tick ('isIni' is set), THEN initialize things and continue with following instruction, ELSE call dispatcher to resume where we left off.
This also initializes the _TickEnd thread. Note that _parent[_TickEnd] is undefined. Note also that _descs[_TickEnd] does not matter, as that thread should never perform an ABORT (TRANS) or JOIN.
| #define trace0t | ( | s, | |||
| f | ) | traceThread(s) trace0(f) |
Print trace prefix + suffix.
s is string denoting instruction (eg, "PAUSE:") f is format string for trace suffix a, b, ... are arguments for format string
| #define traceThread | ( | s | ) |
Value:
instrCntIncr \ trace3("%-9s %d/%s ", s, _cid, state[_cid])
Trace string prefix takes a string s (typically denoting the instruction) and identifies the executing thread, both by name and thread id.
| #define TRANS | ( | label | ) |
| #define u2b | ( | u | ) | (1 << u) |
Encoding of signal/thread 'u' (some non-negative int) in bitvector.
This implementation is fast and simple, BUT limits the max thread ID and max signal ID to the word width of the machine (eg 32).
| #define VAL | ( | s | ) |
Value:
( \
trace3tc("VAL:", "determines value of %s/%d as %d\n", \
s2signame[s], s, valSigInt[s]) \
valSigInt[s])
| #define VALPRE | ( | s | ) |
Value:
( \
trace3tc("VALPRE:", "determines value of %s/%d as %d\n", \
s2signame[s], s, valSigIntPre[s]) \
valSigIntPre[s])
| #define VALPREREG | ( | s, | |||
| reg | ) |
Value:
_BEGIN \ trace3t("VALPREREG:", "determines value of %s/%d as %d\n", \ s2signame[s], s, valSigIntPre[s]) \ reg = valSigIntPre[s]; \ _END
| #define VALREG | ( | s, | |||
| reg | ) |
Value:
_BEGIN \ trace3t("VALREG:", "determines value of %s/%d as %d\n", \ s2signame[s], s, valSigInt[s]) \ reg = valSigInt[s]; \ _END
| void selectCid | ( | ) |
Functions defined in sc.c.
Functions defined in sc.c.
Uses obvious algorithm, run time linear in position of highest bit. Note that there are also alternatives that run logarithmic to bit vector size. See eg http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog . Which is actually faster depends on application.
| int tick | ( | int | isInit | ) |
Compute one tick.
Returns 1 if some thread is still active in current tick.
1.5.7.1