Skip to content

Commit

Permalink
Merge pull request #486 from lf-lang/windows-warnings
Browse files Browse the repository at this point in the history
Various fixes to silence warnings on Windows
  • Loading branch information
edwardalee authored Sep 30, 2024
2 parents 0c56119 + 3909a83 commit 9ef620b
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 63 deletions.
14 changes: 10 additions & 4 deletions core/environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,16 @@ int environment_init(environment_t* env, const char* name, int id, int num_worke
const char* trace_file_name) {
(void)trace_file_name; // Will be used with future enclave support.

env->name = malloc(strlen(name) + 1); // +1 for the null terminator
LF_ASSERT_NON_NULL(env->name);
strcpy(env->name, name);

// Space for the name string with the null terminator.
if (name != NULL) {
size_t name_size = strlen(name) + 1; // +1 for the null terminator
env->name = (char*)malloc(name_size);
LF_ASSERT_NON_NULL(env->name);
// Use strncpy rather than strcpy to avoid compiler warnings.
strncpy(env->name, name, name_size);
} else {
env->name = NULL;
}
env->id = id;
env->stop_tag = FOREVER_TAG;

Expand Down
10 changes: 8 additions & 2 deletions core/threaded/reactor_threaded.c
Original file line number Diff line number Diff line change
Expand Up @@ -1028,8 +1028,12 @@ int lf_reactor_c_main(int argc, const char* argv[]) {
lf_print("---- Start execution ----");
#else
struct timespec physical_time_timespec = {start_time / BILLION, start_time % BILLION};
lf_print("---- Start execution at time %s---- plus %ld nanoseconds", ctime(&physical_time_timespec.tv_sec),
physical_time_timespec.tv_nsec);
struct tm* time_info = localtime(&physical_time_timespec.tv_sec);
char buffer[80]; // Long enough to hold the formatted time string.
// Use strftime rather than ctime because as of C23, ctime is deprecated.
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", time_info);

lf_print("---- Start execution on %s ---- plus %ld nanoseconds", buffer, physical_time_timespec.tv_nsec);
#endif // MINIMAL_STDLIB

// Create and initialize the environments for each enclave
Expand Down Expand Up @@ -1114,6 +1118,8 @@ int lf_reactor_c_main(int argc, const char* argv[]) {
} else {
int failure = lf_thread_join(env->thread_ids[j], &worker_thread_exit_status);
if (failure) {
// Windows warns that strerror is deprecated but doesn't define strerror_r.
// There seems to be no portable replacement.
lf_print_error("Failed to join thread listening for incoming messages: %s", strerror(failure));
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/utils/lf_semaphore.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @param count The count to start with.
* @return lf_semaphore_t* Can be NULL on error.
*/
lf_semaphore_t* lf_semaphore_new(int count) {
lf_semaphore_t* lf_semaphore_new(size_t count) {
lf_semaphore_t* semaphore = (lf_semaphore_t*)malloc(sizeof(lf_semaphore_t));
LF_MUTEX_INIT(&semaphore->mutex);
LF_COND_INIT(&semaphore->cond, &semaphore->mutex);
Expand All @@ -55,7 +55,7 @@ lf_semaphore_t* lf_semaphore_new(int count) {
* @param semaphore Instance of a semaphore
* @param i The count to add.
*/
void lf_semaphore_release(lf_semaphore_t* semaphore, int i) {
void lf_semaphore_release(lf_semaphore_t* semaphore, size_t i) {
assert(semaphore != NULL);
LF_MUTEX_LOCK(&semaphore->mutex);
semaphore->count += i;
Expand Down
2 changes: 2 additions & 0 deletions core/utils/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ void lf_print_error_system_failure(const char* format, ...) {
va_start(args, format);
lf_vprint_error(format, args);
va_end(args);
// Windows warns that strerror is deprecated but doesn't define strerror_r.
// There seems to be no portable replacement.
lf_print_error_and_exit("Error %d: %s", errno, strerror(errno));
exit(EXIT_FAILURE);
}
Expand Down
6 changes: 3 additions & 3 deletions include/core/lf_token.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ typedef struct lf_token_t {
* A record of the subset of channels of a multiport that have present inputs.
*/
typedef struct lf_sparse_io_record_t {
int size; // -1 if overflowed. 0 if empty.
size_t capacity; // Max number of writes to be considered sparse.
size_t present_channels[]; // Array of channel indices that are present.
int size; // -1 if overflowed. 0 if empty.
size_t capacity; // Max number of writes to be considered sparse.
size_t* present_channels; // Array of channel indices that are present.
} lf_sparse_io_record_t;

/**
Expand Down
6 changes: 3 additions & 3 deletions include/core/utils/lf_semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>

typedef struct {
int count;
size_t count;
lf_mutex_t mutex;
lf_cond_t cond;
} lf_semaphore_t;
Expand All @@ -52,15 +52,15 @@ typedef struct {
* @param count The count to start with.
* @return lf_semaphore_t* Can be NULL on error.
*/
lf_semaphore_t* lf_semaphore_new(int count);
lf_semaphore_t* lf_semaphore_new(size_t count);

/**
* @brief Release the 'semaphore' and add 'i' to its count.
*
* @param semaphore Instance of a semaphore
* @param i The count to add.
*/
void lf_semaphore_release(lf_semaphore_t* semaphore, int i);
void lf_semaphore_release(lf_semaphore_t* semaphore, size_t i);

/**
* @brief Acquire the 'semaphore'. Will block if count is 0.
Expand Down
2 changes: 1 addition & 1 deletion lingua-franca-ref.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
add-reaction
master
12 changes: 10 additions & 2 deletions logging/api/logging_macros.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifndef LOGGING_MACROS_H
#define LOGGING_MACROS_H
#include "logging.h"

/**
Expand All @@ -12,6 +14,11 @@
#define LOG_LEVEL LOG_LEVEL_INFO
#endif

// To prevent warnings "conditional expression is constant", we define static booleans
// here instead of directly testing LOG_LEVEL in the if statements in the macros below.
static const bool _lf_log_level_is_log = LOG_LEVEL >= LOG_LEVEL_LOG;
static const bool _lf_log_level_is_debug = LOG_LEVEL >= LOG_LEVEL_DEBUG;

/**
* A macro used to print useful logging information. It can be enabled
* by setting the target property 'logging' to 'LOG' or
Expand All @@ -31,7 +38,7 @@
*/
#define LF_PRINT_LOG(format, ...) \
do { \
if (LOG_LEVEL >= LOG_LEVEL_LOG) { \
if (_lf_log_level_is_log) { \
lf_print_log(format, ##__VA_ARGS__); \
} \
} while (0)
Expand All @@ -54,7 +61,7 @@
*/
#define LF_PRINT_DEBUG(format, ...) \
do { \
if (LOG_LEVEL >= LOG_LEVEL_DEBUG) { \
if (_lf_log_level_is_debug) { \
lf_print_debug(format, ##__VA_ARGS__); \
} \
} while (0)
Expand Down Expand Up @@ -100,3 +107,4 @@
} \
} while (0)
#endif // NDEBUG
#endif // LOGGING_MACROS_H
8 changes: 4 additions & 4 deletions low_level_platform/impl/src/lf_atomic_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
#include "platform/lf_atomic.h"
#include <windows.h>

int lf_atomic_fetch_add(int* ptr, int value) { return InterlockedExchangeAdd(ptr, value); }
int lf_atomic_fetch_add(int* ptr, int value) { return InterlockedExchangeAdd((LONG*)ptr, (LONG)value); }
int64_t lf_atomic_fetch_add64(int64_t* ptr, int64_t value) { return InterlockedExchangeAdd64(ptr, value); }
int lf_atomic_add_fetch(int* ptr, int value) { return InterlockedAdd(ptr, value); }
int lf_atomic_add_fetch(int* ptr, int value) { return InterlockedAdd((LONG*)ptr, (LONG)value); }
int64_t lf_atomic_add_fetch64(int64_t* ptr, int64_t value) { return InterlockedAdd64(ptr, value); }
bool lf_atomic_bool_compare_and_swap(int* ptr, int oldval, int newval) {
return (InterlockedCompareExchange(ptr, newval, oldval) == oldval);
return (InterlockedCompareExchange((LONG*)ptr, (LONG)newval, (LONG)oldval) == oldval);
}
bool lf_atomic_bool_compare_and_swap64(int64_t* ptr, int64_t oldval, int64_t newval) {
return (InterlockedCompareExchange64(ptr, newval, oldval) == oldval);
}
int lf_atomic_val_compare_and_swap(int* ptr, int oldval, int newval) {
return InterlockedCompareExchange(ptr, newval, oldval);
return InterlockedCompareExchange((LONG*)ptr, (LONG)newval, (LONG)oldval);
}
int64_t lf_atomic_val_compare_and_swap64(int64_t* ptr, int64_t oldval, int64_t newval) {
return InterlockedCompareExchange64(ptr, newval, oldval);
Expand Down
49 changes: 40 additions & 9 deletions low_level_platform/impl/src/lf_windows_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <process.h>
#include <sysinfoapi.h>
#include <time.h>
#include <stdio.h> // For fprintf()

#include "platform/lf_windows_support.h"
#include "low_level_platform.h"
Expand All @@ -64,7 +65,7 @@ void _lf_initialize_clock() {
if (_lf_use_performance_counter) {
_lf_frequency_to_ns = (double)performance_frequency.QuadPart / BILLION;
} else {
lf_print_error("High resolution performance counter is not supported on this machine.");
fprintf(stderr, "ERROR: High resolution performance counter is not supported on this machine.\n");
_lf_frequency_to_ns = 0.01;
}
}
Expand All @@ -89,9 +90,9 @@ int _lf_clock_gettime(instant_t* t) {
}
LARGE_INTEGER windows_time;
if (_lf_use_performance_counter) {
int result = QueryPerformanceCounter(&windows_time);
result = QueryPerformanceCounter(&windows_time);
if (result == 0) {
lf_print_error("_lf_clock_gettime(): Failed to read the value of the physical clock.");
fprintf(stderr, "ERROR: _lf_clock_gettime(): Failed to read the value of the physical clock.\n");
return result;
}
} else {
Expand Down Expand Up @@ -140,6 +141,7 @@ int lf_sleep(interval_t sleep_duration) {
}

int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) {
(void)env; // Suppress unused variable warning.
interval_t sleep_duration = wakeup_time - lf_time_physical();

if (sleep_duration <= 0) {
Expand All @@ -165,7 +167,11 @@ int lf_available_cores() {
lf_thread_t lf_thread_self() { return GetCurrentThread(); }

int lf_thread_create(lf_thread_t* thread, void* (*lf_thread)(void*), void* arguments) {
uintptr_t handle = _beginthreadex(NULL, 0, lf_thread, arguments, 0, NULL);
// _beginthreadex requires a function that returns unsigned rather than void*.
// So the following double cast suppresses the warning:
// '_beginthreadex_proc_type' differs in levels of indirection from 'void *(__cdecl *)(void *)'
uintptr_t handle =
_beginthreadex(NULL, 0, (unsigned(__stdcall*)(void*))(uintptr_t(__stdcall*)(void*))lf_thread, arguments, 0, NULL);
*thread = (HANDLE)handle;
if (handle == 0) {
return errno;
Expand All @@ -183,6 +189,9 @@ int lf_thread_create(lf_thread_t* thread, void* (*lf_thread)(void*), void* argum
*/
int lf_thread_join(lf_thread_t thread, void** thread_return) {
DWORD retvalue = WaitForSingleObject(thread, INFINITE);
if (thread_return != NULL) {
*thread_return = (void*)retvalue;
}
if (retvalue == WAIT_FAILED) {
return EINVAL;
}
Expand All @@ -192,11 +201,23 @@ int lf_thread_join(lf_thread_t thread, void** thread_return) {
/**
* Real-time scheduling API not implemented for Windows.
*/
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number) { return -1; }
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number) {
(void)thread; // Suppress unused variable warning.
(void)cpu_number; // Suppress unused variable warning.
return -1;
}

int lf_thread_set_priority(lf_thread_t thread, int priority) { return -1; }
int lf_thread_set_priority(lf_thread_t thread, int priority) {
(void)thread; // Suppress unused variable warning.
(void)priority; // Suppress unused variable warning.
return -1;
}

int lf_thread_set_scheduling_policy(lf_thread_t thread, lf_scheduling_policy_t* policy) { return -1; }
int lf_thread_set_scheduling_policy(lf_thread_t thread, lf_scheduling_policy_t* policy) {
(void)thread; // Suppress unused variable warning.
(void)policy; // Suppress unused variable warning.
return -1;
}

int lf_mutex_init(_lf_critical_section_t* critical_section) {
// Set up a recursive mutex
Expand Down Expand Up @@ -278,10 +299,20 @@ int _lf_cond_timedwait(lf_cond_t* cond, instant_t wakeup_time) {
}

// convert ns to ms and round up to closest full integer
DWORD wait_duration_ms = (wait_duration + 999999LL) / 1000000LL;
interval_t wait_duration_ms = (wait_duration + 999999LL) / 1000000LL;
DWORD wait_duration_saturated;
if (wait_duration_ms > 0xFFFFFFFFLL) {
// Saturate at 0xFFFFFFFFLL
wait_duration_saturated = (DWORD)0xFFFFFFFFLL;
} else if (wait_duration_ms <= 0) {
// No need to wait. Return indicating that the wait is complete.
return LF_TIMEOUT;
} else {
wait_duration_saturated = (DWORD)wait_duration_ms;
}

int return_value = (int)SleepConditionVariableCS((PCONDITION_VARIABLE)&cond->condition,
(PCRITICAL_SECTION)cond->critical_section, wait_duration_ms);
(PCRITICAL_SECTION)cond->critical_section, wait_duration_saturated);
if (return_value == 0) {
// Error
if (GetLastError() == ERROR_TIMEOUT) {
Expand Down
Loading

0 comments on commit 9ef620b

Please sign in to comment.