Skip to content

Commit

Permalink
Merge pull request #142 from lf-lang/critical-section
Browse files Browse the repository at this point in the history
Make critical section functions part of the public API
  • Loading branch information
edwardalee authored Jan 16, 2023
2 parents f3e831a + b031b88 commit 3fd9f4d
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 85 deletions.
21 changes: 3 additions & 18 deletions core/reactor.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ int _lf_do_step(void) {
int next(void) {
// Enter the critical section and do not leave until we have
// determined which tag to commit to and start invoking reactions for.
if (_lf_critical_section_enter() != 0) {
if (lf_critical_section_enter() != 0) {
lf_print_error_and_exit("Could not enter critical section");
}
event_t* event = (event_t*)pqueue_peek(event_q);
Expand Down Expand Up @@ -264,7 +264,7 @@ int next(void) {
// gets scheduled from an interrupt service routine.
// In this case, check the event queue again to make sure to
// advance time to the correct tag.
if(_lf_critical_section_exit() != 0) {
if(lf_critical_section_exit() != 0) {
lf_print_error_and_exit("Could not leave critical section");
}
return 1;
Expand All @@ -287,7 +287,7 @@ int next(void) {
// extract all the reactions triggered by these events, and
// stick them into the reaction queue.
_lf_pop_events();
if(_lf_critical_section_exit() != 0) {
if(lf_critical_section_exit() != 0) {
lf_print_error_and_exit("Could not leave critical section");
}

Expand Down Expand Up @@ -378,18 +378,3 @@ int lf_reactor_c_main(int argc, const char* argv[]) {
return -1;
}
}

/**
* The following calls are directly forwarded to platform.h
*/
void _lf_notify_of_event() {
lf_notify_of_event();
}

int _lf_critical_section_enter() {
return lf_critical_section_enter();
}

int _lf_critical_section_exit() {
return lf_critical_section_exit();
}
18 changes: 9 additions & 9 deletions core/reactor_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1476,13 +1476,13 @@ trigger_t* _lf_action_to_trigger(void* action) {
*/
trigger_handle_t _lf_schedule_token(void* action, interval_t extra_delay, lf_token_t* token) {
trigger_t* trigger = _lf_action_to_trigger(action);
if (_lf_critical_section_enter() != 0) {
if (lf_critical_section_enter() != 0) {
lf_print_error_and_exit("Could not enter critical section");
}
int return_value = _lf_schedule(trigger, extra_delay, token);
// Notify the main thread in case it is waiting for physical time to elapse.
_lf_notify_of_event();
if(_lf_critical_section_exit() != 0) {
lf_notify_of_event();
if(lf_critical_section_exit() != 0) {
lf_print_error_and_exit("Could not leave critical section");
}
return return_value;
Expand All @@ -1503,7 +1503,7 @@ trigger_handle_t _lf_schedule_copy(void* action, interval_t offset, void* value,
lf_print_error("schedule: Invalid trigger or element size.");
return -1;
}
if (_lf_critical_section_enter() != 0) {
if (lf_critical_section_enter() != 0) {
lf_print_error_and_exit("Could not enter critical section");
}
// Initialize token with an array size of length and a reference count of 0.
Expand All @@ -1513,8 +1513,8 @@ trigger_handle_t _lf_schedule_copy(void* action, interval_t offset, void* value,
// The schedule function will increment the reference count.
trigger_handle_t result = _lf_schedule(trigger, offset, token);
// Notify the main thread in case it is waiting for physical time to elapse.
_lf_notify_of_event();
if(_lf_critical_section_exit() != 0) {
lf_notify_of_event();
if(lf_critical_section_exit() != 0) {
lf_print_error_and_exit("Could not leave critical section");
}
return result;
Expand All @@ -1527,16 +1527,16 @@ trigger_handle_t _lf_schedule_copy(void* action, interval_t offset, void* value,
trigger_handle_t _lf_schedule_value(void* action, interval_t extra_delay, void* value, size_t length) {
trigger_t* trigger = _lf_action_to_trigger(action);

if (_lf_critical_section_enter() != 0) {
if (lf_critical_section_enter() != 0) {
lf_print_error_and_exit("Could not enter critical section");
}
lf_token_t* token = create_token(trigger->element_size);
token->value = value;
token->length = length;
int return_value = _lf_schedule(trigger, extra_delay, token);
// Notify the main thread in case it is waiting for physical time to elapse.
_lf_notify_of_event();
if(_lf_critical_section_exit() != 0) {
lf_notify_of_event();
if(lf_critical_section_exit() != 0) {
lf_print_error_and_exit("Could not leave critical section");
}
return return_value;
Expand Down
18 changes: 8 additions & 10 deletions core/threaded/reactor_threaded.c
Original file line number Diff line number Diff line change
Expand Up @@ -1171,24 +1171,22 @@ int lf_reactor_c_main(int argc, const char* argv[]) {
}

/**
* @brief Notification of new event is implemented by broadcasting on a
* condition variable.
* @brief Notify of new event by broadcasting on a condition variable.
*/
void _lf_notify_of_event() {
lf_cond_broadcast(&event_q_changed);
int lf_notify_of_event() {
return lf_cond_broadcast(&event_q_changed);
}

/**
* @brief Enter critical section by locking the global mutex
*
* @brief Enter critical section by locking the global mutex.
*/
int _lf_critical_section_enter() {
int lf_critical_section_enter() {
return lf_mutex_lock(&mutex);
}

/**
* @brief Leave critical section by unlocking the global mutex
*
* @brief Leave a critical section by unlocking the global mutex.
*/
int _lf_critical_section_exit() {
int lf_critical_section_exit() {
return lf_mutex_unlock(&mutex);
}
47 changes: 22 additions & 25 deletions include/core/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@ typedef _interval_t interval_t;
*/
typedef _microstep_t microstep_t;

/**
* Enter a critical section where logical time and the event queue are guaranteed
* to not change unless they are changed within the critical section.
* this can be implemented by disabling interrupts.
* Users of this function must ensure that lf_init_critical_sections() is
* called first and that lf_critical_section_exit() is called later.
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_enter();

/**
* Exit the critical section entered with lf_lock_time().
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_exit();

/**
* Notify any listeners that an event has been created.
* The caller should call lf_critical_section_enter() before calling this function.
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_notify_of_event();

// For platforms with threading support, the following functions
// abstract the API so that the LF runtime remains portable.
Expand Down Expand Up @@ -157,7 +179,6 @@ extern int lf_mutex_lock(lf_mutex_t* mutex);
*/
extern int lf_mutex_unlock(lf_mutex_t* mutex);


/**
* Initialize a conditional variable.
*
Expand Down Expand Up @@ -268,30 +289,6 @@ extern int lf_cond_timedwait(lf_cond_t* cond, lf_mutex_t* mutex, instant_t absol
#error "Compiler not supported"
#endif

#else
/**
* Enter a critical section where logical time and the event queue are guaranteed
* to not change unless they are changed within the critical section.
* this can be implemented by disabling interrupts.
* Users of this function must ensure that lf_init_critical_sections() is
* called first and that lf_critical_section_exit() is called later.
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_enter();

/**
* Exit the critical section entered with lf_lock_time().
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_exit();

/**
* Notify any listeners that an event has been created.
* The caller should call lf_critical_section_enter() before calling this function.
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_notify_of_event();

#endif

/**
Expand Down
23 changes: 0 additions & 23 deletions include/core/reactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,28 +569,5 @@ void _lf_fd_send_stop_request_to_rti(void);
*/
bool _lf_check_deadline(self_base_t* self, bool invoke_deadline_handler);

/**
* 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()`
*
*/
int _lf_critical_section_enter();

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

#endif /* REACTOR_H */
/** @} */

0 comments on commit 3fd9f4d

Please sign in to comment.