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

Making MIN_SLEEP_DURATION a platform variable and Add busy wait #403

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions core/federated/federate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1123,13 +1123,13 @@ static void* update_ports_from_staa_offsets(void* args) {
// we require a minimum wait time here. Note that zero-valued STAAs are
// included, and STA might be zero or very small.
// In this case, this thread will fail to ever release the environment mutex.
// This causes chaos. The MIN_SLEEP_DURATION is the smallest amount of time
// This causes chaos. The lf_min_sleep_duration is the smallest amount of time
// that wait_until will actually wait. Note that this strategy does not
// block progress of any execution that is actually processing events.
// It only slightly delays the decision that an event is absent, and only
// if the STAA and STA are extremely small.
if (wait_time < 5 * MIN_SLEEP_DURATION) {
wait_until_time += 5 * MIN_SLEEP_DURATION;
if (wait_time < 5 * lf_min_sleep_duration) {
wait_until_time += 5 * lf_min_sleep_duration;
}
while (a_port_is_unknown(staa_elem)) {
LF_PRINT_DEBUG("**** (update thread) waiting until: " PRINTF_TIME, wait_until_time - lf_time_start());
Expand Down Expand Up @@ -1197,7 +1197,7 @@ static void* update_ports_from_staa_offsets(void* args) {
// The wait is necessary to prevent a busy wait, which will only occur if port
// status are always known inside the while loop
// Be sure to use wait_until() instead of sleep() because sleep() will not release the mutex.
instant_t wait_until_time = lf_time_add(env->current_tag.time, 2 * MIN_SLEEP_DURATION);
instant_t wait_until_time = lf_time_add(env->current_tag.time, 2 * lf_min_sleep_duration);
wait_until(wait_until_time, &lf_port_status_changed);

continue;
Expand Down
12 changes: 9 additions & 3 deletions core/threaded/reactor_threaded.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "reactor_common.h"
#include "watchdog.h"

#include "platform/lf_unix_clock_support.h"

#ifdef FEDERATED
#include "federate.h"
#endif
Expand Down Expand Up @@ -199,9 +201,13 @@ bool wait_until(instant_t wait_until_time, lf_cond_t* condition) {
LF_PRINT_DEBUG("-------- Waiting until physical time " PRINTF_TIME, wait_until_time - start_time);
// Check whether we actually need to wait, or if we have already passed the timepoint.
interval_t wait_duration = wait_until_time - lf_time_physical();
if (wait_duration < MIN_SLEEP_DURATION) {
LF_PRINT_DEBUG("Wait time " PRINTF_TIME " is less than MIN_SLEEP_DURATION " PRINTF_TIME ". Skipping wait.",
wait_duration, MIN_SLEEP_DURATION);
if (wait_duration < lf_min_sleep_duration) {
LF_PRINT_DEBUG("Wait time " PRINTF_TIME " is less than lf_min_sleep_duration " PRINTF_TIME
". Performing busy wait.",
wait_duration, lf_min_sleep_duration);
while (lf_time_physical() < wait_until_time) {
// Busy wait
}
return true;
}

Expand Down
15 changes: 0 additions & 15 deletions include/core/reactor_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,6 @@
#include "modes.h"
#include "port.h"

////////////////////// Constants & Macros //////////////////////

/**
* @brief Constant giving the minimum amount of time to sleep to wait
* for physical time to reach a logical time.
*
* Unless the "fast" option is given, an LF program will wait until
* physical time matches logical time before handling an event with
* a given logical time. The amount of time is less than this given
* threshold, then no wait will occur. The purpose of this is
* to prevent unnecessary delays caused by simply setting up and
* performing the wait.
*/
#define MIN_SLEEP_DURATION USEC(10)

////////////////////// Global Variables //////////////////////

// The following variables are defined in reactor_common.c and used in reactor.c,
Expand Down
4 changes: 2 additions & 2 deletions include/core/threaded/reactor_threaded.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ void lf_synchronize_with_other_federates(void);
*
* The mutex lock associated with the condition argument is assumed to be held by
* the calling thread. This mutex is released while waiting. If the wait time is
* too small to actually wait (less than MIN_SLEEP_DURATION), then this function
* immediately returns true and the mutex is not released.
* too small (less than lf_min_sleep_duration) to wait using lf_clock_cond_timedwait,
* then this function performs busy wait and the mutex is not released.
*
* @param env Environment within which we are executing.
* @param wait_until_time The time to wait until physical time matches it.
Expand Down
13 changes: 13 additions & 0 deletions low_level_platform/api/platform/lf_unix_clock_support.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
#include <time.h>
#include <errno.h>

/**
* @brief Constant giving the minimum amount of time to sleep to wait
* for physical time to reach a logical time.
*
* Unless the "fast" option is given, an LF program will wait until
* physical time matches logical time before handling an event with
* a given logical time. The amount of time is less than this given
* threshold, then no wait will occur. The purpose of this is
* to prevent unnecessary delays caused by simply setting up and
* performing the wait.
*/
extern instant_t lf_min_sleep_duration;

/**
* @brief Convert a _lf_time_spec_t ('tp') to an instant_t representation in
* nanoseconds.
Expand Down
3 changes: 3 additions & 0 deletions low_level_platform/impl/src/lf_unix_clock_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "logging.h"
#include "platform/lf_unix_clock_support.h"

instant_t lf_min_sleep_duration;

instant_t convert_timespec_to_ns(struct timespec tp) { return ((instant_t)tp.tv_sec) * BILLION + tp.tv_nsec; }

struct timespec convert_ns_to_timespec(instant_t t) {
Expand All @@ -23,6 +25,7 @@ void _lf_initialize_clock() {
}

lf_print("---- System clock resolution: %ld nsec", res.tv_nsec);
lf_min_sleep_duration = NSEC(res.tv_nsec);
}

/**
Expand Down
Loading