22 #define SSM_STATIC_INLINE
24 #define SSM_STATIC static
25 #define SSM_STATIC_INLINE static inline
28 #ifndef SSM_EVENT_QUEUE_SIZE
30 #define SSM_EVENT_QUEUE_SIZE 2048
33 #ifndef SSM_ACT_QUEUE_SIZE
35 #define SSM_ACT_QUEUE_SIZE 1024
39 #define SSM_QUEUE_HEAD 1
90 for (; hole >
SSM_QUEUE_HEAD && priority < act_queue[hole >> 1]->priority;
122 if (priority <
act_queue[child]->priority)
147 for (; hole >
SSM_QUEUE_HEAD && later < event_queue[hole >> 1]->later_time;
213 void event_queue_consistency_check(
void) {
238 void act_queue_consistency_check(
void) {
281 .priority = priority,
295 parent->
step(parent);
314 if (trig->act->priority > prio)
383 event_queue[hole >> 1]->later_time < moved_var->later_time)
461 to_run->
step(to_run);
uint8_t ssm_depth_t
Index of least significant bit in a group of priorities.
void ssm_leave(ssm_act_t *act, size_t size)
Destroy the activation record of a routine before leaving.
ssm_act_t * ssm_enter_int(size_t size, ssm_stepf_t step, ssm_act_t *parent, ssm_priority_t priority, ssm_depth_t depth)
Allocate and initialize a routine activation record.
struct ssm_act ssm_act_t
Activation record for an SSM routine.
void ssm_tick(void)
Run the system for the next scheduled instant.
bool ssm_active(void)
Whether there are still active processes in the activation queue.
void ssm_stepf_t(struct ssm_act *)
The function that does an instant's work for a routine.
uint32_t ssm_priority_t
Thread priority.
void ssm_activate(ssm_act_t *act)
Schedule a routine to run in the current instant.
#define SSM_ASSERT(cond)
Throw an internal error.
#define SSM_THROW(reason)
Terminate due to a non-recoverable error, with a specified reason.
@ SSM_EXHAUSTED_ACT_QUEUE
Tried to insert into full activation record queue.
@ SSM_EXHAUSTED_EVENT_QUEUE
Tried to insert into full event queue.
@ SSM_NOT_READY
Not yet ready to perform the requested action.
@ SSM_INVALID_TIME
Specified invalid time, e.g., scheduled assignment at an earlier time.
void ssm_mem_free(void *m, size_t size)
Deallocate memory allocated by ssm_mem_alloc().
#define ssm_drop(v)
Drop a reference to a possible heap item, and free it if necessary.
void * ssm_mem_alloc(size_t size)
Allocate a contiguous range of memory.
void ssm_sv_desensitize(ssm_trigger_t *trig)
Desensitize a variable from a trigger.
void ssm_unschedule(ssm_sv_t *var)
Unschedule any pending events on a variable.
void ssm_update(ssm_sv_t *sv)
Perform a (delayed) update on a variable.
void ssm_sv_later_unsafe(ssm_sv_t *var, ssm_time_t when, ssm_value_t val)
ssm_later() without automatic reference counting.
void ssm_sv_sensitize(ssm_sv_t *var, ssm_trigger_t *trig)
Sensitize a variable to a trigger.
void ssm_sv_assign_unsafe(ssm_sv_t *var, ssm_priority_t prio, ssm_value_t val)
ssm_assign() without automatic reference counting.
#define SSM_NEVER
Time indicating something will never happen.
void ssm_reset(void)
Reset the scheduler.
void ssm_set_now(ssm_time_t next)
Advance the current model time.
ssm_time_t ssm_now(void)
The current model time.
ssm_time_t ssm_next_event_time(void)
The time of the next event in the event queue.
uint64_t ssm_time_t
Absolute time; never to overflow.
The internal interface of the SSM runtime.
SSM_STATIC_INLINE void act_queue_percolate_up(q_idx_t hole, ssm_act_t *act)
Percolate act queue hole up, to find where to put a new entry.
#define SSM_EVENT_QUEUE_SIZE
Size of the event queue; override as necessary.
#define SSM_ACT_QUEUE_SIZE
Size of the activation record queue; override as necessary.
SSM_STATIC ssm_time_t now
The current model time.
SSM_STATIC_INLINE q_idx_t find_queued_event(ssm_sv_t *var)
Determine the index of an already scheduled event.
SSM_STATIC q_idx_t act_queue_len
the number of elements in act_queue.
#define SSM_STATIC
A symbol is static unless SSM_DEBUG is defined.
SSM_STATIC ssm_act_t * act_queue[SSM_ACT_QUEUE_SIZE+SSM_QUEUE_HEAD]
Activation record queue, for scheduling at each instant.
static size_t num_processes
The program terminates when there are no more processes.
SSM_STATIC_INLINE void act_queue_percolate_down(q_idx_t hole, ssm_act_t *act)
Percolate act queue hole down, to find where to put a new entry.
SSM_STATIC_INLINE void event_queue_percolate_up(q_idx_t hole, ssm_sv_t *var)
Percolate event queue hole up, to find where to put a new entry.
SSM_STATIC q_idx_t event_queue_len
The number of elements in event_queue.
#define SSM_STATIC_INLINE
A symbol is static inline unless SSM_DEBUG is defined.
SSM_STATIC_INLINE void event_queue_percolate_down(q_idx_t hole, ssm_sv_t *event)
Percolate event queue hole down, to find where to put a new entry.
SSM_STATIC ssm_sv_t * event_queue[SSM_EVENT_QUEUE_SIZE+SSM_QUEUE_HEAD]
Event queue, used to track and schedule events between instants.
#define SSM_QUEUE_HEAD
Extra entries at the start of a binary heap.
uint16_t q_idx_t
Queue index type; index of 1 is the first element.
Activation record for an SSM routine.
ssm_priority_t priority
Execution priority; lower goes first.
uint16_t children
Number of running child threads.
struct ssm_act * caller
Activation record of caller.
ssm_stepf_t * step
C function for running this continuation.
uint16_t pc
Stored "program counter" for the function.
bool scheduled
True when in the schedule queue.
A scheduled variable that supports scheduled updates with triggers.
ssm_time_t later_time
When the variable should be next updated.
ssm_time_t last_updated
When the variable was last updated.
ssm_value_t value
Current value.
ssm_trigger_t * triggers
List of sensitive continuations.
ssm_value_t later_value
Buffered value for delayed assignment.
Indicates a routine should run when a scheduled variable is written.
struct ssm_trigger ** prev_ptr
Pointer to self in previous element.
struct ssm_trigger * next
Next sensitive trigger, if any.
SSM values are either "packed" values or heap-allocated.