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

Unit testing of thread scheduling API + additional fixes #416

Merged
merged 10 commits into from
Apr 30, 2024
Merged
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
Loading