reactor-c
C Runtime for Lingua Franca
|
Runtime infrastructure common to the threaded and single-threaded versions of the C runtime. More...
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "low_level_platform.h"
#include "api/schedule.h"
#include "port.h"
#include "pqueue.h"
#include "reactor.h"
#include "tracepoint.h"
#include "util.h"
#include "vector.h"
#include "lf_core_version.h"
#include "hashset/hashset.h"
#include "hashset/hashset_itr.h"
#include "environment.h"
#include "reactor_common.h"
#include "watchdog.h"
Functions | |
void * | lf_allocate (size_t count, size_t size, struct allocation_record_t **head) |
Allocate memory and record on the specified allocation record (a self struct). | |
self_base_t * | lf_new_reactor (size_t size) |
Allocate memory for a new runtime instance of a reactor. | |
void | lf_free (struct allocation_record_t **head) |
Free memory on the specified allocation record (a self struct). | |
void | lf_free_reactor (self_base_t *self) |
Free the specified reactor. | |
void | lf_free_all_reactors (void) |
Free all the reactors that are allocated with lf_new_reactor(size_t) . | |
void | lf_set_stop_tag (environment_t *env, tag_t tag) |
Set the stop tag if it is less than the stop tag of the specified environment. | |
void | _lf_start_time_step (environment_t *env) |
Perform whatever is needed to start a time step. | |
bool | lf_is_tag_after_stop_tag (environment_t *env, tag_t tag) |
Return true if the provided tag is after stop tag. | |
void | _lf_pop_events (environment_t *env) |
Pop all events from event_q with tag equal to current tag. | |
event_t * | lf_get_new_event (environment_t *env) |
void | _lf_initialize_timer (environment_t *env, trigger_t *timer) |
Initialize the given timer. If this timer has a zero offset, enqueue the reactions it triggers. If this timer is to trigger reactions at a future tag as well, schedule it accordingly. | |
void | _lf_initialize_timers (environment_t *env) |
Initialize all the timers in the environment. | |
void | _lf_trigger_startup_reactions (environment_t *env) |
Trigger all the startup reactions in the specified environment. | |
void | _lf_trigger_shutdown_reactions (environment_t *env) |
Trigger all the shutdown reactions in the specified environment. | |
void | lf_recycle_event (environment_t *env, event_t *e) |
Recycle the given event. | |
event_t * | _lf_create_dummy_events (environment_t *env, tag_t tag) |
Create a dummy event with the specified tag. | |
void | lf_replace_token (event_t *event, lf_token_t *token) |
trigger_handle_t | _lf_schedule_at_tag (environment_t *env, trigger_t *trigger, tag_t tag, lf_token_t *token) |
Schedule an event at a specific tag (time, microstep). | |
trigger_handle_t | _lf_insert_reactions_for_trigger (environment_t *env, trigger_t *trigger, lf_token_t *token) |
Insert reactions triggered by trigger to the reaction queue. | |
void | _lf_advance_tag (environment_t *env, tag_t next_tag) |
void | _lf_invoke_reaction (environment_t *env, reaction_t *reaction, int worker) |
void | schedule_output_reactions (environment_t *env, reaction_t *reaction, int worker) |
void | usage (int argc, const char *argv[]) |
int | process_args (int argc, const char *argv[]) |
void | initialize_global (void) |
Check that the provided version information is consistent with the core runtime. | |
void | termination (void) |
Perform final wrap-up on exit. | |
index_t | lf_combine_deadline_and_level (interval_t deadline, int level) |
Combine a deadline and a level into a single index for sorting in the reaction queue. | |
Variables | |
instant_t | start_time |
int | _lf_count_payload_allocations |
bool | fast = false |
unsigned int | _lf_number_of_workers = 0u |
instant_t | duration = -1LL |
bool | keepalive_specified = false |
struct allocation_record_t * | _lf_reactors_to_free = NULL |
int | default_argc = 0 |
const char ** | default_argv = NULL |
bool | _lf_termination_executed = false |
bool | _lf_normal_termination = false |
Runtime infrastructure common to the threaded and single-threaded versions of the C runtime.
void _lf_advance_tag | ( | environment_t * | env, |
tag_t | next_tag ) |
Advance from the current tag to the next. If the given next_time is equal to the current time, then increase the microstep. Otherwise, update the current time and set the microstep to zero.
env | The environment in which we are executing |
next_tag | The tag step to advance to. |
event_t * _lf_create_dummy_events | ( | environment_t * | env, |
tag_t | tag ) |
Create a dummy event with the specified tag.
A dummy event is an event with no triggers that can be put on the event queue to trigger a tag advance to the specified tag.
env | Environment in which we are executing. |
tag | The tag of that event. |
void _lf_initialize_timer | ( | environment_t * | env, |
trigger_t * | timer ) |
Initialize the given timer. If this timer has a zero offset, enqueue the reactions it triggers. If this timer is to trigger reactions at a future tag as well, schedule it accordingly.
env | Environment in which we are executing. |
timer | The timer to initialize. |
void _lf_initialize_timers | ( | environment_t * | env | ) |
Initialize all the timers in the environment.
env | Environment in which we are executing. |
trigger_handle_t _lf_insert_reactions_for_trigger | ( | environment_t * | env, |
trigger_t * | trigger, | ||
lf_token_t * | token ) |
Insert reactions triggered by trigger to the reaction queue.
env | Environment in which we are executing. |
trigger | The trigger. |
token | The token wrapping the payload or NULL for no payload. |
void _lf_invoke_reaction | ( | environment_t * | env, |
reaction_t * | reaction, | ||
int | worker ) |
Invoke the given reaction
env | Environment in which we are executing. |
reaction | The reaction that has just executed. |
worker | The thread number of the worker thread or 0 for single-threaded execution (for tracing). |
void _lf_pop_events | ( | environment_t * | env | ) |
Pop all events from event_q with tag equal to current tag.
This will extract all the reactions triggered by these events and stick them onto the reaction queue.
env | The environment in which we are executing |
trigger_handle_t _lf_schedule_at_tag | ( | environment_t * | env, |
trigger_t * | trigger, | ||
tag_t | tag, | ||
lf_token_t * | token ) |
Schedule an event at a specific tag (time, microstep).
If there is an event found at the requested tag, the payload is replaced and 0 is returned.
Note that this function is an internal API that must be called with a tag that is in the future relative to the current tag (or the environment has not started executing). Also, it must be called with tags that are in order for a given trigger. This means that the following order is illegal:
where bigger_tag > smaller_tag
. This function is primarily used for network communication (which is assumed to be in order).
This function assumes the caller holds the mutex lock.
env | Environment in which we are executing. |
trigger | The trigger to be invoked at a later logical time. |
tag | Logical tag of the event |
token | The token wrapping the payload or NULL for no payload. |
void _lf_start_time_step | ( | environment_t * | env | ) |
Perform whatever is needed to start a time step.
For example, this function resets outputs to be absent at the start of a new time step.
env | The environment in which we are executing |
void _lf_trigger_shutdown_reactions | ( | environment_t * | env | ) |
Trigger all the shutdown reactions in the specified environment.
env | Environment in which we are executing. |
void _lf_trigger_startup_reactions | ( | environment_t * | env | ) |
Trigger all the startup reactions in the specified environment.
env | Environment in which we are executing. |
void initialize_global | ( | void | ) |
Check that the provided version information is consistent with the core runtime.
Initialize global variables and start tracing before calling the _lf_initialize_trigger_objects
function.
void * lf_allocate | ( | size_t | count, |
size_t | size, | ||
struct allocation_record_t ** | head ) |
Allocate memory and record on the specified allocation record (a self struct).
This will allocate memory using calloc (so the allocated memory is zeroed out) and record the allocated memory on the specified self struct so that it will be freed when calling free_reactor(self_base_t)
.
count | The number of items of size 'size' to accomodate. |
size | The size of each item. |
head | Pointer to the head of a list on which to record the allocation, or NULL to not record it (an allocation_record_t** ), |
index_t lf_combine_deadline_and_level | ( | interval_t | deadline, |
int | level ) |
Combine a deadline and a level into a single index for sorting in the reaction queue.
This shifts the deadline right by 16 bits and inserts the level in the low-order 16 bits. If the deadline is larger than ULLONG_MAX >> 16
, then it is treated as the largest possible deadline. @oaran deadline THe deadline.
level | The level in the reaction graph. |
void lf_free | ( | struct allocation_record_t ** | head | ) |
Free memory on the specified allocation record (a self struct).
This will mark the allocation record empty by setting *head
to NULL. If the argument is NULL, do nothing.
head | Pointer to the head of a list on which allocations are recorded. |
void lf_free_all_reactors | ( | void | ) |
Free all the reactors that are allocated with lf_new_reactor(size_t)
.
void lf_free_reactor | ( | self_base_t * | self | ) |
Free the specified reactor.
This will free the memory recorded on the allocations list of the specified reactor and then free the specified self struct.
self | The self struct of the reactor. |
event_t * lf_get_new_event | ( | environment_t * | env | ) |
Get a new event. If there is a recycled event available, use that. If not, allocate a new one. In either case, all fields will be zero'ed out.
env | Environment in which we are executing. |
bool lf_is_tag_after_stop_tag | ( | environment_t * | env, |
tag_t | tag ) |
Return true if the provided tag is after stop tag.
env | Environment in which we are executing. |
tag | The tag to check against stop tag |
self_base_t * lf_new_reactor | ( | size_t | size | ) |
Allocate memory for a new runtime instance of a reactor.
This records the reactor on the list of reactors to be freed at termination of the program. If you plan to free the reactor before termination of the program, use lf_allocate(size_t, size_t, allocation_record_t**)
with a null last argument instead.
size | The size of the self struct, obtained with sizeof(). |
void lf_recycle_event | ( | environment_t * | env, |
event_t * | e ) |
Recycle the given event.
This will zero out the event and push it onto the recycle queue.
env | Environment in which we are executing. |
e | The event to recycle. |
void lf_replace_token | ( | event_t * | event, |
lf_token_t * | token ) |
Replace the token on the specified event with the specified token and free the old token.
event | The event. |
token | The token. |
void lf_set_stop_tag | ( | environment_t * | env, |
tag_t | tag ) |
Set the stop tag if it is less than the stop tag of the specified environment.
int process_args | ( | int | argc, |
const char * | argv[] ) |
Process the command-line arguments. If the command line arguments are not understood, then print a usage message and return 0. Otherwise, return 1.
void schedule_output_reactions | ( | environment_t * | env, |
reaction_t * | reaction, | ||
int | worker ) |
For the specified reaction, if it has produced outputs, insert the resulting triggered reactions into the reaction queue. This procedure assumes the mutex lock is NOT held and grabs the lock only when it actually inserts something onto the reaction queue.
env | Environment in which we are executing. |
reaction | The reaction that has just executed. |
worker | The thread number of the worker thread or 0 for single-threaded execution (for tracing). |
void termination | ( | void | ) |
Perform final wrap-up on exit.
Report elapsed logical and physical times and report if any memory allocated for tokens has not been freed.
void usage | ( | int | argc, |
const char * | argv[] ) |
Print a usage message. TODO: This is not necessary for NO_CLI
|
extern |
Counter used to issue a warning if memory is allocated for message payloads and never freed.
bool _lf_normal_termination = false |
Flag used to disable cleanup operations on abnormal termination.
unsigned int _lf_number_of_workers = 0u |
The number of worker threads for threaded execution. By default, execution is not threaded and this variable will have value 0.
If the execution is threaded, a value of 0 indicates that the runtime should decide on the number of workers (which will be decided based on the number of available cores on the host machine).
struct allocation_record_t* _lf_reactors_to_free = NULL |
Head of a list of pointers to dynamically generated reactor self structs to be freed in terminate().
bool _lf_termination_executed = false |
Flag to prevent termination function from executing twice and to signal to background threads to terminate.
int default_argc = 0 |
const char** default_argv = NULL |
instant_t duration = -1LL |
The logical time to elapse during execution, or -1 if no timeout time has been given. When the logical equal to start_time + duration has been reached, execution will terminate.
bool fast = false |
Indicator of whether to wait for physical time to match logical time. By default, execution will wait. The command-line argument -fast will eliminate the wait and allow logical time to exceed physical time.
bool keepalive_specified = false |
Indicator of whether the keepalive command-line option was given.
|
extern |
The start time read from the trace file.