Skip to content

Commit

Permalink
Merge pull request #416 from lf-lang/thread-sched-test-and-fix
Browse files Browse the repository at this point in the history
Unit testing of thread scheduling API + additional fixes
  • Loading branch information
lhstrh authored Apr 30, 2024
2 parents b4bdaf8 + a1e043b commit 329528f
Show file tree
Hide file tree
Showing 21 changed files with 205 additions and 164 deletions.
13 changes: 11 additions & 2 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
run:
strategy:
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
platform: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.platform }}

steps:
Expand All @@ -24,4 +24,13 @@ jobs:
cd build
cmake .. ${{ inputs.cmake-args }}
cmake --build .
make test
sudo make test
- name: Run RTI unit tests
run: |
cd core/federated/RTI
mkdir build
cd build
cmake ..
cmake --build .
ctest
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ util/tracing/trace_to_csv.o
util/tracing/trace_to_influxdb
util/tracing/trace_to_influxdb.o
util/tracing/trace_util.o

# Generated trace lib
trace/**/*.a
5 changes: 0 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ if(DEFINED LF_SINGLE_THREADED)
add_compile_definitions(LF_SINGLE_THREADED=1)
endif()

# Warnings as errors
add_compile_options(-Werror)

set(Test test)
set(Lib lib)
set(CoreLibPath core)
set(CoreLib reactor-c)
Expand All @@ -42,7 +38,6 @@ include_directories(${CMAKE_SOURCE_DIR}/include/core/utils)
include_directories(${CMAKE_SOURCE_DIR}/include/api)

enable_testing()
add_subdirectory(${Test})
add_subdirectory(${Lib})
add_subdirectory(${CoreLibPath})

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ To run tests for the multithreaded runtime, provide a nonzero number of workers
when invoking `cmake`. For example:

- `cmake .. -DNUMBER_OF_WORKERS=2`
- `cmake --build .`
- `sudo make test`

Note that one of the tests in the multithreaded test suite requires sudo because
it changes the scheduling policy and priorities.

To define/undefine other preprocessor definitions such as `LOG_LEVEL`, pass them as
arguments to `cmake` in the same way as with `NUMBER_OF_WORKERS`, using the same
Expand Down
121 changes: 53 additions & 68 deletions core/federated/RTI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,58 +1,15 @@
# This is a cmake build script providing a solution for compiling
# the RTI in this directory..
#
# Usage:
#
# To compile with cmake, run the following commands:
#
# $> mkdir build && cd build
# $> cmake ../
# $> make
# $> sudo make install
#
# This create a binary RTI in the current working directory. Please put this in
# a directory that is on the path.
#
# To enable DEBUG messages, use the following build commands instead:
#
# $> mkdir build && cd build
# $> cmake -DCMAKE_BUILD_TYPE=DEBUG ../
# $> make
# $> sudo make install
#
# If you would like to go back to non-DEBUG mode, you would have to remove all
# contents of the `build` folder.

# To enable simple HMAC-based authentication of federates,
# add `-DAUTH=ON` option to the cmake command as shown below:
#
# $> mkdir build && cd build
# $> cmake -DAUTH=ON ../
# $> make
# $> sudo make install
#
# If you would like to go back to non-AUTH mode, you would have to remove all
# contents of the `build` folder.

cmake_minimum_required(VERSION 3.12)
project(RTI VERSION 1.0.0 LANGUAGES C)

set(CoreLib ../../../core)
set(LF_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../..)

set(IncludeDir ../../../include/core)
include_directories(../../../include)
include_directories(${IncludeDir})
include_directories(${IncludeDir}/federated)
include_directories(${IncludeDir}/federated/network)
include_directories(${IncludeDir}/modal_models)
include_directories(${IncludeDir}/utils)


# Declare a new executable target and list all its sources
add_executable(
RTI
main.c
set(RTI_LIB rti_lib)
set(RTI_MAIN RTI)

# Add common RTI functionality to a static library. This is done to simplify
# the building of unit tests.
add_library(${RTI_LIB} STATIC
rti_common.c
rti_remote.c
${CoreLib}/tracepoint.c
Expand All @@ -64,6 +21,17 @@ add_executable(
${CoreLib}/utils/pqueue_tag.c
${CoreLib}/utils/pqueue.c
)

# Add the main target which will link with the library.
add_executable(${RTI_MAIN} main.c)

target_include_directories(${RTI_LIB} PUBLIC ../../../include)
target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir})
target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/federated)
target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/federated/network)
target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/modal_models)
target_include_directories(${RTI_LIB} PUBLIC ${IncludeDir}/utils)

if (NOT DEFINED LOG_LEVEL)
set(LOG_LEVEL 0)
ENDIF(NOT DEFINED LOG_LEVEL)
Expand All @@ -73,62 +41,79 @@ IF(CMAKE_BUILD_TYPE MATCHES DEBUG)
message("-- Building RTI with DEBUG messages enabled")
set(LOG_LEVEL 4)
ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG)
target_compile_definitions(RTI PUBLIC LOG_LEVEL=${LOG_LEVEL})
target_compile_definitions(${RTI_LIB} PUBLIC LOG_LEVEL=${LOG_LEVEL})

include(${LF_ROOT}/version/api/CMakeLists.txt)
target_link_libraries(RTI lf::version-api)
target_link_libraries(${RTI_LIB} PUBLIC lf::version-api)

include(${LF_ROOT}/logging/api/CMakeLists.txt)
target_link_libraries(RTI lf::logging-api)
target_link_libraries(${RTI_LIB} PUBLIC lf::logging-api)

include(${LF_ROOT}/tag/api/CMakeLists.txt)
target_link_libraries(RTI lf::tag-api)
target_link_libraries(${RTI_LIB} PUBLIC lf::tag-api)

include(${LF_ROOT}/platform/api/CMakeLists.txt)
target_link_libraries(RTI lf::platform-api)
target_link_libraries(${RTI_LIB} PUBLIC lf::platform-api)

include(${LF_ROOT}/platform/impl/CMakeLists.txt)
target_link_libraries(RTI lf::platform-impl)
target_link_libraries(${RTI_LIB} PUBLIC lf::platform-impl)

include(${LF_ROOT}/trace/api/CMakeLists.txt)
target_link_libraries(RTI lf::trace-api)
target_link_libraries(${RTI_LIB} PUBLIC lf::trace-api)

include(${LF_ROOT}/trace/impl/CMakeLists.txt)
target_link_libraries(RTI lf::trace-impl)
target_link_libraries(${RTI_LIB} PUBLIC lf::trace-impl)

include(${LF_ROOT}/low_level_platform/impl/CMakeLists.txt)
target_link_libraries(RTI lf::low-level-platform-impl)
target_link_libraries(${RTI_LIB} PUBLIC lf::low-level-platform-impl)

include(${LF_ROOT}/low_level_platform/api/CMakeLists.txt)
target_link_libraries(RTI lf::low-level-platform-api)
target_link_libraries(${RTI_LIB} PUBLIC lf::low-level-platform-api)

# Set the STANDALONE_RTI flag to include the rti_remote and rti_common.
target_compile_definitions(RTI PUBLIC STANDALONE_RTI=1)
target_compile_definitions(${RTI_LIB} PUBLIC STANDALONE_RTI=1)

# Set FEDERATED to get federated compilation support
target_compile_definitions(RTI PUBLIC FEDERATED=1)

target_compile_definitions(RTI PUBLIC PLATFORM_${CMAKE_SYSTEM_NAME})
target_compile_definitions(${RTI_LIB} PUBLIC FEDERATED=1)
target_compile_definitions(${RTI_LIB} PUBLIC PLATFORM_${CMAKE_SYSTEM_NAME})

# Set RTI Tracing
target_compile_definitions(RTI PUBLIC RTI_TRACE)
target_compile_definitions(${RTI_LIB} PUBLIC RTI_TRACE)

# Warnings as errors
target_compile_options(RTI PUBLIC -Werror)
target_compile_options(${RTI_LIB} PUBLIC -Werror)

# Find threads and link to it
find_package(Threads REQUIRED)
target_link_libraries(RTI Threads::Threads)
target_link_libraries(${RTI_LIB} PUBLIC Threads::Threads)

# Option for enabling federate authentication by RTI.
option(AUTH "Federate authentication by RTI enabled." OFF)
IF(AUTH MATCHES ON)
add_compile_definitions(__RTI_AUTH__)
target_compile_definitions(${RTI_LIB} PUBLIC __RTI_AUTH__)
# Find OpenSSL and link to it
find_package(OpenSSL REQUIRED)
target_link_libraries(RTI OpenSSL::SSL)
target_link_libraries(${RTI_LIB} PUBLIC OpenSSL::SSL)
ENDIF(AUTH MATCHES ON)

# Link the main target with the library.
target_link_libraries(${RTI_MAIN} PRIVATE ${RTI_LIB})

install(
TARGETS RTI
DESTINATION bin
)

# Build unit tests
enable_testing()
set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test)
set(TEST_SRCS
${TEST_DIR}/rti_common_test.c
)
foreach(TEST_SRC ${TEST_SRCS})
get_filename_component(TEST_NAME ${TEST_SRC} NAME_WE)
add_executable(${TEST_NAME} ${TEST_SRC})
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
target_link_libraries(${TEST_NAME} PUBLIC ${RTI_LIB})
target_include_directories(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
endforeach()
6 changes: 6 additions & 0 deletions core/federated/RTI/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ make
sudo make install
```

To run the unit tests
```bash
make test
```

**Note:** To enable DEBUG messages, use the following build commands instead:

```bash
Expand Down Expand Up @@ -47,3 +52,4 @@ docker login -u [username]
```

To authenticate, request a PAT on [DockerHub](https://hub.docker.com/settings/security).

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#if defined STANDALONE_RTI
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
Expand Down Expand Up @@ -246,7 +245,7 @@ static void multiple_nodes() {
assert(lf_tag_compare(test_rti.scheduling_nodes[3]->min_delays[0].min_delay, (tag_t){NSEC(3), 0}) == 0);
}

int main(int argc, char** argv) {
int main() {
initialize_rti_common(&test_rti);

// Tests for the function update_min_delays_upstream()
Expand All @@ -257,4 +256,3 @@ int main(int argc, char** argv) {
two_nodes_normal_delay();
multiple_nodes();
}
#endif
2 changes: 1 addition & 1 deletion low_level_platform/api/low_level_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ typedef struct {
* @param cpu_number the CPU ID
* @return 0 on success, platform-specific error number otherwise.
*/
int lf_thread_set_cpu(lf_thread_t thread, int cpu_number);
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number);

/**
* @brief Set the priority of a thread.
Expand Down
22 changes: 15 additions & 7 deletions low_level_platform/impl/src/lf_linux_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#else
#include "lf_POSIX_threads_support.c"

int lf_thread_set_cpu(lf_thread_t thread, int cpu_number) {
// First verify that we have num_cores>cpu_number
if (lf_available_cores() <= cpu_number) {
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number) {
// Sanitize input
if (lf_available_cores() <= 0 || cpu_number >= (size_t)lf_available_cores()) {
return -1;
}

Expand Down Expand Up @@ -89,6 +89,7 @@ int lf_thread_set_priority(lf_thread_t thread, int priority) {

int lf_thread_set_scheduling_policy(lf_thread_t thread, lf_scheduling_policy_t* policy) {
int posix_policy, res;
bool set_priority;
struct sched_param schedparam;

// Get the current scheduling policy
Expand All @@ -103,14 +104,18 @@ int lf_thread_set_scheduling_policy(lf_thread_t thread, lf_scheduling_policy_t*
switch (policy->policy) {
case LF_SCHED_FAIR:
posix_policy = SCHED_OTHER;
schedparam.sched_priority = 0;
set_priority = false;
break;
case LF_SCHED_TIMESLICE:
posix_policy = SCHED_RR;
schedparam.sched_priority = sched_get_priority_max(SCHED_RR);
set_priority = true;
break;
case LF_SCHED_PRIORITY:
posix_policy = SCHED_FIFO;
schedparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
set_priority = true;
break;
default:
return -1;
Expand All @@ -123,10 +128,13 @@ int lf_thread_set_scheduling_policy(lf_thread_t thread, lf_scheduling_policy_t*
return res;
}

// Set the priority
res = lf_thread_set_priority(thread, policy->priority);
if (res != 0)
return res;
// Set the priority of we chose a RT scheduler
if (set_priority) {
res = lf_thread_set_priority(thread, policy->priority);
if (res != 0) {
return res;
}
}

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion low_level_platform/impl/src/lf_macos_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/**
* Real-time scheduling API not implemented for macOS.
*/
int lf_thread_set_cpu(lf_thread_t thread, int cpu_number) { return -1; }
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number) { return -1; }

int lf_thread_set_priority(lf_thread_t thread, int priority) { return -1; }

Expand Down
2 changes: 1 addition & 1 deletion low_level_platform/impl/src/lf_windows_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ 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, int cpu_number) { return -1; }
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number) { return -1; }

int lf_thread_set_priority(lf_thread_t thread, int priority) { return -1; }

Expand Down
2 changes: 1 addition & 1 deletion low_level_platform/impl/src/lf_zephyr_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ int lf_thread_id() { return *((int*)k_thread_custom_data_get()); }

lf_thread_t lf_thread_self() { return k_current_get(); }

int lf_thread_set_cpu(lf_thread_t thread, int cpu_number) { return k_thread_cpu_pin(thread, cpu_number); }
int lf_thread_set_cpu(lf_thread_t thread, size_t cpu_number) { return k_thread_cpu_pin(thread, cpu_number); }

/**
* Real-time scheduling API
Expand Down
2 changes: 0 additions & 2 deletions test/CMakeLists.txt

This file was deleted.

Loading

0 comments on commit 329528f

Please sign in to comment.