Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements of support for watchdogs #209

Merged
merged 70 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
d28b56d
saving changes made to runtime
Jan 5, 2023
37a9604
removed watchdog handler from reaction struct, not needed
Jan 6, 2023
11dc26d
defined watchdog_t struct
Jan 8, 2023
96da894
added additional changes to struct definitions
Jan 18, 2023
90a0a9b
added questions about watchdog start and stop
Jan 18, 2023
050abfa
saving changes
Jan 25, 2023
0820da9
save before merge
Feb 1, 2023
92160a8
include all
Feb 1, 2023
04173e9
committing types
Feb 10, 2023
7fd67a5
Merge remote-tracking branch 'origin/main' into watchdogs
Feb 10, 2023
6dff526
fix build problems associated w merge
Feb 17, 2023
0f28759
should fix issues with build after submodule update
Feb 17, 2023
59dfc4f
fixed c compile errors
Feb 20, 2023
9a40303
fixed c compile problems
Feb 20, 2023
b4b70c5
saving reactor common c before submodule update
Feb 21, 2023
c974d4d
Merge branch 'watchdogs' of https://github.com/lf-lang/reactor-c into…
Feb 21, 2023
3358cd1
saving actual fixes to c compilation issues
Feb 21, 2023
4677a37
Merge branch 'temp-branch' into watchdogs
Feb 21, 2023
38aec13
fixed
Feb 21, 2023
c643234
tried applying fix for non-threaded runtime
Feb 26, 2023
b97d084
fixed merge conflict from detached head
Feb 26, 2023
c00691a
Merge remote-tracking branch 'origin/main' into watchdogs
Feb 26, 2023
8a8827f
fixed some compile issues w non-threaded
Mar 3, 2023
50ef0d2
saving fix to watchdogs on unthreaded
Mar 9, 2023
742f294
Update lingua-franca-ref.txt
lhstrh Mar 9, 2023
faaf56b
removed fixmes
Mar 9, 2023
4fe27cc
removed fixmes
Mar 9, 2023
f5825b4
fixed ccpp test issue?
Mar 9, 2023
82afe9b
Merge branch 'main' into watchdogs
Benichiwa Mar 12, 2023
ff3c84c
removed unnecessary ifdef endif
Mar 15, 2023
8ca094f
fixed some code review suggestions
Mar 20, 2023
10c275b
Merged main into watchdogs
edwardalee Mar 25, 2023
e516564
Made watchdog function match thread function signature
edwardalee Mar 25, 2023
b62683e
Comment formatting only
edwardalee Mar 25, 2023
24c0dc7
Made watchdog function conform with thread function
edwardalee Mar 25, 2023
e24e3bc
Merge pull request #184 from lf-lang/watchdogs-eal
Benichiwa Mar 31, 2023
ccb0a3c
updating reactor-c
Apr 21, 2023
9b6c7dc
fixed merge conflicts
Apr 21, 2023
7dcdb7d
fixed problem from reactor-commonc merge
Apr 21, 2023
9ba9817
Merge branch 'main' into watchdogs
Benichiwa Apr 21, 2023
abe2485
Merge branch 'main' into watchdogs
edwardalee Apr 27, 2023
5c0ba3b
First pass a refactoring
edwardalee Apr 27, 2023
4aef0ef
Fixed compile errors
edwardalee Apr 27, 2023
5d58c62
Continued refactoring
edwardalee Apr 28, 2023
68e2c14
Continued refactoring and docs
edwardalee Apr 29, 2023
2c7a514
Added LF_SOURCE_DIRECTORY and LF_FILE_SEPARATOR
edwardalee Apr 21, 2023
05b6e96
Cleaned up docs for doxygen
edwardalee Apr 21, 2023
795d38b
Cleaned up docs and const args
edwardalee Apr 21, 2023
24e1dc0
Added cmake file for wave reader
edwardalee Apr 21, 2023
cee63e1
const modifier to suppress warnings
edwardalee Apr 23, 2023
a48b022
Moved \#define from platform.h to tag.h because platform.h is no long…
edwardalee Apr 20, 2023
02cbf70
Moved memory leak check to account for persistent tokens
edwardalee Apr 26, 2023
2f51b30
Add CMake definition to find FEDERATED_AUTHENTICATED
Apr 15, 2023
436decc
Change ci.yml point
Apr 15, 2023
c985c6a
Try openssl/hmac.h first
Apr 16, 2023
775b27a
Revert "Try openssl/hmac.h first"
Apr 16, 2023
eede0fa
Fix ci tests
Apr 21, 2023
aeff26c
Add openssl library links to reactor-c/core
Apr 21, 2023
670f634
Add mac options
Apr 22, 2023
9ae8632
Uncommented code tof fix memory leak
edwardalee Apr 25, 2023
5427b5d
Removed incorrect free
edwardalee Apr 25, 2023
4265119
Resurrected lf_set_array
edwardalee Apr 26, 2023
97466da
Merge branch 'main' into watchdogs-eal2
edwardalee Apr 30, 2023
32559bf
Removed watchdog initialization for unthreaded runtime
edwardalee May 1, 2023
ffe9a6a
Guard code to include only for threaded runtime
edwardalee May 1, 2023
618fa07
Added extern C qualifier
edwardalee May 6, 2023
cc37956
Merge branch 'watchdogs' into watchdogs-eal2
lhstrh May 15, 2023
5ed95a7
Update lingua-franca-ref.txt
edwardalee May 15, 2023
c2c6a54
In response to review, renamed variables
edwardalee May 16, 2023
5454513
Merge branch 'main' into watchdogs-eal2
erlingrj May 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/reactor.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ int lf_reactor_c_main(int argc, const char* argv[]) {
_lf_execution_started = true;
_lf_trigger_startup_reactions();
_lf_initialize_timers();

// If the stop_tag is (0,0), also insert the shutdown
// reactions. This can only happen if the timeout time
// was set to 0.
Expand Down
30 changes: 30 additions & 0 deletions core/reactor_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "hashset/hashset.h"
#include "hashset/hashset_itr.h"

#ifdef LF_THREADED
#include "watchdog.h"

// Code generated global variables.
extern int _lf_watchdog_count;
extern watchdog_t* _lf_watchdogs;
#endif

// Global variable defined in tag.c:
extern tag_t current_tag;
extern instant_t start_time;
Expand Down Expand Up @@ -1292,17 +1300,32 @@ trigger_handle_t _lf_schedule_int(lf_action_base_t* action, interval_t extra_del
}

/**

* Invoke the given reaction
*
* @param reaction The reaction that has just executed.
* @param worker The thread number of the worker thread or 0 for unthreaded execution (for tracing).
*/
void _lf_invoke_reaction(reaction_t* reaction, int worker) {

#ifdef LF_THREADED
if (((self_base_t*) reaction->self)->reactor_mutex != NULL) {
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
lf_mutex_lock((lf_mutex_t*)((self_base_t*)reaction->self)->reactor_mutex);
}
#endif

tracepoint_reaction_starts(reaction, worker);
((self_base_t*) reaction->self)->executing_reaction = reaction;
reaction->function(reaction->self);
((self_base_t*) reaction->self)->executing_reaction = NULL;
tracepoint_reaction_ends(reaction, worker);


#ifdef LF_THREADED
if (((self_base_t*) reaction->self)->reactor_mutex != NULL) {
lf_mutex_unlock((lf_mutex_t*)((self_base_t*)reaction->self)->reactor_mutex);
}
#endif
}

/**
Expand Down Expand Up @@ -1743,6 +1766,13 @@ void termination(void) {
lf_print_warning("Memory allocated for tokens has not been freed!");
lf_print_warning("Number of unfreed tokens: %d.", _lf_count_token_allocations);
}
#ifdef LF_THREADED
for (int i = 0; i < _lf_watchdog_count; i++) {
if (_lf_watchdogs[i].base->reactor_mutex != NULL) {
free(_lf_watchdogs[i].base->reactor_mutex);
}
}
#endif
_lf_free_all_reactors();
free(_lf_is_present_fields);
free(_lf_is_present_fields_abbreviated);
Expand Down
1 change: 1 addition & 0 deletions core/threaded/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(
scheduler_NP.c
scheduler_PEDF_NP.c
scheduler_sync_tag_advance.c
watchdog.c
)
list(APPEND INFO_SOURCES ${THREADED_SOURCES})

Expand Down
2 changes: 2 additions & 0 deletions core/threaded/reactor_threaded.c
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@ int lf_reactor_c_main(int argc, const char* argv[]) {
// it can be probably called in that manner as well).
_lf_initialize_start_tag();

_lf_initialize_watchdog_mutexes();

start_threads();

lf_mutex_unlock(&mutex);
Expand Down
83 changes: 83 additions & 0 deletions core/threaded/watchdog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* @file
* @author Benjamin Asch
* @author Edward A. Lee
* @copyright (c) 2023, The University of California at Berkeley.
* License: <a href="https://github.com/lf-lang/reactor-c/blob/main/LICENSE.md">BSD 2-clause</a>
* @brief Definitions for watchdogs.
*/

#include <assert.h>
#include "watchdog.h"

extern int _lf_watchdog_count;
extern watchdog_t* _lf_watchdogs;

/**
* @brief Initialize watchdog mutexes.
* For any reactor with one or more watchdogs, the self struct should have a non-NULL
* `reactor_mutex` field which points to an instance of `lf_mutex_t`.
* This function initializes those mutexes.
*/
void _lf_initialize_watchdog_mutexes() {
for (int i = 0; i < _lf_watchdog_count; i++) {
self_base_t* current_base = _lf_watchdogs[i].base;
if (current_base->reactor_mutex != NULL) {
lf_mutex_init((lf_mutex_t*)(current_base->reactor_mutex));
}
}
}

/**
edwardalee marked this conversation as resolved.
Show resolved Hide resolved
* @brief Thread function for watchdog.
* This function sleeps until physical time exceeds the expiration time of
* the watchdog and then invokes the watchdog expiration handler function.
* In normal usage, the expiration time is incremented while the thread is
* sleeping, so the watchdog never expires and the handler function is never
* invoked.
* This function acquires the reaction mutex and releases it while sleeping.
*
* @param arg A pointer to the watchdog struct
* @return NULL
*/
void* _lf_run_watchdog(void* arg) {
watchdog_t* watchdog = (watchdog_t*)arg;

self_base_t* base = watchdog->base;
assert(base->reactor_mutex != NULL);
lf_mutex_lock((lf_mutex_t*)(base->reactor_mutex));
instant_t physical_time = lf_time_physical();
while (physical_time < watchdog->expiration) {
interval_t T = watchdog->expiration - physical_time;
lf_mutex_unlock((lf_mutex_t*)base->reactor_mutex);
lf_sleep(T);
lf_mutex_lock((lf_mutex_t*)(base->reactor_mutex));
physical_time = lf_time_physical();
}

if (watchdog->expiration != NEVER) {
watchdog_function_t watchdog_func = watchdog->watchdog_function;
(*watchdog_func)(base);
}
watchdog->thread_active = false;

lf_mutex_unlock((lf_mutex_t*)(base->reactor_mutex));
return NULL;
}

void lf_watchdog_start(watchdog_t* watchdog, interval_t additional_timeout) {
// Assumes reaction mutex is already held.

self_base_t* base = watchdog->base;

watchdog->expiration = lf_time_logical() + watchdog->min_expiration + additional_timeout;

if (!watchdog->thread_active) {
lf_thread_create(&(watchdog->thread_id), _lf_run_watchdog, watchdog);
watchdog->thread_active = true;
}
}

void lf_watchdog_stop(watchdog_t* watchdog) {
watchdog->expiration = NEVER;
}
4 changes: 4 additions & 0 deletions include/core/lf_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ typedef struct allocation_record_t {
typedef struct self_base_t {
struct allocation_record_t *allocations;
struct reaction_t *executing_reaction; // The currently executing reaction of the reactor.
#ifdef LF_THREADED
void* reactor_mutex; // If not null, this is expected to point to an lf_mutex_t.
// It is not declared as such to avoid a dependence on platform.h.
#endif
#ifdef MODAL_REACTORS
reactor_mode_state_t _lf__mode_state; // The current mode (for modal models).
#endif
Expand Down
8 changes: 8 additions & 0 deletions include/core/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PLATFORM_H
#define PLATFORM_H

#ifdef __cplusplus
extern "C" {
#endif

#include "lf_types.h"

#if defined(LF_THREADED) && defined(LF_UNTHREADED)
Expand Down Expand Up @@ -313,4 +317,8 @@ extern int lf_sleep_until_locked(instant_t wakeup_time);
*/
DEPRECATED(extern int lf_nanosleep(interval_t sleep_duration));

#ifdef __cplusplus
}
#endif

#endif // PLATFORM_H
28 changes: 28 additions & 0 deletions include/core/reactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,11 @@ void _lf_initialize_timers(void);
*/
void _lf_trigger_startup_reactions(void);

/**
* Function to initialize mutexes for watchdogs
*/
void _lf_initialize_watchdog_mutexes(void);


/**
* Function (to be code generated) to terminate execution.
Expand Down Expand Up @@ -530,5 +535,28 @@ trigger_handle_t _lf_schedule_copy(lf_action_base_t* action, interval_t offset,
*/
void _lf_fd_send_stop_request_to_rti(void);

/**
* These functions must be implemented by both threaded and unthreaded
* runtime. Should be routed to appropriate API calls in platform.h
*/

/**
* @brief Notify other threads of new events on the event queue.
*
*/
void _lf_notify_of_event();

/**
* @brief Enter critical section. Must be paired with a
* `_lf_critical_section_exit()`
*
*/
void _lf_critical_section_enter();

/**
* @brief Leave critical section
*/
void _lf_critical_section_exit();

#endif /* REACTOR_H */
/** @} */
67 changes: 67 additions & 0 deletions include/core/threaded/watchdog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @file
* @author Benjamin Asch
* @author Edward A. Lee
* @copyright (c) 2023, The University of California at Berkeley.
* License: <a href="https://github.com/lf-lang/reactor-c/blob/main/LICENSE.md">BSD 2-clause</a>
* @brief Declarations for watchdogs.
*/

#ifndef WATCHDOG_H
#define WATCHDOG_H 1

#include "platform.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* Watchdog function type. The argument passed to one of
* these watchdog functions is a pointer to the self struct
* for the reactor.
*/
typedef void(*watchdog_function_t)(void*);

/** Typdef for watchdog_t struct, used to call watchdog handler. */
typedef struct watchdog_t watchdog_t;

/** Watchdog struct for handler. */
struct watchdog_t {
struct self_base_t* base; // The reactor that contains the watchdog.
trigger_t* trigger; // The trigger associated with this watchdog.
instant_t expiration; // The expiration instant for the watchdog. (Initialized to NEVER)
interval_t min_expiration; // The minimum expiration interval for the watchdog.
lf_thread_t thread_id; // The thread that the watchdog is meant to run on.
bool thread_active; // Boolean indicating whether or not thread is active.
watchdog_function_t watchdog_function; // The function/handler for the watchdog.
};

/**
* @brief Start or restart the watchdog timer.
* This function sets the expiration time of the watchdog to the current logical time
* plus the minimum timeout of the watchdog plus the specified `additional_timeout`.
* If a watchdog timer thread is not already running, then this function will start one.
* This function assumes the reactor mutex is held when it is called; this assumption
* is satisfied whenever this function is called from within a reaction that declares
* the watchdog as an effect.
*
* @param watchdog The watchdog to be started
* @param additional_timeout Additional timeout to be added to the watchdog's
* minimum expiration.
*/
void lf_watchdog_start(watchdog_t* watchdog, interval_t additional_timeout);

/**
* @brief Stop the specified watchdog without invoking the expiration handler.
* This function sets the expiration time of the watchdog to `NEVER`.
*
* @param watchdog The watchdog.
*/
void lf_watchdog_stop(watchdog_t* watchdog);

#ifdef __cplusplus
}
#endif

#endif
2 changes: 1 addition & 1 deletion lingua-franca-ref.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
master
watchdogs-eal2
1 change: 1 addition & 0 deletions test/src_gen_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ bool _lf_trigger_shutdown_reactions() { return true; }
void _lf_set_default_command_line_options() {}
void _lf_trigger_startup_reactions() {}
void _lf_initialize_timers() {}
void _lf_initialize_watchdog_mutexes() {}
void logical_tag_complete(tag_t tag_to_send) {}