From 4d4b9bf857341e3cae2ffaef849846b2d12cacbb Mon Sep 17 00:00:00 2001 From: Javier Date: Mon, 3 Oct 2022 22:34:25 +0200 Subject: [PATCH 1/3] Fixed wrong merge --- srcCpp/perftest_cpp.cxx | 2 +- srcCpp11/perftest_cpp.cxx | 2 +- srcCs/Perftest.cs | 2 +- srcDoc/compatibility.rst | 2 +- srcJava/com/rti/perftest/ddsimpl/PerftestVersion.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/srcCpp/perftest_cpp.cxx b/srcCpp/perftest_cpp.cxx index 652b9f1d..95b8091a 100644 --- a/srcCpp/perftest_cpp.cxx +++ b/srcCpp/perftest_cpp.cxx @@ -73,7 +73,7 @@ bool perftest_cpp::_testCompleted = false; bool perftest_cpp::_testCompleted_scan = true; // In order to enter into the scan mode const int timeout_wait_for_ack_sec = 0; const unsigned int timeout_wait_for_ack_nsec = 100000000; -const Perftest_ProductVersion_t perftest_cpp::_version = {9, 9, 9, 9}; +const Perftest_ProductVersion_t perftest_cpp::_version = {0, 0, 0, 0}; /* * PERFTEST-108 diff --git a/srcCpp11/perftest_cpp.cxx b/srcCpp11/perftest_cpp.cxx index e34eacdb..182a944d 100755 --- a/srcCpp11/perftest_cpp.cxx +++ b/srcCpp11/perftest_cpp.cxx @@ -85,7 +85,7 @@ bool perftest_cpp::_testCompleted_scan = true; // In order to enter into the sca const long timeout_wait_for_ack_sec = 0; const unsigned long timeout_wait_for_ack_nsec = 100000000; -const Perftest_ProductVersion_t perftest_cpp::_version = {9, 9, 9, 9}; +const Perftest_ProductVersion_t perftest_cpp::_version = {0, 0, 0, 0}; ThreadPriorities _threadPriorities; /* diff --git a/srcCs/Perftest.cs b/srcCs/Perftest.cs index d7c57252..8b9a2b4c 100755 --- a/srcCs/Perftest.cs +++ b/srcCs/Perftest.cs @@ -36,7 +36,7 @@ public class Perftest : IDisposable private static bool showCpu; private static bool testCompleted; public readonly TimeSpan timeoutWaitForAckTimeSpan = new TimeSpan(0, 0, 0, 0, 10); - public static readonly PerftestVersion version = new PerftestVersion(9, 9, 9, 9); + public static readonly PerftestVersion version = new PerftestVersion(0, 0, 0, 0); /* * PERFTEST-108 diff --git a/srcDoc/compatibility.rst b/srcDoc/compatibility.rst index e7e76481..e56b78e0 100644 --- a/srcDoc/compatibility.rst +++ b/srcDoc/compatibility.rst @@ -3,7 +3,7 @@ Compatibility ============= -*RTI Perftest Master* is designed to be compatible with the *RTI Connext DDS* +*RTI Perftest Develop* is designed to be compatible with the *RTI Connext DDS* middleware. It has been compiled and tested against: - *RTI Connext DDS Professional* 6.0.0 and above. Nonetheless previous versions diff --git a/srcJava/com/rti/perftest/ddsimpl/PerftestVersion.java b/srcJava/com/rti/perftest/ddsimpl/PerftestVersion.java index 1242b359..ea2d90b4 100644 --- a/srcJava/com/rti/perftest/ddsimpl/PerftestVersion.java +++ b/srcJava/com/rti/perftest/ddsimpl/PerftestVersion.java @@ -14,7 +14,7 @@ public final class PerftestVersion { private final ProductVersion_t _productVersion; private PerftestVersion() { - _productVersion = new ProductVersion_t(new int[] { 9, 9, 9, 9 }); + _productVersion = new ProductVersion_t(new int[] { 0, 0, 0, 0 }); } public static PerftestVersion getInstance() { From 1581174f90c840fc4cb362a54baa30215fdaa251 Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 4 Oct 2022 13:48:59 +0200 Subject: [PATCH 2/3] Add option to skip Zero-Copy libraries on non-windows systems --- build.sh | 8 ++++++++ srcDoc/compilation.rst | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/build.sh b/build.sh index c0dba754..cce63be6 100755 --- a/build.sh +++ b/build.sh @@ -178,6 +178,7 @@ function usage() echo " --flatData-max-size Specify the maximum bounded size on bytes " echo " for sequences when using FlatData language " echo " binding. Default 10MB " + echo " --no-zeroCopy Do not try to compile against Zero-Copy libs " echo " --osx-shmem-shmmax Maximum segment size for shared memory in OSX " echo " in bytes. Default 400MB " echo " --ns-resolution Try to use the system real-time clock to get " @@ -498,6 +499,10 @@ function additional_defines_calculation() additional_rtiddsgen_defines_flatdata=${additional_rtiddsgen_defines_flatdata}" -D RTI_FLATDATA_MAX_SIZE=${RTI_FLATDATA_MAX_SIZE}" fi + if [ "${SKIP_ZEROCOPY}" == "1" ]; then + export ZEROCOPY_AVAILABLE="0" + fi + if [ "${ZEROCOPY_AVAILABLE}" == "1" ]; then additional_rti_libs="nddsmetp ${additional_rti_libs}" additional_defines=${additional_defines}" DRTI_ZEROCOPY_AVAILABLE" @@ -1643,6 +1648,9 @@ while [ "$1" != "" ]; do --fastQueue) FAST_QUEUE=1 ;; + --no-zeroCopy) + SKIP_ZEROCOPY="1" + ;; *) echo -e "${ERROR_TAG} unknown parameter \"$1\"" usage diff --git a/srcDoc/compilation.rst b/srcDoc/compilation.rst index 84d2ed37..14f6aa9c 100644 --- a/srcDoc/compilation.rst +++ b/srcDoc/compilation.rst @@ -167,6 +167,11 @@ The ``build.sh`` script accepts the following list of parameters: - Optional - Specify the maximum size in bytes of the sample to be sent when using FlatData language binding. Default: 10485760 + * - ``--no-zeroCopy`` + - Optional + - Avoid adding the libraries and flags for Zero-Copy. This might be needed + if the compilation fails due to missing libraries (`nddsmetpz`). + Default: Not enabled. * - ``--secure`` - Optional - Enable the compilation of the Perfest code specific for security and adds the From 0e4fff48bac37ce4c25636cbbe0be9a6f3063ae7 Mon Sep 17 00:00:00 2001 From: Javier Morales-Castro Date: Tue, 4 Oct 2022 07:09:36 -0700 Subject: [PATCH 3/3] Pull request #54: Feature/ConnextTSS: Make perftest compatible with TSS Merge in PERF/rti-perftest from feature/ConnextTSS to develop Squashed commit of the following: commit 60a59c404f414f9fc16bac38f3efcd9cd9d6f00d Author: plombardero0 Date: Tue Oct 4 10:23:21 2022 +0200 ConnextTSS: Minor tweaks to building process commit 8fd81bb8d1af42e230ab5a379d4561275d39e27a Author: plombardero0 Date: Thu Sep 29 09:51:05 2022 +0200 ConnextTSS: Applying documentation feedback commit 960849b4bfc3cca4b4e946cdc43eb8680d8bb084 Author: plombardero0 Date: Wed Sep 28 15:52:46 2022 +0200 ConnextTSS: Modifying documentation to describe TSS support Minor changes for version string Old TODOs removed commit 557aa120fe183261360eec49c48a3a6076e3290a Author: Javier Date: Wed Sep 28 14:39:56 2022 +0200 Fix issue in documentation commit fd71cc3314e169653e4c2ca1bac4403fa66f66e2 Author: Javier Morales-Castro Date: Tue Sep 27 14:22:58 2022 +0200 Documentation changes for TSS (WIP-Pablo) commit e44c7ffea8c3f773fcfe7d99a4fe03dbe0919b0c Author: plombardero0 Date: Thu Sep 15 16:27:37 2022 +0200 ConnextTSS: removing logger for printing out error message commit 491dc47ac6c6eb933776913ee4315d18ddb520cc Author: plombardero0 Date: Wed Sep 7 13:19:14 2022 +0200 ConnextTSS: Fixing batching for Pro, relocating the generated binary so that it sits under bin/TSS instead of directly bin, fixing issues that impacted compilation with other implementations commit 4a854c0c18946014f68b3d14f0a37448fb1b4854 Author: Perfuser Date: Mon Sep 5 14:50:07 2022 +0000 Fix issue with PerftestSemaphore take where it would wait infinite time commit 76843c6aa413e25851ebd6096c8eb2419343d252 Author: plombardero0 Date: Thu Sep 1 12:09:22 2022 +0200 ConnextTSS: PR feedback applied commit 77d713e7342cf949b37760ce74b2ba24861880f6 Author: plombardero0 Date: Wed Aug 31 13:29:06 2022 +0200 ConnextTSS: Applying some PR feedback commit d98dfbec1ac4722b2a98f605b2c3a42f0ffcac5d Author: plombardero0 Date: Tue Aug 30 15:36:11 2022 +0200 ConnextTSS: Fixing how QoSs are applied commit 06b718cbea95199d5d2f3ab153a7c282205e2df4 Author: plombardero0 Date: Mon Aug 29 17:26:50 2022 +0200 ConnextTSS: Fixing bugs and TSS-related warnings commit 00befaeb47364788eed843f412d68b6d5e2293b2 Author: plombardero0 Date: Fri Aug 26 13:09:32 2022 +0200 ConnextTSS: Optimizing send commit 4755b468e4d9756c228984db12aabd9b0353eacc Author: plombardero0 Date: Fri Aug 26 12:53:46 2022 +0200 ConnextTSS: Adding TSS as another Middleware type and defining two ways of sending and receiving: loaning and not loaning (now the default) commit 507281458ac04595f8216f3a221d2dee50828626 Author: plombardero0 Date: Mon Aug 22 17:16:29 2022 +0200 ConnextTSS: Max buffer size for unbounded sequences fixed commit a6fe751c5df403afefc1b595ffcabd4bcfe6946f Author: plombardero0 Date: Mon Aug 22 16:53:27 2022 +0200 ConnextTSS: Fix to not set asynchronous publishing when not needed commit 67431a0cf41fd7d42ebf7c6284857aa067b21660 Author: plombardero0 Date: Mon Aug 22 16:07:33 2022 +0200 ConnextTSS: Communication between different machines using Micro fixed commit 621d942ad210c072c41e2b0679c0ec9809f16503 Author: plombardero0 Date: Tue Aug 2 14:42:29 2022 +0200 ConnextTSS: minor correction commit 931355274abe455515dc8d20d045b09c28ebc75a Author: plombardero0 Date: Tue Aug 2 13:49:28 2022 +0200 ConnextTSS: Fixing SHMEM communcation for Pro commit 6668bb00f2418f10ea1fddb74b6d64caa62ec27e Author: plombardero0 Date: Tue Aug 2 10:53:09 2022 +0200 ConnextTSS: Fixing allowInterfaces and peer, and implementing large data and unbounded sequences for Pro ... and 18 more commits --- .gitignore | 4 + .vscode/c_cpp_properties.json | 26 + build.sh | 117 +- resource/tss/CMakeLists.txt | 338 +++++ srcCpp/Infrastructure_common.cxx | 7 +- srcCpp/Infrastructure_common.h | 34 +- srcCpp/PerftestTransport.cxx | 3 +- srcCpp/PerftestTransport.h | 2 +- srcCpp/connextDDS/TSS/CustomConfiguration.hpp | 442 ++++++ srcCpp/connextDDS/TSS/CustomQosSupport.cpp | 756 ++++++++++ srcCpp/connextDDS/TSS/CustomQosSupport.hpp | 42 + srcCpp/connextDDS/TSS/RTITSSImpl.cxx | 1281 +++++++++++++++++ srcCpp/connextDDS/TSS/RTITSSImpl.h | 272 ++++ .../connextDDS/micro/Infrastructure_micro.cxx | 78 +- .../connextDDS/micro/Infrastructure_micro.h | 8 +- srcCpp/perftest_cpp.cxx | 134 +- srcCppCommon/Parameter.cxx | 11 +- srcCppCommon/Parameter.h | 3 + srcCppCommon/ParameterManager.cxx | 99 +- srcDoc/command_line_parameters.rst | 105 ++ srcDoc/compatibility.rst | 4 + srcDoc/compilation.rst | 60 +- srcDoc/index.rst | 2 + srcDoc/release_notes.rst | 23 + srcIdl/perftest.idl | 21 +- 25 files changed, 3773 insertions(+), 99 deletions(-) create mode 100644 resource/tss/CMakeLists.txt create mode 100644 srcCpp/connextDDS/TSS/CustomConfiguration.hpp create mode 100644 srcCpp/connextDDS/TSS/CustomQosSupport.cpp create mode 100644 srcCpp/connextDDS/TSS/CustomQosSupport.hpp create mode 100644 srcCpp/connextDDS/TSS/RTITSSImpl.cxx create mode 100644 srcCpp/connextDDS/TSS/RTITSSImpl.h diff --git a/.gitignore b/.gitignore index 104bc13a..e97ef500 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ /srcC*/perftestSupport.* /srcC*/perftest_publisher.* /srcC*/perftest_subscriber.* +/srcC*/perftest_TypeSupport.* +/srcC*/perftest_QosSupport.* +/srcC*/perftest_Config.* +/srcC*/perftest_TypedTS* /srcC*/makefile_* /srcC*/objs /srcCs/bin diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index c17cee79..c0a1aa98 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -150,6 +150,32 @@ "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "clang-x64" + }, + { + "name": "Linux TSS C++", + "includePath": [ + "${workspaceFolder}/srcCpp/", + "${workspaceFolder}/srcCppCommon/", + "${workspaceFolder}/srcCpp/connextDDS", + "${workspaceFolder}/srcCpp/connextDDS/TSS", + "${env.NDDSHOME}/include", + "${env.NDDSHOME}/include/ndds", + "${env.NDDSHOME}/include/ndds/hpp", + "${env.RTIMEHOME}/include/", + "${env.RTITSSHOME}/include", + "${env.RTITSSHOME}/include/*" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE", + "RTI_PERF_TSS", + "RTI_PERF_TSS_PRO", + "PERFTEST_RTI_MICRO_24x_COMPATIBILITY" + ], + "intelliSenseMode": "${default}", + "cStandard": "c11", + "cppStandard": "c++11" } ], "version": 4 diff --git a/build.sh b/build.sh index cce63be6..01c7bd53 100755 --- a/build.sh +++ b/build.sh @@ -19,6 +19,12 @@ cStringifyFile_script="${script_location}/resource/scripts/cStringifyFile.pl" qos_file="${script_location}/perftest_qos_profiles.xml" doc_folder="${script_location}/srcDoc" generate_doc_folder="${script_location}/doc" +resource_folder="${script_location}/resource" + +# By default we will not build TSS with Pro libs +BUILD_TSS=0 +BUILD_TSS_PRO=0 +FACE_COMPLIANCE="None" # By default we will build pro, not micro BUILD_MICRO=0 @@ -185,6 +191,9 @@ function usage() echo " nano-second resolution. " echo " For the Classic C++ Implementation only. " echo " Default is not enabled. " + echo " --tss Build against Connext TSS (pro and micro) " + echo " For the Classic C++ Implementation only. " + echo " Default is not enabled. " echo " --help -h Display this message. " echo " " echo "================================================================================" @@ -257,7 +266,22 @@ function executable_checking() fi # If we are Building MICRO - if [ "${BUILD_MICRO}" -eq "1" ]; then + if [ "${BUILD_TSS}" -eq "1" ]; then + if [ -z "${RTITSSHOME}" ]; then + echo -e "${ERROR_TAG} The RTITSSHOME variable is not set or the path does not exist" + usage + exit -1 + elif [ "${BUILD_TSS_PRO}" -eq "1" ] && [ -z "${NDDSHOME}" ]; then + echo -e "${ERROR_TAG} The NDDSHOME variable is not set or the path does not exist" + usage + exit -1 + elif [ "${BUILD_MICRO}" -eq "1" ] && [ -z "${RTIMEHOME}" ]; then + echo -e "${ERROR_TAG} The RTIMEHOME variable is not set or the path does not exist" + usage + exit -1 + fi + + elif [ "${BUILD_MICRO}" -eq "1" ]; then # Is RTIMEHOME set? if [ -z "${RTIMEHOME}" ]; then @@ -286,6 +310,7 @@ function executable_checking() echo -e "${WARNING_TAG} ${MAKE_EXE} executable not found, perftest_cpp will not be built." fi fi + else # If building pro # Is NDDSHOME set? @@ -372,7 +397,7 @@ function executable_checking() BUILD_CS=0 fi - fi #Micro/Pro + fi #TSS/Micro/Pro } @@ -411,9 +436,9 @@ function additional_defines_calculation() # Avoid optimized out variables when debugging if [ "${RELEASE_DEBUG}" == "release" ]; then echo -e "${INFO_TAG} C++ code will be optimized." - additional_defines=${additional_defines}"O3" + additional_defines=${additional_defines}" O3" else - additional_defines=${additional_defines}"O0" + additional_defines=${additional_defines}" O0" fi if [ "${LEGACY_DD_IMPL}" == "1" ]; then @@ -1074,6 +1099,68 @@ function build_micro_cpp() fi } +function build_tss_cpp() +{ + copy_src_cpp_common + + ############################################################################## + # Generate files for the custom type files + additional_defines_custom_type="" + additional_header_files_custom_type="" + additional_source_files_custom_type="" + + if [ "${USE_CUSTOM_TYPE}" == "1" ]; then + build_cpp_custom_type + fi + + if [ "${BUILD_MICRO}" == "1" ]; then + TSS_IMPL="micro" + else + additional_defines_calculation "CppTraditional" + TSS_IMPL="pro" + fi + + additional_defines=${additional_defines}" DRTI_PERF_TSS" + + cp "${resource_folder}/tss/CMakeLists.txt" \ + "${classic_cpp_folder}/CMakeLists.txt" + + ############################################################################## + # Compile srcCpp code + echo "" + echo -e "${INFO_TAG} Compiling perftest_cpp" + cd "${classic_cpp_folder}" + + cmake_generate_command="RTITSSARCH=${platform} ${CMAKE_EXE} \ + -DRTI_CONNEXT_TYPE=${TSS_IMPL} \ + -DRTI_TSS_ENABLE_FACE_COMPLIANCE=${FACE_COMPLIANCE} \ + -DCMAKE_BUILD_TYPE=${RELEASE_DEBUG} \ + -G \"Unix Makefiles\" \ + -B./perftest_build -H." + + echo -e "${INFO_TAG} Cmake Generate Command: $cmake_generate_command" + eval $cmake_generate_command + if [ "$?" != 0 ]; then + echo -e "${ERROR_TAG} Failure generating makefiles with cmake for ${classic_cpp_lang_string}." + cd .. + exit -1 + fi + + cmake_build_command="${CMAKE_EXE} --build ./perftest_build --config ${RELEASE_DEBUG}" + echo -e "${INFO_TAG} Cmake Build Command: $cmake_build_command" + eval $cmake_build_command + if [ "$?" != 0 ]; then + echo -e "${ERROR_TAG} Failure compiling code for ${classic_cpp_lang_string}." + cd .. + exit -1 + fi + + echo -e "${INFO_TAG} Compilation successful" + cd .. + + clean_copied_files +} + function build_cpp11() { copy_src_cpp_common @@ -1471,6 +1558,13 @@ while [ "$1" != "" ]; do clean exit ;; + --tss) + BUILD_TSS=1 + ;; + --face-profile) + FACE_COMPLIANCE=$2 + shift + ;; --micro) BUILD_MICRO=1 ;; @@ -1660,9 +1754,22 @@ while [ "$1" != "" ]; do shift done +if [ "${BUILD_TSS}" -eq "1" ] && [ "${BUILD_MICRO}" -eq "0" ]; then + BUILD_TSS_PRO=1 +fi + executable_checking -if [ "${BUILD_MICRO}" -eq "1" ]; then +if [ "${BUILD_TSS}" -eq "1" ]; then + rtiddsgen_executable="$RTITSSHOME/bin/rtiddsgen" + classic_cpp_lang_string=FACEC++ + + if [ "${BUILD_CPP}" -eq "1" ]; then + library_sufix_calculation + build_tss_cpp + fi + +elif [ "${BUILD_MICRO}" -eq "1" ]; then rtiddsgen_executable="$RTIMEHOME/rtiddsgen/scripts/rtiddsgen" diff --git a/resource/tss/CMakeLists.txt b/resource/tss/CMakeLists.txt new file mode 100644 index 00000000..3ec776dd --- /dev/null +++ b/resource/tss/CMakeLists.txt @@ -0,0 +1,338 @@ +############################################################################### +# (c) Copyright, Real-Time Innovations 2018-2022 +# +# All rights reserved. +# No duplications, whole or partial, manual or electronic, may be made +# without express written permission. Any such copies, or +# revisions thereof, must display this notice unaltered. +# This code contains trade secrets of Real-Time Innovations, Inc. +# +# Description: +# ------------ +# CMakeLists.txt for building perftest with Connext DDS Pro or Micro +# +################################################################################ + +cmake_minimum_required(VERSION 3.8) +cmake_policy(SET CMP0048 NEW) # Support VERSION in project +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) # Support *_ROOT variables +endif() + +# Build configuration variables. To overwrite the default value, run cmake with +# -Dvar=value. These two variables must be before the project call since +# toolchains need them. +# option(BUILD_SHARED_LIBS "Libraries type; TRUE for shared, FALSE for static" FALSE) +set(CMAKE_BUILD_TYPE "debug" CACHE STRING "Build type: 'Debug' or 'Release'") +option(RTI_REPLACE_GEN "Replace generated source? TRUE to replace, FALSE to keep" TRUE) + +set (CMAKE_CXX_STANDARD 11) + +set(RTI_CONNEXT_PRO_TYPE "pro") +set(RTI_CONNEXT_MICRO_TYPE "micro") + +set(RTI_CONNEXT_TYPE ${RTI_CONNEXT_MICRO_TYPE} CACHE STRING "Connext DDS product type: 'pro' or 'micro'") +set_property(CACHE RTI_CONNEXT_TYPE PROPERTY STRINGS + ${RTI_CONNEXT_PRO_TYPE} + ${RTI_CONNEXT_MICRO_TYPE}) + +set(RTI_TSS_MICRO_2_4_11_1_SUPPORT FALSE CACHE BOOL "Set to TRUE if compiling against Micro 2.4.11.1") + +# Prerequisite environment variables +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_PRO_TYPE}) + if (NOT DEFINED ENV{NDDSHOME}) + message(FATAL_ERROR "[RTI] NDDSHOME is not set. Please set to Connext DDS Pro installation directory.") + endif() + + file(TO_CMAKE_PATH "$ENV{NDDSHOME}" CONNEXTHOME) + file(TO_CMAKE_PATH "$ENV{NDDSHOME}" NDDSHOME) + set(NDDSHOME $ENV{NDDSHOME}) + set(RTIDDSGEN_OPTS "") +else() + if (NOT DEFINED ENV{RTIMEHOME}) + message(FATAL_ERROR "[RTI] RTIMEHOME is not set. Please set to Connext DDS Micro installation directory.") + endif() + + file(TO_CMAKE_PATH "$ENV{RTIMEHOME}" CONNEXTHOME) + file(TO_CMAKE_PATH "$ENV{RTIMEHOME}" RTIMEHOME) + set(RTIDDSGEN_OPTS "-micro") + add_definitions(-DRTI_CONNEXT_MICRO) +endif() + +if (NOT DEFINED RTITSSHOME) + if (NOT DEFINED ENV{RTITSSHOME}) + message(FATAL_ERROR "[RTI] RTITSSHOME is not set. Please set to Connext TSS installation directory") + endif() + + file(TO_CMAKE_PATH "$ENV{RTITSSHOME}" RTITSSHOME) +endif() + +if (NOT DEFINED RTI_TSS_PLATFORM) + if (NOT DEFINED ENV{RTITSSARCH}) + message(FATAL_ERROR "[RTI] RTITSSARCH is not set. Please set to the name of the platform architecture (e.g. x64Linux3gcc4.8.2).") + endif() + + file(TO_CMAKE_PATH "$ENV{RTITSSARCH}" RTI_TSS_PLATFORM) +endif() + +# Pro Platform architecture must be set in NDDSARCH environment variable +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_PRO_TYPE}) + if(NOT DEFINED RTI_NDDS_ARCH) + if(NOT DEFINED ENV{NDDSARCH}) + message(Warning "[RTI] Pro Architecture not specified. Please define a CMake variable RTI_NDDS_ARCH or + set environment variable NDDSARCH to use a specific Pro Architecture. Setting Pro Architecture to RTITSSARCH.") + set(RTIPROARCH ${RTI_TSS_PLATFORM}) + else() + set(RTIPROARCH $ENV{NDDSARCH}) + endif() + else() + set(RTIPROARCH ${RTI_NDDS_ARCH}) + endif() +endif() + +#Micro Platform architecture must be set in RTIMEARCH environment variable +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_MICRO_TYPE}) + if(NOT DEFINED RTI_ME_ARCH) + if(NOT DEFINED ENV{RTIMEARCH}) + message(Warning "[RTI] Micro Architecture not specified. Please define a CMake variable RTI_ME_ARCH or + set environment variable RTIMEARCH to use a specific Micro Architecture. Setting Micro Architecture to RTITSSARCH.") + set(RTIMEARCH ${RTI_TSS_PLATFORM}) + else() + set(RTIMEARCH $ENV{RTIMEARCH}) + endif() + else() + set(RTIMEARCH ${RTI_ME_ARCH}) + endif() +endif() + +set(DDSGENHOME ${RTITSSHOME}) + +# We need to setup the module path before 'project()' loads any file. +list(APPEND CMAKE_MODULE_PATH "${RTITSSHOME}/resource/cmake/Modules") +list(APPEND CMAKE_MODULE_PATH "${RTITSSHOME}/resource/cmake/Toolchains") + +# Toolchain (host or cross-compilation) is included if available +set(RTI_TSS_ARCH_TOOLCHAIN + ${RTITSSHOME}/resource/cmake/Toolchains/Architecture/${RTI_TSS_PLATFORM}.cmake) + + +include(${RTI_TSS_ARCH_TOOLCHAIN} OPTIONAL RESULT_VARIABLE FOUND_TOOLCHAIN) +if (FOUND_TOOLCHAIN) + message(STATUS "[RTI] Included toolchain ......: ${FOUND_TOOLCHAIN}") +endif() + + +# Support only C and C++ +set(project_langs C CXX) + + +project(perftest + LANGUAGES ${project_langs}) + + +include(ConnextTss) + +# Toolchain for this platform +include(Architecture/${RTI_TSS_PLATFORM} OPTIONAL) + +message(STATUS "[RTI] RTI_CONNEXT_TYPE ................: ${RTI_CONNEXT_TYPE}") +message(STATUS "[RTI] RTITSSHOME ......................: ${RTITSSHOME}") +message(STATUS "[RTI] CONNEXTHOME .....................: ${CONNEXTHOME}") +message(STATUS "[RTI] CMAKE_BUILD_TYPE ................: ${CMAKE_BUILD_TYPE}") +message(STATUS "[RTI] PLATFORM_ARCH ...................: ${RTI_TSS_PLATFORM}") +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_PRO_TYPE}) + message(STATUS "[RTI] PRO_PLATFORM_ARCH ...............: ${RTIPROARCH}") +endif() +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_MICRO_TYPE}) + message(STATUS "[RTI] MICRO_PLATFORM_ARCH .............: ${RTIMEARCH}") +endif() +message(STATUS "[RTI] RTI_TSS_ENABLE_FACE_COMPLIANCE...: ${RTI_TSS_ENABLE_FACE_COMPLIANCE}") +message(STATUS "[RTI] RTI_REPLACE_GEN..................: ${RTI_REPLACE_GEN}") + +# External libraries + +if(NOT WIN32) +set(LIB_PREFIX "lib") +endif() + +# Connext Pro +set(nddscore_lib ${LIB_PREFIX}nddscore) +set(nddsc_lib ${LIB_PREFIX}nddsc) +set(nddscpp_lib ${LIB_PREFIX}nddscpp) +# Connext Micro +set(rtime_lib ${LIB_PREFIX}rti_me) +set(rtime_rh_lib ${LIB_PREFIX}rti_me_rhsm) +set(rtime_wh_lib ${LIB_PREFIX}rti_me_whsm) +set(rtime_dpde_lib ${LIB_PREFIX}rti_me_discdpde) +set(rtime_dpse_lib ${LIB_PREFIX}rti_me_discdpse) +set(rtime_cpp_lib ${LIB_PREFIX}rti_me_cpp) +# Connext TSS +set(rtitss_lib ${LIB_PREFIX}rti_tsscpp) + +# Link libs +set(ndds_libs_dir ${NDDSHOME}/lib/${RTIPROARCH}) +set(rtime_libs_dir ${RTIMEHOME}/lib/${RTIMEARCH}) +set(rtitss_libs_dir ${RTITSSHOME}/lib/${RTI_TSS_PLATFORM}/${RTI_CONNEXT_TYPE}) + +# static libs only +if(CMAKE_BUILD_TYPE MATCHES "release") +if(WIN32) + set(LIB_SUFFIX "z.lib") +else() + set(LIB_SUFFIX "z.a") +endif() +else() +if(WIN32) + set(LIB_SUFFIX "zd.lib") +else() + set(LIB_SUFFIX "zd.a") +endif() +endif() + + +# Includes +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_PRO_TYPE}) + list(APPEND RTITSS_INC_DIRS ${RTITSSHOME}/include + ${RTITSSHOME}/include/pro) + list(APPEND CONNEXT_INC_DIRS ${NDDSHOME}/include + ${NDDSHOME}/include/ndds) +else() + list(APPEND RTITSS_INC_DIRS ${RTITSSHOME}/include + ${RTITSSHOME}/include/micro) + list(APPEND CONNEXT_INC_DIRS ${RTIMEHOME}/include + ${RTIMEHOME}/include/rti_me) +endif() + +SET(GEN_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../srcCpp/gen) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS/pro + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS/micro + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS/TSS + ${GEN_OUTPUT_DIR} + ${CONNEXT_INC_DIRS} + ${RTITSS_INC_DIRS}) + +# Generated source for user data type +set(rtiddsgen_cmd ${RTITSSHOME}/bin/rtiddsgen) + +MESSAGE(STATUS "[RTI] rtiddsgen_cmd: ${rtiddsgen_cmd}") + +if (RTI_REPLACE_GEN) + set(REPLACE_GEN "-replace") +else() + set(REPLACE_GEN "") +endif() + +set(PERF_GEN_IDL ${CMAKE_CURRENT_SOURCE_DIR}/../srcIdl/perftest.idl) + +set(PERF_GEN_SRC ${GEN_OUTPUT_DIR}/perftest.cxx + ${GEN_OUTPUT_DIR}/perftestSupport.cxx + ${GEN_OUTPUT_DIR}/perftestPlugin.cxx) + +set(PERF_GEN_HEADERS ${GEN_OUTPUT_DIR}/perftest.h + ${GEN_OUTPUT_DIR}/perftest.hpp + ${GEN_OUTPUT_DIR}/perftestSupport.h + ${GEN_OUTPUT_DIR}/perftestPlugin.h + ${GEN_OUTPUT_DIR}/FACE/DM/TestData_t/TypedTS_Impl.hpp + ${GEN_OUTPUT_DIR}/FACE/DM/TestDataLarge_t/TypedTS_Impl.hpp + ${GEN_OUTPUT_DIR}/FACE/DM/TestDataKeyed_t/TypedTS_Impl.hpp + ${GEN_OUTPUT_DIR}/FACE/DM/TestDataKeyedLarge_t/TypedTS_Impl.hpp + ${GEN_OUTPUT_DIR}/perftest_TSSConfigInterface.hpp) + +list(APPEND PERF_CONFIG_SRC ${GEN_OUTPUT_DIR}/perftest_TSSQosSupport.cpp) + +list(APPEND PERF_GEN_TYPE_SRC + ${GEN_OUTPUT_DIR}/FACE/DM/TestData_t/TypedTS_Impl.cpp + ${GEN_OUTPUT_DIR}/FACE/DM/TestDataLarge_t/TypedTS_Impl.cpp + ${GEN_OUTPUT_DIR}/FACE/DM/TestDataKeyed_t/TypedTS_Impl.cpp + ${GEN_OUTPUT_DIR}/FACE/DM/TestDataKeyedLarge_t/TypedTS_Impl.cpp) + +add_definitions(-DFACE_SEQUENCE_AND_STRING_IMPLEMENTED=TRUE) +add_definitions(-DFACE_SEQUENCE_AND_STRING_SERIALIZABLE=TRUE) + +# Connext TSS and DDS plugin generation +ADD_CUSTOM_COMMAND(OUTPUT ${PERF_GEN_SRC} ${PERF_CONFIG_SRC} ${PERF_GEN_TYPE_SRC} ${PERF_GEN_HEADERS} ${PERF_DISC_SRC} + nonexistentFileToForceThisCmd + COMMAND ${CMAKE_COMMAND} -E make_directory ${GEN_OUTPUT_DIR} + COMMAND ${rtiddsgen_cmd} -d ${GEN_OUTPUT_DIR} + -I ${RTITSSHOME}/include -D RTI_PERF_TSS + ${REPLACE_GEN} ${RTIDDSGEN_OPTS} -language FACEC++ ${PERF_GEN_IDL} + COMMENT "Running rtiddsgen (FACEC++) for ${PERF_GEN_IDL}" + DEPENDS ${PERF_GEN_IDL}) + +#Additional files to be copied +list(APPEND TSS_INFRASTRUCTURE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS/TSS/CustomQosSupport.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS/TSS/RTITSSImpl.cxx) + +# perftest application +list(APPEND PERF_APP_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/perftest_cpp.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/ThreadPriorities.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/Parameter.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/ParameterManager.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/CpuMonitor.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/PerftestTransport.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/connextDDS/${RTI_CONNEXT_TYPE}/Infrastructure_${RTI_CONNEXT_TYPE}.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/Infrastructure_common.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/FileDataLoader.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/PerftestPrinter.cxx + ${TSS_INFRASTRUCTURE_FILES} + ${PERF_CONFIG_SRC} + ${PERF_GEN_SRC} + ${PERF_GEN_TYPE_SRC} + ${PERF_DISC_SRC}) + +set(APP_NAME perftest_cpp_tss_${RTI_CONNEXT_TYPE}) +add_executable(${APP_NAME} ${PERF_APP_SRC}) + +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_PRO_TYPE}) + # add_definitions( -DPERFTEST_RTI_PRO ) + add_definitions( -DRTI_PERF_TSS_PRO ) +else() + # add_definitions(-DPERFTEST_RTI_MICRO ) + add_definitions( -DRTI_PERF_TSS_MICRO ) +endif() + +add_definitions( -DRTI_LANGUAGE_CPP_TRADITIONAL -O0 -DRTI_PERF_TSS -DRTI_USE_CPP_11_INFRASTRUCTURE) + +if(${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_MICRO_TYPE}) + add_definitions( -DPERFTEST_RTI_MICRO_24x_COMPATIBILITY ) +endif() + +if (${RTI_CONNEXT_TYPE} MATCHES ${RTI_CONNEXT_PRO_TYPE}) + target_link_libraries(${APP_NAME} + PRIVATE ${rtitss_libs_dir}/${rtitss_lib}${LIB_SUFFIX} + ${ndds_libs_dir}/${nddscpp_lib}${LIB_SUFFIX} + ${ndds_libs_dir}/${nddsc_lib}${LIB_SUFFIX} + ${ndds_libs_dir}/${nddscore_lib}${LIB_SUFFIX} + ${SYSLIBS_ARCH}) +elseif (((${RTI_TSS_ENABLE_FACE_COMPLIANCE} MATCHES "SafetyBase") OR + (${RTI_TSS_ENABLE_FACE_COMPLIANCE} MATCHES "Security")) AND + NOT ${RTI_TSS_MICRO_2_4_11_1_SUPPORT}) + target_link_libraries(${APP_NAME} + PRIVATE ${rtitss_libs_dir}/${rtitss_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_lib}${LIB_SUFFIX} + ${SYSLIBS_ARCH}) +else() + target_link_libraries(${APP_NAME} + PRIVATE ${rtitss_libs_dir}/${rtitss_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_rh_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_wh_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_dpde_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_dpse_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_lib}${LIB_SUFFIX} + ${rtime_libs_dir}/${rtime_cpp_lib}${LIB_SUFFIX} + ${SYSLIBS_ARCH}) +endif() + +target_compile_options(${APP_NAME} PRIVATE -fexceptions) + +set(APP_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../bin/TSS/${RTI_TSS_PLATFORM}/${RTI_CONNEXT_TYPE}/${CMAKE_BUILD_TYPE}) +add_custom_command(TARGET ${APP_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${APP_OUTPUT_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${APP_OUTPUT_DIR} + COMMENT "Copying application to ${APP_OUTPUT_DIR} ...") diff --git a/srcCpp/Infrastructure_common.cxx b/srcCpp/Infrastructure_common.cxx index c4ec5daa..bb112a5d 100644 --- a/srcCpp/Infrastructure_common.cxx +++ b/srcCpp/Infrastructure_common.cxx @@ -46,7 +46,7 @@ bool PerftestSemaphore_give(PerftestSemaphore* semaphore) bool PerftestSemaphore_take(PerftestSemaphore* semaphore, int timeout) { - return semaphore->take(); + return semaphore->take(timeout); } /********************************************************************/ @@ -115,7 +115,7 @@ void PerftestClock::sleep(const struct DDS_Duration_t& sleep_period) NDDSUtility::sleep(sleep_period); } -#if !defined(PERFTEST_RTI_MICRO) && !defined(PERFTEST_RTI_PRO) +#if !defined(PERFTEST_RTI_MICRO) && !defined(PERFTEST_RTI_PRO) && !defined(RTI_PERF_TSS_PRO) void NDDSUtility::sleep(const struct DDS_Duration_t &durationIn) { std::this_thread::sleep_for( @@ -166,7 +166,8 @@ NDDSUtility::get_spin_per_microsecond(unsigned int precision) return (unsigned long long) (iterations * spinCount) / usec; } -#endif //#if !defined(PERFTEST_RTI_MICRO) && !defined(PERFTEST_RTI_PRO) +#endif //#if !defined(PERFTEST_RTI_MICRO) && !defined(PERFTEST_RTI_PRO) && + // !defined(RTI_PERF_TSS_PRO) /********************************************************************/ /* Perftest Thread class */ diff --git a/srcCpp/Infrastructure_common.h b/srcCpp/Infrastructure_common.h index c5b73dfa..a0ec8e69 100644 --- a/srcCpp/Infrastructure_common.h +++ b/srcCpp/Infrastructure_common.h @@ -8,6 +8,8 @@ #if defined(PERFTEST_RTI_PRO) || defined(PERFTEST_RTI_MICRO) #include "perftest.h" +#elif defined(RTI_PERF_TSS) + #include "gen/perftest.h" #endif #include #include @@ -15,6 +17,10 @@ #include #include +#ifdef RTI_PERF_TSS_PRO + #include "ndds/ndds_cpp.h" +#endif + #ifdef RTI_VXWORKS #include #include @@ -48,9 +54,9 @@ * implementation for these classes. */ -#ifdef PERFTEST_RTI_PRO +#if defined(PERFTEST_RTI_PRO) || defined(RTI_PERF_TSS_PRO) #include "Infrastructure_pro.h" -#elif PERFTEST_RTI_MICRO +#elif defined(PERFTEST_RTI_MICRO) || defined(RTI_PERF_TSS_MICRO) #include "Infrastructure_micro.h" #endif @@ -67,10 +73,14 @@ * generated variable for a string is different. We need to move it to a generic * place and remove it from here in the future. */ -#if !defined(PERFTEST_RTI_PRO) && !defined(PERFTEST_RTI_MICRO) +#if !defined(PERFTEST_RTI_PRO) && !defined(PERFTEST_RTI_MICRO) && !defined(RTI_PERF_TSS) static const char *const THROUGHPUT_TOPIC_NAME = "Throughput"; static const char *const LATENCY_TOPIC_NAME = "Latency"; static const char *const ANNOUNCEMENT_TOPIC_NAME = "Announcement"; +#elif defined(RTI_PERF_TSS) +static const char *const THROUGHPUT_TOPIC_NAME = THROUGHPUT_TOPIC_NAME_STRING.buffer(); +static const char *const LATENCY_TOPIC_NAME = LATENCY_TOPIC_NAME_STRING.buffer(); +static const char *const ANNOUNCEMENT_TOPIC_NAME = ANNOUNCEMENT_TOPIC_NAME_STRING.buffer(); #endif @@ -105,6 +115,20 @@ class PerftestSemaphore { } } + bool take(int timeout_millisec) + { + try { + std::chrono::milliseconds timeout(timeout_millisec); + std::unique_lock lock(mutex); + condition.wait_for(lock, timeout, [&]() -> bool { return count > 0; }); + --count; + return true; + } catch (std::exception& e) { + std::cerr << "[Exception]: "<< e.what() << std::endl; + return false; + } + } + bool give() { try { @@ -170,12 +194,14 @@ PerftestThread *PerftestThread_new( void PerftestThread_delete(PerftestThread *thread); -#if !defined(PERFTEST_RTI_PRO) && !defined(PERFTEST_RTI_MICRO) +#if !defined(PERFTEST_RTI_PRO) && !defined(PERFTEST_RTI_MICRO) && !defined(RTI_PERF_TSS) struct DDS_Duration_t { int sec; unsigned int nanosec; }; +#endif +#if !defined(PERFTEST_RTI_PRO) && !defined(PERFTEST_RTI_MICRO) && !defined(RTI_PERF_TSS_PRO) class NDDSUtility { public: /*e \dref_Utility_sleep */ diff --git a/srcCpp/PerftestTransport.cxx b/srcCpp/PerftestTransport.cxx index 5d037b10..56e7eee4 100644 --- a/srcCpp/PerftestTransport.cxx +++ b/srcCpp/PerftestTransport.cxx @@ -11,7 +11,8 @@ PerftestTransport::PerftestTransport() { - multicastAddrMap[LATENCY_TOPIC_NAME] = TRANSPORT_MULTICAST_ADDR_LATENCY; + multicastAddrMap[LATENCY_TOPIC_NAME] = + TRANSPORT_MULTICAST_ADDR_LATENCY; multicastAddrMap[ANNOUNCEMENT_TOPIC_NAME] = TRANSPORT_MULTICAST_ADDR_ANNOUNCEMENT; multicastAddrMap[THROUGHPUT_TOPIC_NAME] = diff --git a/srcCpp/PerftestTransport.h b/srcCpp/PerftestTransport.h index 79939b72..aa6a6b8d 100644 --- a/srcCpp/PerftestTransport.h +++ b/srcCpp/PerftestTransport.h @@ -28,7 +28,7 @@ * TODO: that Encapsulation should be taken out from the sample instead of here. */ -#ifdef PERFTEST_RTI_PRO +#if defined(PERFTEST_RTI_PRO) || defined(RTI_PERF_TSS_PRO) #define TMP_COMMEND_WRITER_MAX_RTPS_OVERHEAD 512 #define MESSAGE_OVERHEAD_BYTES (TMP_COMMEND_WRITER_MAX_RTPS_OVERHEAD + 48 + RTI_CDR_ENCAPSULATION_HEADER_SIZE + 3) #else diff --git a/srcCpp/connextDDS/TSS/CustomConfiguration.hpp b/srcCpp/connextDDS/TSS/CustomConfiguration.hpp new file mode 100644 index 00000000..4628024f --- /dev/null +++ b/srcCpp/connextDDS/TSS/CustomConfiguration.hpp @@ -0,0 +1,442 @@ + +/******************************************************************************* + * Copyright (c) 2018-2021 Real-Time Innovations, Inc. All rights reserved. + * + * No duplications, whole or partial, manual or electronic, may be made + * without express written permission. Any such copies, or revisions thereof, + * must display this notice unaltered. + * This code contains trade secrets of Real-Time Innovations, Inc. + *******************************************************************************/ + +#ifndef CUSTOM_CONFIGURATION_HPP +#define CUSTOM_CONFIGURATION_HPP + +#include + +#include "gen/perftest_TSSConfigInterface.hpp" + +#include "Infrastructure_common.h" +#include "ParameterManager.h" +#include "gen/perftest.h" + +/** CustomConfiguration is an extension of the generated Configuration. + * This allows customization of the configuration without creating an entirely + * new config. + * */ +class CustomConfiguration : public RTI::perftest::Configuration +{ + public: + CustomConfiguration() + {} + + CustomConfiguration(const char* type_name) + { + _type_name = type_name; + } + + void Initialize( + const FACE::Configuration::INITIALIZATION_TYPE + &initialization_information, + FACE::RETURN_CODE_TYPE::Value &return_code) + { + UNUSED_ARG(initialization_information); + + if (_initialized) + { + return_code = FACE::RETURN_CODE_TYPE::NO_ERROR; + return; + } + + if (!_populate_type_support_config()) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_CONFIG; + return; + } + + if (!_populate_system_config() || + !_populate_custom_connection_config() || + !_populate_custom_domain_config()) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_CONFIG; + return; + } + + _initialized = DDS_BOOLEAN_TRUE; + return_code = FACE::RETURN_CODE_TYPE::NO_ERROR; + } + + void Read(FACE::Configuration::HANDLE_TYPE handle, + const FACE::Configuration::SET_NAME_TYPE &set_name, + FACE::SYSTEM_ADDRESS_TYPE buffer, + FACE::Configuration::BUFFER_SIZE_TYPE buffer_size, + FACE::Configuration::BUFFER_SIZE_TYPE &bytes_read, + FACE::RETURN_CODE_TYPE::Value &return_code) + { + const char *set_name_ptr = NULL; + + UNUSED_ARG(buffer_size); + + if (buffer == NULL) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_PARAM; + return; + } + + if (!_initialized) + { + return_code = FACE::RETURN_CODE_TYPE::NOT_AVAILABLE; + return; + } + + #ifdef FACE_SEQUENCE_AND_STRING_IMPLEMENTED + set_name_ptr = set_name.buffer(); + #else + set_name_ptr = set_name; + #endif + + if (handle == system_configurations_handle) + { + RTI_TSS_System_Configuration_T **sys_config = + (RTI_TSS_System_Configuration_T**) buffer; + + if (!_get_system_config(sys_config, set_name_ptr)) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_CONFIG; + return; + } + + bytes_read = sizeof(void*); + } + else if (handle == domain_configurations_handle) + { + RTI_TSS_DDS_DomainParticipant_Configuration_T **domain_config = + (RTI_TSS_DDS_DomainParticipant_Configuration_T**) buffer; + + if (!_get_domain_config(domain_config, set_name_ptr)) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_CONFIG; + return; + } + + bytes_read = sizeof(void*); + } + else if (handle == type_support_configurations_handle) + { + RTI_TSS_TypeSupport_Configuration_T **type_config = + (RTI_TSS_TypeSupport_Configuration_T**) buffer; + + if (!_get_type_config(type_config, set_name_ptr)) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_CONFIG; + return; + } + + bytes_read = sizeof(void*); + } + else if (handle == connection_configurations_handle) + { + RTI_TSS_Connection_Configuration_T **connection_config = + (RTI_TSS_Connection_Configuration_T**) buffer; + + if (!_custom_get_connection_config(connection_config, set_name_ptr)) + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_CONFIG; + return; + } + + bytes_read = sizeof(void*); + } + else + { + return_code = FACE::RETURN_CODE_TYPE::INVALID_PARAM; + return; + } + + return_code = FACE::RETURN_CODE_TYPE::NO_ERROR; + } + + private: + + FACE::Boolean _populate_custom_system_config() + { + if (!RTI_TSS_System_Configuration_initialize(&_system_configurations[0])) + { + return false; + } + _system_configurations[0].config_name = "perftest"; + _system_configurations[0].configure_domain_participant_factory_qos_fn = FACE_DM_TestData_t_participant_factory_qos; + +#ifdef RTI_PERF_TSS_MICRO + _system_configurations[0].max_connections = 32; + _system_configurations[0].max_topics = _connection_configurations_length / 2; + + _system_configurations[0].components_length = 4; + int i = 3; + + _system_configurations[0].components = + new RTI_TSS_Micro_Component_T[_system_configurations[0].components_length]; + + // Writer History Component + if (!RTI_TSS_Micro_Component_initialize(&_system_configurations[0].components[0])) + { + return false; + } + _system_configurations[0].components[0].name = DDSHST_WRITER_DEFAULT_HISTORY_NAME; + _system_configurations[0].components[0].component = WHSM_HistoryFactory_get_interface(); + _system_configurations[0].components[0].listener = NULL; + _system_configurations[0].components[0].property = NULL; + + // Reader History Component + if (!RTI_TSS_Micro_Component_initialize(&_system_configurations[0].components[1])) + { + return false; + } + _system_configurations[0].components[1].name = DDSHST_READER_DEFAULT_HISTORY_NAME; + _system_configurations[0].components[1].component = RHSM_HistoryFactory_get_interface(); + _system_configurations[0].components[1].listener = NULL; + _system_configurations[0].components[1].property = NULL; + + #if !FACE_COMPLIANCE_LEVEL_SAFETY_BASE_OR_STRICTER + // DPDE Component + struct DPDE_DiscoveryPluginProperty *dpde_properties = + (struct DPDE_DiscoveryPluginProperty*) malloc( + sizeof(struct DPDE_DiscoveryPluginProperty)); + + if (DPDE_DiscoveryPluginProperty_initialize(dpde_properties) != DDS_RETCODE_OK) + { + printf("Failed to Initialize DPDE properties"); + return false; + } + + if (!RTI_TSS_Micro_Component_initialize(&_system_configurations[0].components[i])) + { + return false; + } + _system_configurations[0].components[i].name = "dpde"; + _system_configurations[0].components[i].component = DPDE_DiscoveryFactory_get_interface(); + _system_configurations[0].components[i].listener = NULL; + _system_configurations[0].components[i].property = + (struct RT_ComponentFactoryProperty*) dpde_properties; + i++; +#endif /* !FACE_COMPLIANCE_LEVEL_SAFETY_BASE_OR_STRICTER */ + +#if !EXCLUDE_UDP + + // UDP Component + if (!RTI_TSS_Micro_Component_initialize(&_system_configurations[0].components[i])) + { + return false; + } + _system_configurations[0].components[i].name = NETIO_DEFAULT_UDP_NAME; + _system_configurations[0].components[i].component = UDP_InterfaceFactory_get_interface(); + _system_configurations[0].components[i].listener = NULL; + _system_configurations[0].components[i].property = + (struct RT_ComponentFactoryProperty*) _new_udp_property(); +#endif /* !EXCLUDE_UDP */ +#endif /* RTI_CONNEXT_MICRO */ + + return true; + } + + FACE::Boolean _custom_get_connection_config( + RTI_TSS_Connection_Configuration_T **cfg, + const char *cfg_name) + { + if ((cfg == NULL) || + (*cfg != NULL) || + (cfg_name == NULL)) + { + return false; + } + + for (FACE::UnsignedLong i = 0; i < _connection_configs.size(); i++) + { + if (_strcmp_uppercase(_connection_configs[i].config_name, cfg_name)) + { + *cfg = &_connection_configs[i]; + return true; + } + } + + return false; + } + + FACE::Boolean _populate_custom_domain_config() + { + if (!RTI_TSS_DDS_DomainParticipant_Configuration_initialize(&_domain_configurations[0])) + { + return false; + } + _domain_configurations[0].config_name = "domain_0"; + _domain_configurations[0].domain_id = 0; + _domain_configurations[0].configure_domain_participant_qos_fn = NULL; + _domain_configurations[0].user_data = NULL; + #ifdef RTI_CONNEXT_PRO + // The binding with QoS library and profile will happen later on, so + // no need to assign any QoS function here + _domain_configurations[0].qos_library = NULL; + _domain_configurations[0].qos_profile = NULL; + #endif + + return true; + } + + RTI_TSS_Connection_Configuration_T GenerateConnectionConfiguration( + const char* config_name, + const char* domain_config_name, + FACE_CONNECTION_DIRECTION_TYPE direction, + const char* topic_name, + const char* type_name, + FACE::Boolean &success) + { + success = DDS_BOOLEAN_TRUE; + + RTI_TSS_Connection_Configuration_T connection_configuration; + if (!RTI_TSS_Connection_Configuration_initialize(&connection_configuration)) + { + success = DDS_BOOLEAN_FALSE; + return connection_configuration; + } + connection_configuration.config_name = DDS_String_dup(config_name); + connection_configuration.domain_config_name = domain_config_name; + connection_configuration.direction = direction; + connection_configuration.topic_name = topic_name; + connection_configuration.type_name = type_name; + // The binding with QoS functions will happen later on, so no need to + // assign any QoS function here + connection_configuration.configure_publisher_qos_fn = NULL; + connection_configuration.configure_topic_qos_fn = NULL; + connection_configuration.configure_datawriter_qos_fn = NULL; + connection_configuration.configure_subscriber_qos_fn = NULL; + connection_configuration.configure_datareader_qos_fn = NULL; + connection_configuration.user_data = NULL; +#ifndef RTI_CONNEXT_MICRO + connection_configuration.bi_dir_ignore_self = DDS_BOOLEAN_TRUE; + // The binding with QoS library and profile will happen later on, so + // no need to assign any QoS function here + connection_configuration.qos_library = NULL; + connection_configuration.qos_profile = NULL; +#endif + + return connection_configuration; + } + + FACE::Boolean _populate_custom_connection_config() + { + char* conf_name = (char*)malloc(32); + + if (!conf_name) + { + return DDS_BOOLEAN_FALSE; + } + + FACE::Boolean success = true; + + sprintf(conf_name, "writer "); + strcat(conf_name, ANNOUNCEMENT_TOPIC_NAME); + + /***** Announcement *****/ + _connection_configs.push_back(GenerateConnectionConfiguration( + conf_name, + "domain_0", + FACE_SOURCE, + ANNOUNCEMENT_TOPIC_NAME, + _type_name, + success)); + + if (!success) + { + free(conf_name); + return DDS_BOOLEAN_FALSE; + } + + sprintf(conf_name, "reader "); + strcat(conf_name, ANNOUNCEMENT_TOPIC_NAME); + _connection_configs.push_back(GenerateConnectionConfiguration( + conf_name, + "domain_0", + FACE_DESTINATION, + ANNOUNCEMENT_TOPIC_NAME, + _type_name, + success)); + + if (!success) + { + free(conf_name); + return DDS_BOOLEAN_FALSE; + } + + sprintf(conf_name, "writer "); + strcat(conf_name, LATENCY_TOPIC_NAME); + /***** Latency *****/ + _connection_configs.push_back(GenerateConnectionConfiguration( + conf_name, + "domain_0", + FACE_SOURCE, + LATENCY_TOPIC_NAME, + _type_name, + success)); + + if (!success) + { + free(conf_name); + return DDS_BOOLEAN_FALSE; + } + + sprintf(conf_name, "reader "); + strcat(conf_name, LATENCY_TOPIC_NAME); + _connection_configs.push_back(GenerateConnectionConfiguration( + conf_name, + "domain_0", + FACE_DESTINATION, + LATENCY_TOPIC_NAME, + _type_name, + success)); + + if (!success) + { + free(conf_name); + return DDS_BOOLEAN_FALSE; + } + + sprintf(conf_name, "writer "); + strcat(conf_name, THROUGHPUT_TOPIC_NAME); + /*****Throughput *****/ + _connection_configs.push_back(GenerateConnectionConfiguration( + conf_name, + "domain_0", + FACE_SOURCE, + THROUGHPUT_TOPIC_NAME, + _type_name, + success)); + + if (!success) + { + free(conf_name); + return DDS_BOOLEAN_FALSE; + } + + sprintf(conf_name, "reader "); + strcat(conf_name, THROUGHPUT_TOPIC_NAME); + _connection_configs.push_back(GenerateConnectionConfiguration( + conf_name, + "domain_0", + FACE_DESTINATION, + THROUGHPUT_TOPIC_NAME, + _type_name, + success)); + + if (!success) + { + free(conf_name); + return DDS_BOOLEAN_FALSE; + } + + return success; + } + + const char* _type_name; + std::vector _connection_configs; +}; + +#endif // CUSTOM_CONFIGURATION_HPP diff --git a/srcCpp/connextDDS/TSS/CustomQosSupport.cpp b/srcCpp/connextDDS/TSS/CustomQosSupport.cpp new file mode 100644 index 00000000..ec84e0ac --- /dev/null +++ b/srcCpp/connextDDS/TSS/CustomQosSupport.cpp @@ -0,0 +1,756 @@ +#include "CustomQosSupport.hpp" + +std::string stringValueQoS(DDS_Long resourceLimitValue) { + if (resourceLimitValue == -1) { + return "Unlimited"; + } else if (resourceLimitValue == -2) { + return "Auto"; + } else { + return perftest::to_string(resourceLimitValue); + } +} + +/* function for customizing domain participant qos */ +DDS_Boolean +RTI_TSS_participant_qos(struct DDS_DomainParticipantQos *dp_qos, void *data) +{ + struct QoSBundle *ctx = (struct QoSBundle*) data; + +#ifdef RTI_PERF_TSS_PRO + // Set initial peers and not use multicast + const std::vector peerList = + ctx->pm->get_vector("peer"); + if (!peerList.empty()) { + DDS_StringSeq_set_maximum(&dp_qos->discovery.initial_peers, 0); + + std::vector cstrings; + cstrings.reserve(peerList.size()); + for(unsigned int i = 0; i < peerList.size(); ++i) { + cstrings.push_back(const_cast(peerList[i].c_str())); + } + DDS_StringSeq_from_array(&dp_qos->discovery.initial_peers, + (const char **)&cstrings[0], + (long)peerList.size()); + DDS_StringSeq_set_length( + &dp_qos->discovery.multicast_receive_addresses, 0); + } +#elif defined(RTI_PERF_TSS_MICRO) + DDS_StringSeq_set_maximum(&dp_qos->discovery.initial_peers, 0); + + const std::vector peerList = + ctx->pm->get_vector("peer"); + if (!peerList.empty()) { + DDS_StringSeq_set_maximum( + &dp_qos->discovery.initial_peers, (int) peerList.size()); + DDS_StringSeq_set_length( + &dp_qos->discovery.initial_peers, (int) peerList.size()); + for(unsigned int i = 0; i < peerList.size(); ++i) { + *DDS_StringSeq_get_reference(&dp_qos->discovery.initial_peers, i) + = DDS_String_dup(peerList[i].c_str()); + } + } else { /* Default discovery peers (unicast and multicast) */ + DDS_StringSeq_set_maximum( + &dp_qos->discovery.initial_peers, 2); + DDS_StringSeq_set_length( + &dp_qos->discovery.initial_peers, 2); + *DDS_StringSeq_get_reference(&dp_qos->discovery.initial_peers, 0) + = DDS_String_dup("239.255.0.1"); + *DDS_StringSeq_get_reference(&dp_qos->discovery.initial_peers, 1) + = DDS_String_dup("127.0.0.1"); + } + dp_qos->discovery.accept_unknown_peers = DDS_BOOLEAN_TRUE; +#endif + + if (!PerftestConfigureTransport(*ctx->transport, *dp_qos, ctx->pm)) { + return false; + } + +#ifdef RTI_PERF_TSS_MICRO + RT_Registry_T *registry = NULL; + struct DPDE_DiscoveryPluginProperty *discovery_plugin_properties = + (DPDE_DiscoveryPluginProperty*)malloc( + sizeof(DPDE_DiscoveryPluginProperty)); + + DPDE_DiscoveryPluginProperty_initialize(discovery_plugin_properties); + + registry = DDS_DomainParticipantFactory_get_registry( + DDS_DomainParticipantFactory_get_instance()); + + if ((RT_Registry_lookup(registry, + DDSHST_WRITER_DEFAULT_HISTORY_NAME) == NULL) && + !RT_Registry_register(registry, DDSHST_WRITER_DEFAULT_HISTORY_NAME, + WHSM_HistoryFactory_get_interface(), NULL, NULL)) + { + fprintf(stderr, "failed to register writer history\n"); + return DDS_BOOLEAN_FALSE; + } + + if ((RT_Registry_lookup(registry, + DDSHST_READER_DEFAULT_HISTORY_NAME) == NULL) && + !RT_Registry_register(registry, DDSHST_READER_DEFAULT_HISTORY_NAME, + RHSM_HistoryFactory_get_interface(), NULL, NULL)) + { + fprintf(stderr, "failed to register reader history\n"); + return DDS_BOOLEAN_FALSE; + } + + #if FACE_COMPLIANCE_LEVEL_SAFETY_BASE_OR_STRICTER + /* Safety Base or stricter must use non-auto DDS participant ID + * ATTENTION: the participant_id below _must_ be modified to be unique + * between all applications. Otherwise, new participants with the same ID + * with an existing participant will fail to be created. + */ + dp_qos->protocol.participant_id = 1; + #endif /* FACE_COMPLIANCE_LEVEL_SAFETY_BASE_OR_STRICTER */ +#endif + + /* + * At this point, and not before is when we know the transport message size. + * Now we can decide if we need to use asynchronous or not. + */ + *ctx->maxSynchronousSize = ctx->transport->minimumMessageSizeMax - (MESSAGE_OVERHEAD_BYTES); + + if (!data_size_related_calculations(ctx)) { + fprintf(stderr, "Failed to configure the data size settings\n"); + return DDS_BOOLEAN_FALSE; + } + + return DDS_BOOLEAN_TRUE; +} + +bool data_size_related_calculations(QoSBundle* ctx) +{ + /* + * Check that the overhead is not bigger than the -dataLen, since we can not + * send a lower size that the overhead of the test_type. + */ + if (ctx->pm->get("dataLen") + < perftest_cpp::OVERHEAD_BYTES) { + fprintf(stderr, + "The minimum dataLen allowed for this configuration is %d " + "Bytes.\n", + perftest_cpp::OVERHEAD_BYTES); + /* + * T::TypeSupport::get_type_name() can not be used since we do need + * refractor RTIDDSImpl_FlatData class to properly inherit from a + * templated class instead from a final class. + */ + return false; + } + + // If the user wants to use asynchronous we enable it + if (ctx->pm->get("asynchronous")) { + *ctx->isLargeData = true; + } else { //If the message size max is lower than the datalen + *ctx->isLargeData = (ctx->pm->get("dataLen") > *ctx->maxSynchronousSize); + } + + // Manage parameter -batchSize + if (ctx->pm->get("batchSize") > 0) { + + // Check if using asynchronous + if (ctx->pm->get("asynchronous")) { + if (ctx->pm->is_set("batchSize") && ctx->pm->get("batchSize") != 0) { + fprintf(stderr, + "Batching cannot be used with asynchronous writing.\n"); + return false; + } else { + ctx->pm->set("batchSize", 0); // Disable Batching + } + } + + /* + * Large Data + batching cannot be set. But batching is enabled by default, + * so in that case, we just disabled batching, else, the customer set it up, + * so we explitly fail + */ + if (*ctx->isLargeData) { + if (ctx->pm->is_set("batchSize") && ctx->pm->get("batchSize") != 0) { + fprintf(stderr, "Batching cannot be used with Large Data.\n"); + return false; + } else { + ctx->pm->set("batchSize", -2); + } + } else if (((unsigned long)ctx->pm->get("batchSize") + < ctx->pm->get("dataLen") * 2) + && !ctx->pm->is_set("scan")) { + /* + * We don't want to use batching if the batch size is not large + * enough to contain at least two samples (in this case we avoid the + * checking at the middleware level). + */ + if (ctx->pm->is_set("batchSize")) { + /* + * Batchsize disabled. A message will be print if batchSize < 0 + * in perftest_cpp::print_configuration() + */ + ctx->pm->set("batchSize", -1); + } else { + ctx->pm->set("batchSize", 0); // Disable Batching + } + } + } + + // Manage parameter -enableTurboMode + if (ctx->pm->get("enableTurboMode")) { + if (ctx->pm->get("asynchronous")) { + fprintf(stderr, "Turbo Mode cannot be used with asynchronous writing.\n"); + return false; + } if (ctx->isLargeData) { + fprintf(stderr, "Turbo Mode disabled, using large data.\n"); + ctx->pm->set("enableTurboMode", false); + } + } + + // Manage the parameter: -scan + if (ctx->pm->is_set("scan")) { + const std::vector scanList = + ctx->pm->get_vector("scan"); + + // Check if scan is large data or small data + if (scanList[0] <= (unsigned long long) ctx->maxSynchronousSize + && scanList[scanList.size() - 1] > (unsigned long long)ctx->maxSynchronousSize) { + fprintf(stderr, "The sizes of -scan ["); + for (unsigned int i = 0; i < scanList.size(); i++) { + fprintf(stderr, "%llu ", scanList[i]); + } + fprintf(stderr, + "] should be either all smaller or all bigger than %llu.\n", + *ctx->maxSynchronousSize); + return false; + } + } + + return true; +} + +/* function for customizing data writer qos */ +DDS_Boolean +RTI_TSS_datawriter_qos(struct DDS_DataWriterQos *dw_qos, void *data) +{ + struct QoSBundle *ctx = (struct QoSBundle*) data; + +#ifdef RTI_PERF_TSS_PRO + if (ctx->pm->get("noPositiveAcks") + && (strcmp(ctx->topic_name.c_str(), THROUGHPUT_TOPIC_NAME) == 0 || strcmp(ctx->topic_name.c_str(), LATENCY_TOPIC_NAME) == 0)) { + dw_qos->protocol.disable_positive_acks = true; + if (ctx->pm->is_set("keepDurationUsec")) { + DDS_Duration_t keep_duration; + keep_duration.sec = 0; + keep_duration.nanosec = + ctx->pm->get("keepDurationUsec") * 1000; + dw_qos->protocol.rtps_reliable_writer.disable_positive_acks_min_sample_keep_duration = keep_duration; + } + } + + if (*ctx->isLargeData || ctx->pm->get("asynchronous")) { + dw_qos->publish_mode.kind = DDS_ASYNCHRONOUS_PUBLISH_MODE_QOS; + if (ctx->pm->get("flowController") != "default") { + dw_qos->publish_mode.flow_controller_name = + DDS_String_dup(("dds.flow_controller.token_bucket." + + ctx->pm->get("flowController")).c_str()); + } + } + + dw_qos->resource_limits.initial_samples = ctx->pm->get("sendQueueSize"); +#endif + + if (strcmp(ctx->topic_name.c_str(), ANNOUNCEMENT_TOPIC_NAME) != 0) + { + if (ctx->pm->get("bestEffort")) + { + dw_qos->reliability.kind = DDS_BEST_EFFORT_RELIABILITY_QOS; + } + else + { + // default: use the setting specified in the qos profile +#ifdef RTI_PERF_TSS_MICRO + dw_qos->reliability.kind = DDS_RELIABLE_RELIABILITY_QOS; +#endif + } + } + else + { +#ifdef RTI_PERF_TSS_MICRO + dw_qos->reliability.kind = DDS_RELIABLE_RELIABILITY_QOS; + dw_qos->durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS; +#endif + } + + if (strcmp(ctx->topic_name.c_str(), ANNOUNCEMENT_TOPIC_NAME) == 0 + || strcmp(ctx->topic_name.c_str(), THROUGHPUT_TOPIC_NAME) == 0) { +#ifdef RTI_PERF_TSS_PRO + dw_qos->protocol.rtps_reliable_writer.low_watermark = + ctx->pm->get("sendQueueSize") * 1 / 10; + dw_qos->protocol.rtps_reliable_writer.high_watermark = + ctx->pm->get("sendQueueSize") * 9 / 10; + + /* + * If _SendQueueSize is 1 low watermark and high watermark would both be + * 0, which would cause the middleware to fail. So instead we set the + * high watermark to the low watermark + 1 in such case. + */ + if (dw_qos->protocol.rtps_reliable_writer.high_watermark + == dw_qos->protocol.rtps_reliable_writer.low_watermark) { + dw_qos->protocol.rtps_reliable_writer.high_watermark = + dw_qos->protocol.rtps_reliable_writer.low_watermark + 1; + } +#endif + } + + if (strcmp(ctx->topic_name.c_str(), THROUGHPUT_TOPIC_NAME) == 0) { +#ifdef RTI_PERF_TSS_PRO + if (ctx->pm->get("multicast")) { + dw_qos->protocol.rtps_reliable_writer.enable_multicast_periodic_heartbeat = + RTI_TRUE; + } + + if (ctx->pm->get("batchSize") > 0) { + dw_qos->batch.enable = true; + dw_qos->batch.max_data_bytes = ctx->pm->get("batchSize"); + dw_qos->resource_limits.max_samples = DDS_LENGTH_UNLIMITED; + dw_qos->writer_resource_limits.max_batches = + ctx->pm->get("sendQueueSize"); + } else { + dw_qos->resource_limits.max_samples = ctx->pm->get("sendQueueSize"); + } +#else + dw_qos->resource_limits.max_samples = ctx->pm->get("sendQueueSize"); +#endif + dw_qos->resource_limits.max_samples_per_instance = + dw_qos->resource_limits.max_samples; + + dw_qos->durability.kind = + (DDS_DurabilityQosPolicyKind)ctx->pm->get("durability"); + +#ifdef RTI_PERF_TSS_PRO + dw_qos->resource_limits.initial_samples = + ctx->pm->get("sendQueueSize"); + dw_qos->durability.direct_communication = + !ctx->pm->get("noDirectCommunication"); +#endif // RTI_PERF_TSS_PRO + + if (ctx->pm->get("dataLen") > DEFAULT_MESSAGE_SIZE_MAX) { + dw_qos->protocol.rtps_reliable_writer.heartbeats_per_max_samples = + ctx->pm->get("sendQueueSize"); + } else { + dw_qos->protocol.rtps_reliable_writer.heartbeats_per_max_samples = + ctx->pm->get("sendQueueSize") / 10; + } + +#ifdef RTI_PERF_TSS_MICRO +#ifdef PERFTEST_RTI_MICRO_24x_COMPATIBILITY + dw_qos->history.kind = DDS_KEEP_LAST_HISTORY_QOS; +#else + dw_qos->history.kind = DDS_KEEP_ALL_HISTORY_QOS; +#endif // PERFTEST_RTI_MICRO_24x_COMPATIBILITY + + dw_qos->history.depth = ctx->pm->get("sendQueueSize"); + + // Same values we use for Pro (See perftest_qos_profiles.xml). + dw_qos->protocol.rtps_reliable_writer.heartbeat_period.sec = 0; + dw_qos->protocol.rtps_reliable_writer.heartbeat_period.nanosec = 10000000; +#endif // RTI_PERF_TSS_PRO + } + + if (strcmp(ctx->topic_name.c_str(), LATENCY_TOPIC_NAME)) { + if (ctx->pm->get("noDirectCommunication") + && (ctx->pm->get("durability") == DDS_TRANSIENT_DURABILITY_QOS + || ctx->pm->get("durability") == DDS_PERSISTENT_DURABILITY_QOS)) + { + dw_qos->durability.kind = + (DDS_DurabilityQosPolicyKind) ctx->pm->get("durability"); +#ifdef RTI_PERF_TSS_PRO + dw_qos->durability.direct_communication = + !ctx->pm->get("noDirectCommunication"); +#endif // RTI_PERF_TSS_PRO + } + +#ifdef RTI_PERF_TSS_PRO + if (ctx->pm->get("dataLen") > DEFAULT_MESSAGE_SIZE_MAX) { + dw_qos->protocol.rtps_reliable_writer.heartbeats_per_max_samples = + ctx->pm->get("sendQueueSize"); + } else { + dw_qos->protocol.rtps_reliable_writer.heartbeats_per_max_samples = + ctx->pm->get("sendQueueSize") / 10; + } + + if (ctx->pm->is_set("sendQueueSize")) { + dw_qos->protocol.rtps_reliable_writer.max_send_window_size = + ctx->pm->get("sendQueueSize"); + dw_qos->protocol.rtps_reliable_writer.min_send_window_size = + ctx->pm->get("sendQueueSize"); + } +#endif // RTI_PERF_TSS_PRO + } + + //One extra for MAX_CFT_VALUE + dw_qos->resource_limits.max_instances = + (DDS_Long)ctx->pm->get("instances") + 1; + +#ifdef RTI_PERF_TSS_PRO + dw_qos->resource_limits.initial_instances = + dw_qos->resource_limits.max_instances; + + // If is LargeData + if (ctx->pm->get("unbounded") != 0) { + char buf[10]; + sprintf(buf, "%d", ctx->pm->get("unbounded")); + DDSPropertyQosPolicyHelper::add_property(dw_qos->property, + "dds.data_writer.history.memory_manager.fast_pool.pool_buffer_max_size", + buf, + false); + } + + if (ctx->pm->get("instances") > 1) { + if (ctx->pm->is_set("instanceHashBuckets")) { + dw_qos->resource_limits.instance_hash_buckets = + ctx->pm->get("instanceHashBuckets"); + } else { + dw_qos->resource_limits.instance_hash_buckets = + ctx->pm->get("instances"); + } + } +#endif + + if (ctx->pm->get("showResourceLimits") + && ctx->topic_name.c_str() != ANNOUNCEMENT_TOPIC_NAME) { + std::ostringstream stringStream; + + stringStream << "Resource Limits DW (" + << ctx->topic_name.c_str() + << " topic):\n" + // Samples + << "\tSamples (" + #ifdef RTI_PERF_TSS_PRO + << "Initial/" + #endif + << "Max): " + #ifdef RTI_PERF_TSS_PRO + << stringValueQoS(dw_qos->resource_limits.initial_samples) + << "/" + #endif + << stringValueQoS(dw_qos->resource_limits.max_samples) + << "\n"; + + if (ctx->pm->get("keyed")) { + // Instances + stringStream << "\tInstances (" + #ifdef RTI_PERF_TSS_PRO + << "Initial/" + #endif + << "Max): " + #ifdef RTI_PERF_TSS_PRO + << stringValueQoS(dw_qos->resource_limits.initial_instances) + << "/" + #endif + << stringValueQoS(dw_qos->resource_limits.max_instances) + << "\n"; + + // Samples per Instance + stringStream << "\tMax Samples per Instance: " + << stringValueQoS(dw_qos->resource_limits.max_samples_per_instance) + << "\n"; + } + + #ifdef RTI_PERF_TSS_PRO + // Batches + if (dw_qos->batch.enable) { + stringStream << "\tBatching Max Bytes: " + << stringValueQoS(dw_qos->batch.max_data_bytes) + << "\n" + << "\tBatching Max Batches: " + << stringValueQoS(dw_qos->writer_resource_limits.max_batches) + << "\n"; + } + + // Send Queue + stringStream << "\tSend Queue (Min/Max): " + << stringValueQoS( + dw_qos->protocol.rtps_reliable_writer.min_send_window_size) + << "/" + << stringValueQoS( + dw_qos->protocol.rtps_reliable_writer.max_send_window_size) + << "\n"; + + #ifdef RTI_FLATDATA_AVAILABLE + // writer_loaned_sample_allocation + if (_isFlatData) { + stringStream << "\twriter_loaned_sample_allocation (initial_count/max_count): " + << stringValueQoS( + dw_qos->writer_resource_limits.writer_loaned_sample_allocation.initial_count) + << "/" + << stringValueQoS( + dw_qos->writer_resource_limits.writer_loaned_sample_allocation.max_count) + << "\n"; + // Property: pool_buffer_max_size + stringStream << "\tfast_pool.pool_buffer_max_size: " + << stringValueQoS( + _isFlatData ? DDS_LENGTH_UNLIMITED : ctx->pm->get("unbounded")) + << "\n"; + } + #endif + + // Heartbeats per max samples + stringStream << "\tHeartbeats per max samples: " + << stringValueQoS( + dw_qos->protocol.rtps_reliable_writer.heartbeats_per_max_samples) + << "\n"; + + #endif + + // Heartbeats per max samples + stringStream << "\tHeartbeat period (s/ns): " + << dw_qos->protocol.rtps_reliable_writer.heartbeat_period.sec + << ", " + << dw_qos->protocol.rtps_reliable_writer.heartbeat_period.nanosec + << "\n"; + + fprintf(stderr, "%s\n", stringStream.str().c_str()); + + } + + return DDS_BOOLEAN_TRUE; +} + +/* function for customizing data reader qos */ +DDS_Boolean +RTI_TSS_datareader_qos(struct DDS_DataReaderQos *dr_qos, void *data) +{ + struct QoSBundle *ctx = (struct QoSBundle*) data; + +#ifdef RTI_PERF_TSS_PRO + dr_qos->resource_limits.initial_instances = 1; +#endif // RTI_PERF_TSS_PRO + + // Only force reliability on throughput/latency topics + if (strcmp(ctx->topic_name.c_str(), ANNOUNCEMENT_TOPIC_NAME) != 0) { + if (ctx->pm->get("bestEffort")) { + dr_qos->reliability.kind = DDS_BEST_EFFORT_RELIABILITY_QOS; + } else { + dr_qos->reliability.kind = DDS_RELIABLE_RELIABILITY_QOS; + } + } + +#ifdef RTI_PERF_TSS_PRO + if (ctx->pm->is_set("receiveQueueSize")) { + dr_qos->resource_limits.initial_samples = + ctx->pm->get("receiveQueueSize"); + } + + dr_qos->resource_limits.initial_instances = + ctx->pm->get("instances") + 1; + if (ctx->instanceMaxCountReader != DDS_LENGTH_UNLIMITED) { + ctx->instanceMaxCountReader++; + } +#else + /* + * In micro we cannot have UNLIMITED instances, this means that we need to + * increase the InstanceMaxCountReader (max instances for the dr) in all + * cases + */ + ctx->instanceMaxCountReader++; +#endif // RTI_PERF_TSS_PRO + dr_qos->resource_limits.max_instances = + (DDS_Long)ctx->instanceMaxCountReader; + +#ifdef RTI_PERF_TSS_PRO + if (ctx->pm->get("instances") > 1) { + if (ctx->pm->is_set("instanceHashBuckets")) { + dr_qos->resource_limits.instance_hash_buckets = + ctx->pm->get("instanceHashBuckets"); + } else { + dr_qos->resource_limits.instance_hash_buckets = + ctx->pm->get("instances"); + } + } + + if (ctx->pm->get("noPositiveAcks") + && (ctx->topic_name.c_str() == THROUGHPUT_TOPIC_NAME + || ctx->topic_name.c_str() == LATENCY_TOPIC_NAME)) { + dr_qos->protocol.disable_positive_acks = true; + } +#endif + + if (ctx->topic_name.c_str() == THROUGHPUT_TOPIC_NAME + || (ctx->topic_name.c_str() == LATENCY_TOPIC_NAME + && ctx->pm->get("noDirectCommunication") + && (ctx->pm->get("durability") == DDS_TRANSIENT_DURABILITY_QOS + || ctx->pm->get("durability") == DDS_PERSISTENT_DURABILITY_QOS))) { + dr_qos->durability.kind = + (DDS_DurabilityQosPolicyKind) ctx->pm->get("durability"); +#ifndef RTI_PERF_TSS_MICRO + dr_qos->durability.direct_communication = + !ctx->pm->get("noDirectCommunication"); +#endif + + } + +#ifdef RTI_PERF_TSS_PRO + if (ctx->pm->get("multicast") && ctx->transport->allowsMulticast()) { + DDS_TransportMulticastSettingsSeq_ensure_length( + &dr_qos->multicast.value, 1, 1); + DDS_TransportMulticastSettingsSeq_get_reference( + &dr_qos->multicast.value, 0)->receive_address = DDS_String_dup( + ctx->transport->getMulticastAddr(ctx->topic_name.c_str()).c_str()); + + if (DDS_TransportMulticastSettingsSeq_get_reference( + &dr_qos->multicast.value, 0)->receive_address == NULL) { + fprintf(stderr, + "topic name must either be %s or %s or %s.\n", + THROUGHPUT_TOPIC_NAME, + LATENCY_TOPIC_NAME, + ANNOUNCEMENT_TOPIC_NAME); + return false; + } + + DDS_TransportMulticastSettingsSeq_get_reference( + &dr_qos->multicast.value, 0)->receive_port = 0; + DDS_StringSeq_set_length( + &DDS_TransportMulticastSettingsSeq_get_reference( + &dr_qos->multicast.value, 0)->transports, 0); + } +#endif + +#ifdef RTI_PERF_TSS_MICRO + if (strcmp(ctx->topic_name.c_str(), THROUGHPUT_TOPIC_NAME) == 0) { + /* + * For Connext DDS Pro settings are set so initial samples are set to + * a lower value than max_samples, so we can grow if needed. For micro + * however we do not have the initial_samples parameter, therefore we + * must choose a value for max_samples since the beginning. We chose to + * use 10000. This value should be large enough to handle most of the + * communications. + * + * We could potentially modify this with a new command line parameter + */ + if (ctx->pm->get("dataLen") > MAX_BOUNDED_SEQ_SIZE) { + dr_qos->resource_limits.max_samples = 50; + dr_qos->resource_limits.max_samples_per_instance = 50; + dr_qos->history.depth = 50; + } + else { + dr_qos->resource_limits.max_samples = 5000; + dr_qos->resource_limits.max_samples_per_instance = 5000; + dr_qos->history.depth = 5000; + } + /* + * In micro 2.4.x we don't have keep all, this means we need to set the + * history to keep last and chose a history depth. For the depth value + * we can we same value as max_samples + */ + #if PERFTEST_RTI_MICRO_24x_COMPATIBILITY + // Keep all not supported in Micro 2.4.x + dr_qos->history.kind = DDS_KEEP_LAST_HISTORY_QOS; + #else + dr_qos->history.kind = DDS_KEEP_ALL_HISTORY_QOS; + #endif + + } else { // "LatencyQos" or "AnnouncementQos" + + /* + * By default Micro will use a max_samples = 1. This is too low for the + * initial burst of data. In pro we set this value via QoS to + * LENGTH_UNLIMITED. In Micro we will use a lower number due to + * memory restrictions. + */ + if (ctx->pm->get("dataLen") > MAX_BOUNDED_SEQ_SIZE) { + dr_qos->resource_limits.max_samples = 50; + } + else { + dr_qos->resource_limits.max_samples = 5000; + } + } + + /* + * We could potentially use here the number of subscriber, right now this + * class does not have access to the number of subscriber though. + */ + dr_qos->reader_resource_limits.max_remote_writers = 50; + dr_qos->reader_resource_limits.max_remote_writers_per_instance = 50; + + if (ctx->pm->get("multicast")) { + + if (ctx->transport->getMulticastAddr(ctx->topic_name.c_str()).empty()) { + fprintf(stderr, + "topic name must either be %s or %s or %s.\n", + THROUGHPUT_TOPIC_NAME, + LATENCY_TOPIC_NAME, + ANNOUNCEMENT_TOPIC_NAME); + return false; + } + + std::string receive_address = "_udp://" + ctx->transport->getMulticastAddr(ctx->topic_name.c_str()); + DDS_StringSeq_set_maximum(&dr_qos->transport.enabled_transports, 1); + DDS_StringSeq_set_length(&dr_qos->transport.enabled_transports, 1); + *DDS_StringSeq_get_reference(&dr_qos->transport.enabled_transports, 0) = + DDS_String_dup(receive_address.c_str()); + + } + + if (ctx->pm->get("showResourceLimits") + && ctx->topic_name.c_str() != ANNOUNCEMENT_TOPIC_NAME) + { + std::ostringstream stringStream; + + stringStream << "Resource Limits DR (" + << ctx->topic_name.c_str() + << " topic):\n" + // Samples + << "\tSamples (" + #ifdef RTI_PERF_TSS_PRO + << "Initial/" + #endif + << "Max): " + #ifdef RTI_PERF_TSS_PRO + << stringValueQoS(dr_qos->resource_limits.initial_samples) + << "/" + #endif + << stringValueQoS(dr_qos->resource_limits.max_samples) + << "\n"; + + if (ctx->pm->get("keyed")){ + // Instances + stringStream << "\tInstances (" + #ifdef RTI_PERF_TSS_PRO + << "Initial/" + #endif + << "Max): " + #ifdef RTI_PERF_TSS_PRO + << stringValueQoS(dr_qos->resource_limits.initial_instances) + << "/" + #endif + << stringValueQoS(dr_qos->resource_limits.max_instances) + << "\n"; + + // Samples per Instance + stringStream << "\tMax Samples per Instance: " + << stringValueQoS(dr_qos->resource_limits.max_samples_per_instance) + << "\n"; + } + + fprintf(stderr, "%s\n", stringStream.str().c_str()); + } +#endif //RTI_PERF_TSS_MICRO + + if (ctx->pm->get("unbounded") != 0) + { + #ifdef RTI_PERF_TSS_PRO + char buf[10]; + sprintf(buf, "%d", ctx->pm->get("unbounded")); + DDSPropertyQosPolicyHelper::add_property(dr_qos->property, + "dds.data_reader.history.memory_manager.fast_pool.pool_buffer_max_size", + buf, false); + #else + /* This is only needed for Micro 2.4.x. False unbounded sequences are + * available in Micro 3.0 */ + #if PERFTEST_RTI_MICRO_24x_COMPATIBILITY + fprintf(stderr, + "Unbounded sequences not supported on Micro.\n"); + return false; + #endif + #endif + } + + return DDS_BOOLEAN_TRUE; +} \ No newline at end of file diff --git a/srcCpp/connextDDS/TSS/CustomQosSupport.hpp b/srcCpp/connextDDS/TSS/CustomQosSupport.hpp new file mode 100644 index 00000000..bee7e452 --- /dev/null +++ b/srcCpp/connextDDS/TSS/CustomQosSupport.hpp @@ -0,0 +1,42 @@ +/* include RTI TSS header file for QoS configuration */ +#include "util/rti_tss_common.h" + +#ifdef RTI_PERF_TSS_PRO + #include "Infrastructure_pro.h" +#else + #include "Infrastructure_micro.h" +#endif + +#include "log/ext_log.h" + +#include "Infrastructure_common.h" +#include "ParameterManager.h" +#include "perftest.h" +#include "PerftestTransport.h" + +#include "perftest_cpp.h" + +typedef struct QoSBundle { + ParameterManager* pm; + PerftestTransport* transport; + std::string topic_name; + long instanceMaxCountReader; + bool* isLargeData; + unsigned long long* maxSynchronousSize; +} QoSBundle; + +std::string stringValueQoS(DDS_Long resourceLimitValue); + +/* function for customizing domain participant qos */ +DDS_Boolean +RTI_TSS_participant_qos(struct DDS_DomainParticipantQos *dp_qos, void *data); + +bool data_size_related_calculations(QoSBundle* ctx); + +/* function for customizing data writer qos */ +DDS_Boolean +RTI_TSS_datawriter_qos(struct DDS_DataWriterQos *writer_qos, void *data); + +/* function for customizing data reader qos */ +DDS_Boolean +RTI_TSS_datareader_qos(struct DDS_DataReaderQos *reader_qos, void *data); \ No newline at end of file diff --git a/srcCpp/connextDDS/TSS/RTITSSImpl.cxx b/srcCpp/connextDDS/TSS/RTITSSImpl.cxx new file mode 100644 index 00000000..298cb0d7 --- /dev/null +++ b/srcCpp/connextDDS/TSS/RTITSSImpl.cxx @@ -0,0 +1,1281 @@ +/* + * (c) 2005-2020 Copyright, Real-Time Innovations, Inc. All rights reserved. + * Subject to Eclipse Public License v1.0; see LICENSE.md for details. + */ + +#include "MessagingIF.h" +#include "perftest_cpp.h" +#include "RTITSSImpl.h" +#include "CustomConfiguration.hpp" + +#include "rti_tss_impl.h" + +#ifdef RTI_PERF_TSS_PRO + #include "ndds/ndds_cpp.h" +#endif + +const std::string GetMiddlewareVersionString() +{ + return std::string(RTI_TSS_VER_INFO_STR); +} + +template +RTITSSImpl::RTITSSImpl(const char*type_name) : + _tss(new RTI::TSS::Base), + _pong_semaphore(NULL), + _pm(NULL) +{ + _type_name = type_name; + + _qoSProfileNameMap[LATENCY_TOPIC_NAME] = std::string("LatencyQos"); + _qoSProfileNameMap[ANNOUNCEMENT_TOPIC_NAME] = std::string("AnnouncementQos"); + _qoSProfileNameMap[THROUGHPUT_TOPIC_NAME] = std::string("ThroughputQos"); + +#ifdef PERFTEST_RTI_PRO + _instanceMaxCountReader = DDS_LENGTH_UNLIMITED; +#else + /* + * For micro we want to restrict the use of memory, and since we need + * to set a maximum (other than DDS_LENGTH_UNLIMITED), we decided to use + * a default of 1. This means that for Micro, we need to specify the + * number of instances that will be received in the reader side. + */ + _instanceMaxCountReader = 1; +#endif + + _maxSynchronousSize = MESSAGE_SIZE_MAX_NOT_SET; + + _isLargeData = false; +} + +template +const std::string RTITSSImpl::get_qos_profile_name(const char *topicName) +{ + if (_qoSProfileNameMap[std::string(topicName)].empty()) { + fprintf(stderr, + "topic name must either be %s or %s or %s.\n", + THROUGHPUT_TOPIC_NAME, + LATENCY_TOPIC_NAME, + ANNOUNCEMENT_TOPIC_NAME); + } + + /* If the topic name dont match any key return a empty string */ + return _qoSProfileNameMap[std::string(topicName)]; +} + +template +void RTITSSImpl::configure_middleware_verbosity( + int verbosity_level) +{ +#ifdef RTI_PERF_TSS_PRO + + NDDS_Config_LogVerbosity verbosity = NDDS_CONFIG_LOG_VERBOSITY_ERROR; + switch (verbosity_level) { + case 0: verbosity = NDDS_CONFIG_LOG_VERBOSITY_SILENT; + fprintf(stderr, "Setting verbosity to SILENT\n"); + break; + case 1: verbosity = NDDS_CONFIG_LOG_VERBOSITY_ERROR; + fprintf(stderr, "Setting verbosity to ERROR\n"); + break; + case 2: verbosity = NDDS_CONFIG_LOG_VERBOSITY_WARNING; + fprintf(stderr, "Setting verbosity to WARNING\n"); + break; + case 3: verbosity = NDDS_CONFIG_LOG_VERBOSITY_STATUS_ALL; + fprintf(stderr, "Setting verbosity to STATUS_ALL\n"); + break; + default: fprintf(stderr, + "Invalid value for the verbosity parameter. Setting verbosity to ERROR (1)\n"); + break; + } + NDDSConfigLogger::get_instance()->set_verbosity(verbosity); + +#else // defined(RTI_PERF_TSS_MICRO) + + OSAPI_LogVerbosity_T verbosity = OSAPI_LOG_VERBOSITY_ERROR; + switch (verbosity_level) { + case 0: verbosity = OSAPI_LOG_VERBOSITY_SILENT; + fprintf(stderr, "Setting verbosity to SILENT\n"); + break; + case 1: verbosity = OSAPI_LOG_VERBOSITY_ERROR; + fprintf(stderr, "Setting verbosity to ERROR\n"); + break; + case 2: verbosity = OSAPI_LOG_VERBOSITY_WARNING; + fprintf(stderr, "Setting verbosity to WARNING\n"); + break; + case 3: verbosity = OSAPI_LOG_VERBOSITY_DEBUG; + fprintf(stderr, "Setting verbosity to STATUS_ALL\n"); + break; + default: fprintf(stderr, + "Invalid value for the verbosity parameter. Setting verbosity to ERROR (1)\n"); + break; + } + OSAPI_Log_set_verbosity(verbosity); + +#endif +} + +/* RTITSSImpl implementation */ +template +bool RTITSSImpl::initialize(ParameterManager &PM, perftest_cpp *parent) +{ + UNUSED_ARG(parent); + + FACE::RETURN_CODE_TYPE::Value retcode; + + _pm = &PM; + _transport.initialize(_pm); + if (!validate_input()) { + fprintf(stderr, "Failed to validate test input\n"); + return false; + } + + _customConfig = new CustomConfiguration(_type_name); + + _tss->Set_Reference("ThisIsIgnored", &_customConfig, 0, retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + fprintf(stderr, "Failed Set_Reference (rc=%d)\n", retcode); + return false; + } + + if (!SetSystemConfig(_customConfig, "perftest")) + { + fprintf(stderr, "Failed to set SystemConfig\n"); + return false; + } + + ((CustomConfiguration*)_tss)->Initialize("perftest", retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + fprintf(stderr, "Failed Initialize(rc=%d)\n", retcode); + return false; + } + + if (!SetDomainParticipantConfig("domain_0")) + { + fprintf(stderr, "Failed to set DomainParticipantConfig\n"); + return false; + } + + if (_pm->get("latencyTest")) { + _pong_semaphore = PerftestSemaphore_new(); + if (_pong_semaphore == NULL) { + fprintf(stderr, "Failed create pong semaphore\n"); + return false; + } + } + + return true; +} + +template +DDS_Boolean +RTITSSImpl::SetDomainParticipantConfig( + const char* domain_cfg_name) +{ + QoSBundle* participant_qos_bundle = new QoSBundle; + + participant_qos_bundle->pm = _pm; + participant_qos_bundle->transport = &_transport; + + participant_qos_bundle->topic_name = "ThisIsIgnored"; + + // instanceMaxCountReader is not used for configuring participant QoS + participant_qos_bundle->instanceMaxCountReader = 0; + + participant_qos_bundle->isLargeData = &_isLargeData; + + participant_qos_bundle->maxSynchronousSize = &_maxSynchronousSize; + + FACE::RETURN_CODE_TYPE::Value return_code; + FACE::Configuration::HANDLE_TYPE domain_config_handler; + FACE::Configuration::BUFFER_SIZE_TYPE bytes_read = 0; + RTI_TSS_DDS_DomainParticipant_Configuration_T* domain_config = NULL; + + _customConfig->Open( + RTI_TSS_DOMAIN_PARTICIPANT_CONFIGURATION_CONTAINER_NAME, + domain_config_handler, + return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + + _customConfig->Read( + domain_config_handler, + domain_cfg_name, + (void *)&domain_config, + sizeof(&domain_config), + bytes_read, + return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + if (domain_config == NULL) + { + return false; + } + + domain_config->domain_id = _pm->get("domain"); + + domain_config->user_data = (void*)participant_qos_bundle; + domain_config->configure_domain_participant_qos_fn = + RTI_TSS_participant_qos; + + return true; +} + +template +DDS_Boolean +RTITSSImpl::GetSystemConfig( + FACE::Configuration *configuration, + const FACE::CONFIGURATION_RESOURCE &name, + RTI_TSS_System_Configuration_T *&sys_cfg) +{ + FACE::RETURN_CODE_TYPE::Value return_code; + FACE::Configuration::HANDLE_TYPE system_config_handler; + FACE::Configuration::BUFFER_SIZE_TYPE bytes_read = 0; + + configuration->Initialize(name, return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + + configuration->Open( + RTI_TSS_SYSTEM_CONFIGURATION_CONTAINER_NAME, + system_config_handler, + return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + + configuration->Read( + system_config_handler, + name, + (void *)&sys_cfg, + sizeof(&sys_cfg), + bytes_read, + return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + if (sys_cfg == NULL) + { + return false; + } + + return true; +} + +template +DDS_Boolean +RTITSSImpl::SetSystemConfig( + FACE::Configuration *configuration, + const FACE::CONFIGURATION_RESOURCE &name) +{ + RTI_TSS_System_Configuration_T *sys_config = NULL; + + if (!GetSystemConfig(configuration, name, sys_config)) + { + printf("Failed to get system config\n"); + return DDS_BOOLEAN_FALSE; + } + +#ifdef RTI_PERF_TSS_MICRO + sys_config->max_connections = 3; + sys_config->max_topics = 3; +#endif + +#ifdef RTI_PERF_TSS_PRO + if (!_pm->get("noXmlQos")) + { + sys_config->xml_qos_file = + DDS_String_dup(_pm->get("qosFile").c_str()); + sys_config->qos_library = + DDS_String_dup(_pm->get("qosLibrary").c_str()); + sys_config->qos_profile = DDS_String_dup("BaseProfileQos"); + } +#endif + + return DDS_BOOLEAN_TRUE; +} + +template +void RTITSSImpl::shutdown() +{ + FACE::RETURN_CODE_TYPE::Value retcode; + + for (unsigned long i = 0; i < _connections.size(); ++i) { + _tss->Destroy_Connection(_connections[i], retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + fprintf(stderr, "Failed destroy connection (rc=%d)\n", retcode); + } + } + + if(_pong_semaphore != NULL) { + PerftestSemaphore_delete(_pong_semaphore); + _pong_semaphore = NULL; + } +} + +/********************************************************* + + * Validate and manage the parameters + */ +template +bool RTITSSImpl::validate_input() +{ + // Manage parameter -instance + if (_pm->is_set("instances")) { + _instanceMaxCountReader = _pm->get("instances"); + } + + // Manage parameter -writeInstance + if (_pm->is_set("writeInstance")) { + if (_pm->get("instances") < _pm->get("writeInstance")) { + fprintf(stderr, + "Specified '-WriteInstance' (%ld) invalid: " + "Bigger than the number of instances (%ld).\n", + _pm->get("writeInstance"), + _pm->get("instances")); + return false; + } + } + + // Manage parameter -peer + if (_pm->get_vector("peer").size() >= RTIPERFTEST_MAX_PEERS) { + fprintf(stderr, + "The maximum of 'initial_peers' is %d\n", + RTIPERFTEST_MAX_PEERS); + return false; + } + + // Manage parameter -batchSize + if (_pm->get("batchSize") > 0) { + // We will not use batching for a latency test + if (_pm->get("latencyTest")) { + if (_pm->is_set("batchSize")) { + fprintf(stderr, "Batching cannot be used in a Latency test.\n"); + return false; + } else { + _pm->set("batchSize", 0); // Disable Batching + } + } + } + + // Manage transport parameter + if (!_transport.validate_input()) { + fprintf(stderr, "Failure validating the transport options.\n"); + return false; + }; + + /* + * Manage parameter -verbosity. + * Setting verbosity if the parameter is provided + */ + if (_pm->is_set("verbosity")) { + configure_middleware_verbosity(_pm->get("verbosity")); + } + + return true; +} + +template +std::string RTITSSImpl::print_configuration() +{ + std::ostringstream stringStream; + + stringStream << std::endl << "TSS Configuration:" << std::endl; + + stringStream << "\tDomain: " << _pm->get("domain") << std::endl; + + stringStream << "\tFACE Profile: "; +#if ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_NONE + stringStream << "None"; +#elif ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_SECURITY + stringStream << "Security"; +#elif ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_SAFETY_BASE + stringStream << "Safety Base"; +#elif ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_SAFETY_EXTENDED + stringStream << "Safety Extended"; +#elif ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_GENERAL + stringStream << "General Purpose"; +#else + #warning "Unknown FACE profile"; + stringStream << "Unknown - " << ENABLE_FACE_COMPLIANCE; +#endif + + stringStream << std::endl; + + stringStream << "\tXML File: " << _pm->get("qosFile") << std::endl; + + stringStream << std::endl << _transport.printTransportConfigurationSummary(); + + return stringStream.str(); +} + +template +FACE::TSS::CONNECTION_ID_TYPE RTITSSImpl::_createConnection( + std::string connection_name, + std::string topic_name, + FACE::RETURN_CODE_TYPE::Value &retcode) +{ + FACE::TSS::MESSAGE_SIZE_TYPE max_message_size; + FACE::TSS::CONNECTION_ID_TYPE connection_id; + FACE::TIMEOUT_TYPE timeout(0); + + InstrumentConnection(connection_name.c_str(), topic_name.c_str()); + + _tss->Create_Connection(connection_name.c_str(), + timeout, + connection_id, + max_message_size, + retcode); + + return connection_id; +} + +template +DDS_Boolean +RTITSSImpl::InstrumentConnection( + const FACE::TSS::CONNECTION_NAME_TYPE &connection_name, + const char* topic_name) +{ + RTI_TSS_Connection_Configuration_T *connection_config = NULL; + QoSBundle* connection_qos_bundle = new QoSBundle; + + connection_qos_bundle->pm = _pm; + connection_qos_bundle->transport = &_transport; + + connection_qos_bundle->topic_name = const_cast(topic_name); + + connection_qos_bundle->instanceMaxCountReader = _instanceMaxCountReader; + + connection_qos_bundle->isLargeData = &_isLargeData; + + connection_qos_bundle->maxSynchronousSize = &_maxSynchronousSize; + + if (!GetConnectionConfig(connection_name, connection_config)) + { + printf("Failed to get connection config.\n"); + return DDS_BOOLEAN_FALSE; + } + +#ifdef RTI_PERF_TSS_PRO + if (!_pm->get("noXmlQos")) + { + connection_config->qos_library = + DDS_String_dup(_pm->get("qosLibrary").c_str()); + connection_config->qos_profile = + DDS_String_dup(get_qos_profile_name(topic_name).c_str()); + } +#endif + + connection_config->user_data = (void *)connection_qos_bundle; + + connection_config->configure_datawriter_qos_fn = RTI_TSS_datawriter_qos; + connection_config->configure_datareader_qos_fn = RTI_TSS_datareader_qos; + + return DDS_BOOLEAN_TRUE; +} + +template +DDS_Boolean +RTITSSImpl::GetConnectionConfig( + const FACE::TSS::CONNECTION_NAME_TYPE &connection_name, + RTI_TSS_Connection_Configuration_T *&connection_config) +{ + FACE::RETURN_CODE_TYPE::Value return_code; + FACE::Configuration::HANDLE_TYPE connection_config_handler; + FACE::Configuration::BUFFER_SIZE_TYPE bytes_read = 0; + + _customConfig->Open( + RTI_TSS_CONNECTION_CONFIGURATION_CONTAINER_NAME, + connection_config_handler, + return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + + _customConfig->Read( + connection_config_handler, + connection_name, + (void *)&connection_config, + sizeof(&connection_config), + bytes_read, + return_code); + if (return_code != FACE::RETURN_CODE_TYPE::NO_ERROR) + { + return false; + } + if (connection_config == NULL) + { + return false; + } + + return true; +} + +template +IMessagingWriter *RTITSSImpl::create_writer(const char *topic_name) +{ + std::string name = "writer " + std::string(topic_name); + FACE::TSS::CONNECTION_ID_TYPE connection_id; + FACE::RETURN_CODE_TYPE::Value retcode; + + connection_id = _createConnection(name, std::string(topic_name), retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + fprintf(stderr, "Failed Create_Connection %s (writer) (rc=%d)\n", + name.c_str(), retcode); + return NULL; + } + + _connections.push_back(connection_id); + + return new RTITSSPublisher( + connection_id, + _pm->get("instances"), + _pong_semaphore, + _pm->get("writeInstance"), + _pm->get("loaningSendReceive")); +} + +template +IMessagingReader *RTITSSImpl::create_reader(const char *topic_name, + IMessagingCB *callback) +{ + std::string name = "reader " + std::string(topic_name); + FACE::TSS::CONNECTION_ID_TYPE connection_id; + FACE::RETURN_CODE_TYPE::Value retcode; + + connection_id = _createConnection(name, std::string(topic_name), retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + fprintf(stderr, "Failed Create_Connection %s (reader) (rc=%d)\n", + name.c_str(), retcode); + return NULL; + } + + _connections.push_back(connection_id); + + return new RTITSSSubscriber( + connection_id, + _pm->get("instances"), + _pong_semaphore, + _pm->get("writeInstances"), + callback, + _pm->get("loaningSendReceive")); +} + +template +unsigned long RTITSSImpl::get_initial_burst_size() +{ + return _pm->get("sendQueueSize"); +} + +#ifdef RTI_PERF_TSS_PRO + +template <> +int RTITSSImpl::_serializeTyped( + FACE::DM::TestData_t *data, unsigned int &size) +{ + return FACE_DM_TestData_tPlugin_serialize_to_cdr_buffer(NULL, &size, (FACE_DM_TestData_t *)data); +} + +template <> +int RTITSSImpl::_serializeTyped( + FACE::DM::TestDataLarge_t *data, unsigned int &size) +{ + return FACE_DM_TestDataLarge_tPlugin_serialize_to_cdr_buffer(NULL, &size, (FACE_DM_TestDataLarge_t *)data); +} + + +template <> +int RTITSSImpl::_serializeTyped( + FACE::DM::TestDataKeyed_t *data, unsigned int &size) +{ + return FACE_DM_TestDataKeyed_tPlugin_serialize_to_cdr_buffer(NULL, &size, (FACE_DM_TestDataKeyed_t *)data); +} + +template <> +int RTITSSImpl::_serializeTyped( + FACE::DM::TestDataKeyedLarge_t *data, unsigned int &size) +{ + return FACE_DM_TestDataKeyedLarge_tPlugin_serialize_to_cdr_buffer(NULL, &size, (FACE_DM_TestDataKeyedLarge_t *)data); +} + +template +bool RTITSSImpl::get_serialized_overhead_size(unsigned int &overhead_size) +{ + Type data; + data.entity_id = 0; + data.seq_num = 0; + data.timestamp_sec = 0; + data.timestamp_usec = 0; + data.latency_ping = 0; + + if (!DDS_OctetSeq_ensure_length((DDS_OctetSeq*)&data.bin_data, 0, 0)) { + fprintf(stderr, "Failed DDS_OctetSeq_ensure_length\n"); + return false; + } + + if (_serializeTyped(&data, overhead_size) != DDS_RETCODE_OK) { + fprintf(stderr, "Failed to serialize to CDR buffer\n"); + return false; + } + + overhead_size -= RTI_CDR_ENCAPSULATION_HEADER_SIZE; + + return true; +} + +#endif /* RTI_PERF_TSS_PRO */ + +/* RTITSSPublisher implementation */ +template +RTITSSPublisher::RTITSSPublisher( + FACE::TSS::CONNECTION_ID_TYPE connection_id, + unsigned long num_instances, + PerftestSemaphore * pongSemaphore, + long instancesToBeWritten, + bool loaning) + : TSSConnection(connection_id, + num_instances, + instancesToBeWritten, + loaning), + _pong_semaphore(pongSemaphore) +{ + DDS_DataWriterQos qos; + DDS_DataWriterQos_initialize(&qos); + DDS_DataWriter_get_qos(this->_writer, &qos); + _is_reliable = (qos.reliability.kind == DDS_RELIABLE_RELIABILITY_QOS); + + if (!loaning) + { + this->_send_function = &TSSConnection::_send; + } + else + { + this->_send_function = &TSSConnection::_send_loaning; + } +} + +template +bool RTITSSPublisher::send(const TestMessage &message, + bool isCftWildCardKey) +{ + return (this->*_send_function)(message, isCftWildCardKey); +} + +template +void RTITSSPublisher::wait_for_ack(int sec, unsigned int nsec) +{ +#ifdef RTI_PERF_TSS_PRO + if (_is_reliable) { + DDS_Duration_t timeout = {sec, nsec}; + DDS_DataWriter_wait_for_acknowledgments(this->_writer, &timeout); + } else { + PerftestClock::milliSleep(nsec / 1000000); + } +#else + UNUSED_ARG(sec); +#endif + + // Since there is no implementation of wait_for_ack() in Micro 2.4.x, + // an sleep is performed in both reliable and best-effort + PerftestClock::milliSleep(nsec / 1000000); +} + +template +void RTITSSPublisher::wait_for_readers(int numSubscribers) +{ + DDS_PublicationMatchedStatus status; + DDS_ReturnCode_t retcode; + + while (true) { + retcode = DDS_DataWriter_get_publication_matched_status(this->_writer, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "WaitForReaders failed: %d\n", retcode); + } + + if (status.current_count >= numSubscribers) { + break; + } + + PerftestClock::milliSleep(PERFTEST_DISCOVERY_TIME_MSEC); + } +} + +template +bool RTITSSPublisher::wait_for_ping_response() +{ + if(_pong_semaphore != NULL) { + if (!PerftestSemaphore_take( + _pong_semaphore, PERFTEST_SEMAPHORE_TIMEOUT_INFINITE)) { + fprintf(stderr, "Error taking semaphore\n"); + return false; + } + } + + return true; +} + +template +bool RTITSSPublisher::wait_for_ping_response(int timeout) +{ + if(_pong_semaphore != NULL) { + if (!PerftestSemaphore_take(_pong_semaphore, timeout)) { + fprintf(stderr, "Error taking semaphore\n"); + return false; + } + } + + return true; +} + +template +bool RTITSSPublisher::notify_ping_response() +{ + if(_pong_semaphore != NULL) { + if (!PerftestSemaphore_give(_pong_semaphore)) { + fprintf(stderr, "Error giving semaphore\n"); + return false; + } + } + + return true; +} + +template +unsigned int RTITSSPublisher::get_pulled_sample_count() +{ +#ifdef RTI_PERF_TSS_PRO + DDS_DataWriterProtocolStatus status; + DDS_ReturnCode_t retcode; + + retcode = DDS_DataWriter_get_datawriter_protocol_status(this->_writer, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "Error getting protocol status\n"); + return -1; + } + + return (unsigned int) status.pulled_sample_count; +#else + // Not supported in Micro + return 0; +#endif +} + +template +unsigned int RTITSSPublisher::get_sample_count() +{ +#ifdef RTI_PERF_TSS_PRO + DDS_DataWriterCacheStatus status; + DDS_ReturnCode_t retcode; + + retcode = DDS_DataWriter_get_datawriter_cache_status(this->_writer, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "get_datawriter_cache_status failed: %d.\n", retcode); + return -1; + } + + return (unsigned int) status.sample_count; +#else + // Not supported in Micro + return 0; +#endif +} + +template +unsigned int RTITSSPublisher::get_sample_count_peak() +{ +#ifdef RTI_PERF_TSS_PRO + DDS_DataWriterCacheStatus status; + DDS_ReturnCode_t retcode; + + retcode = DDS_DataWriter_get_datawriter_cache_status(this->_writer, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "get_datawriter_cache_status failed: %d.\n", retcode); + return -1; + } + + return (unsigned int)status.sample_count_peak; +#else + // Not supported in Micro + return 0; +#endif +} + + +/* RTITSSSubscriber Implementation */ +template +RTITSSSubscriber::RTITSSSubscriber( + FACE::TSS::CONNECTION_ID_TYPE connection_id, + unsigned long num_instances, + PerftestSemaphore * pongSemaphore, + long instancesToBeWritten, + IMessagingCB *callback, + bool loaning) + : TSSConnection(connection_id, + num_instances, + instancesToBeWritten, + loaning, + callback), + _pong_semaphore(pongSemaphore) +{ + if (!loaning) + { + this->_receive_function = &TSSConnection::_receive; + } + else + { + this->_receive_function = &TSSConnection::_receive_loaning; + } +} + +template +TestMessage *RTITSSSubscriber::receive_message() +{ + return (this->*_receive_function)(); +} + +template +void RTITSSSubscriber::wait_for_writers(int numPublishers) +{ + DDS_SubscriptionMatchedStatus status; + DDS_ReturnCode_t retcode; + + while (true) { + retcode = DDS_DataReader_get_subscription_matched_status(this->_reader, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "wait_for_writers failed: %d\n", retcode); + } + + if (status.current_count >= numPublishers) { + break; + } + + PerftestClock::milliSleep(PERFTEST_DISCOVERY_TIME_MSEC); + } +} + +template +unsigned int RTITSSSubscriber::get_sample_count() +{ +#ifdef RTI_PERF_TSS_PRO + DDS_DataReaderCacheStatus status; + DDS_ReturnCode_t retcode; + + retcode = DDS_DataReader_get_datareader_cache_status(this->_reader, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "get_datareader_cache_status failed: %d.\n", retcode); + return -1; + } + + return (unsigned int)status.sample_count; +#else + // Not supported in Micro + return 0; +#endif +} + +template +unsigned int RTITSSSubscriber::get_sample_count_peak() +{ +#ifdef RTI_PERF_TSS_PRO + DDS_DataReaderCacheStatus status; + DDS_ReturnCode_t retcode; + + retcode = DDS_DataReader_get_datareader_cache_status(this->_reader, &status); + if (retcode != DDS_RETCODE_OK) { + fprintf(stderr, "get_datareader_cache_status failed: %d.\n", retcode); + return -1; + } + + return (unsigned int)status.sample_count_peak; +#else + // Not supported in Micro + return 0; +#endif +} + +template +TSSConnection::TSSConnection(FACE::TSS::CONNECTION_ID_TYPE connection_id, + unsigned long num_instances, + long instancesToBeWritten, + bool loaning, + IMessagingCB *callback) + : _connection_id(connection_id), _typedTS(new TypedTS), _typedCB(NULL) +{ + _num_instances = num_instances; + _instancesToBeWritten = instancesToBeWritten; + _instance_counter = 0; + + RTI_TSS_Impl *rti_tss = NULL; + DDS_DomainParticipant *participant = NULL; + FACE::RETURN_CODE_TYPE::Value retcode; + FACE_CONNECTION_DIRECTION_TYPE direction; + struct RTI_TSS_ConnectionEntry *connection_entry = NULL; + bool set_writer = false; + bool set_reader = false; + + rti_tss = RTI_TSS_Impl_get_instance(); + if (rti_tss == NULL) { + fprintf(stderr, "Failed to get TSS impl instance.\n"); + return; + } + + connection_entry = RTI_TSS_ConnectionManager_lookup_connection_id( + rti_tss->connection_mgr, _connection_id); + if (connection_entry == NULL) { + fprintf(stderr, "Failed to get connection entry.\n"); + return; + } + + participant = connection_entry->participant; + if (participant == NULL) { + fprintf(stderr, "Failed to get participant from connection.\n"); + return; + } + + direction = RTI_TSS_ConnectionEntry_get_connection_direction(connection_entry); + if (direction == FACE_SOURCE) { + set_writer = true; + } else if (direction == FACE_DESTINATION) { + set_reader = true; + } else { + set_writer = true; + set_reader = true; + } + + if (set_writer) { + _writer = connection_entry->writer; + if (_writer == NULL) { + fprintf(stderr, "Failed to get writer from connection.\n"); + return; + } + } + + if (set_reader) { + _reader = connection_entry->reader; + if (_reader == NULL) { + fprintf(stderr, "Failed to get reader from connection.\n"); + return; + } + } + + if (callback != NULL) { + if (!loaning) + { + _typedCB = new TSSListener(callback); + } + else + { + _typedCB = new TSSListenerLoaning(callback); + } + _typedTS->Register_Callback(_connection_id, *_typedCB, retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + printf("Failed Register_Callback (rc=%d)\n", retcode); + return; + } + } +} + +template +TSSConnection::~TSSConnection() +{ + if (_typedTS != NULL) delete _typedTS; + if (_typedCB != NULL) delete _typedCB; +} + +template +inline bool TSSConnection::_send( + const TestMessage &message, + bool isCftWildCardKey) +{ + FACE::RETURN_CODE_TYPE::Value retcode; + FACE::TSS::TRANSACTION_ID_TYPE transaction_id(0); + FACE::TIMEOUT_TYPE timeout(0); + unsigned long key = MAX_CFT_VALUE; + int seq_length = 0; + + // Calculate key and add it if using more than one instance + if (!isCftWildCardKey) { + if (_num_instances > 1) { + if (_instancesToBeWritten == -1) { + key = _instance_counter++ % _num_instances; + } else { // send sample to a specific subscriber + key = _instancesToBeWritten; + } + } + } + + for (int c = 0; c < KEY_SIZE; ++c) { + _sample.key[c] = (unsigned char)(key >> c * 8); + } + + _sample.entity_id = message.entity_id; + _sample.seq_num = message.seq_num; + _sample.timestamp_sec = message.timestamp_sec; + _sample.timestamp_usec = message.timestamp_usec; + _sample.latency_ping = message.latency_ping; + + seq_length = DDS_OctetSeq_get_length((const DDS_OctetSeq*)&_sample.bin_data); + + if (seq_length != message.size) + { + _sample.bin_data.clear(); + DDS_OctetSeq_set_length((DDS_OctetSeq*)&_sample.bin_data, message.size); + } + + memcpy(_sample.bin_data.buffer(), message.data, message.size); + + _typedTS->Send_Message(_connection_id, + timeout, + transaction_id, /* not used */ + _sample, + retcode); + + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + fprintf(stderr, "Failed Send_Message (rc=%d)\n", retcode); + return false; + } + + return true; +} + +template +inline bool TSSConnection::_send_loaning( + const TestMessage &message, + bool isCftWildCardKey) +{ + FACE::RETURN_CODE_TYPE::Value retcode; + FACE::TSS::TRANSACTION_ID_TYPE transaction_id(0); + FACE::TIMEOUT_TYPE timeout(0); + unsigned long key = MAX_CFT_VALUE; + + // Calculate key and add it if using more than one instance + if (!isCftWildCardKey) { + if (_num_instances > 1) { + if (_instancesToBeWritten == -1) { + key = _instance_counter++ % _num_instances; + } else { // send sample to a specific subscriber + key = _instancesToBeWritten; + } + } + } + + for (int c = 0; c < KEY_SIZE; ++c) { + _sample.key[c] = (unsigned char)(key >> c * 8); + } + + _sample.entity_id = message.entity_id; + _sample.seq_num = message.seq_num; + _sample.timestamp_sec = message.timestamp_sec; + _sample.timestamp_usec = message.timestamp_usec; + _sample.latency_ping = message.latency_ping; + + DDS_OctetSeq_set_maximum((DDS_OctetSeq*)&_sample.bin_data, 0); + +#ifdef RTI_PERF_TSS_PRO + if (!DDS_OctetSeq_loan_contiguous((DDS_OctetSeq*)&_sample.bin_data, + (DDS_Octet*) message.data, + message.size, message.size)) { + fprintf(stderr, "bin_data.loan_contiguous() failed.\n"); + return false; + } +#else + if (!CDR_OctetSeq_loan_contiguous((CDR_OctetSeq*)&_sample.bin_data, + (DDS_Octet*) message.data, + message.size, message.size)) { + fprintf(stderr, "bin_data.loan_contiguous() failed.\n"); + return false; + } +#endif // RTI_PERF_TSS_PRO + + _typedTS->Send_Message(_connection_id, + timeout, + transaction_id, /* not used */ + _sample, + retcode); + +#ifdef RTI_PERF_TSS_PRO + if (!DDS_OctetSeq_unloan((DDS_OctetSeq*)&_sample.bin_data)) { + fprintf(stderr, "bin_data.unloan() failed.\n"); + return false; + } +#else + if (!CDR_OctetSeq_unloan((CDR_OctetSeq*)&_sample.bin_data)) { + fprintf(stderr, "bin_data.unloan() failed.\n"); + return false; + } +#endif // RTI_PERF_TSS_PRO + + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + fprintf(stderr, "Failed Send_Message (rc=%d)\n", retcode); + return false; + } + + return true; +} + +template +inline TestMessage* TSSConnection::_receive() +{ + FACE::RETURN_CODE_TYPE::Value retcode; + FACE::TSS::TRANSACTION_ID_TYPE transaction_id(0); + FACE::TSS::QoS_EVENT_TYPE qos_parameters; + FACE::TSS::HEADER_TYPE header; + FACE::TIMEOUT_TYPE timeout(0); + int seq_length; + + _typedTS->Receive_Message(_connection_id, + timeout, + transaction_id, /* not used */ + _sample, + header, /* not used */ + qos_parameters, /* not used */ + retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + if (retcode != FACE::RETURN_CODE_TYPE::NOT_AVAILABLE && + retcode != FACE::RETURN_CODE_TYPE::TIMED_OUT) + fprintf(stderr, "!Failed Receive_Message (rc=%d)\n", retcode); + + return NULL; + } + + _message.entity_id = _sample.entity_id; + _message.seq_num = _sample.seq_num; + _message.timestamp_sec = _sample.timestamp_sec; + _message.timestamp_usec = _sample.timestamp_usec; + _message.latency_ping = _sample.latency_ping; + + seq_length = DDS_OctetSeq_get_length((const DDS_OctetSeq*)&_sample.bin_data); + + if (seq_length != _message.size) + { + free(_message.data); + _message.data = (char*)malloc(seq_length); + } + + memcpy(_message.data, _sample.bin_data.buffer(), seq_length); + + _message.size = seq_length; + + return &_message; +} + +template +inline TestMessage* TSSConnection::_receive_loaning() +{ + FACE::RETURN_CODE_TYPE::Value retcode; + FACE::TSS::TRANSACTION_ID_TYPE transaction_id(0); + FACE::TSS::QoS_EVENT_TYPE qos_parameters; + FACE::TSS::HEADER_TYPE header; + FACE::TIMEOUT_TYPE timeout(0); + + _typedTS->Receive_Message(_connection_id, + timeout, + transaction_id, /* not used */ + _sample, + header, /* not used */ + qos_parameters, /* not used */ + retcode); + if (retcode != FACE::RETURN_CODE_TYPE::NO_ERROR) { + if (retcode != FACE::RETURN_CODE_TYPE::NOT_AVAILABLE && + retcode != FACE::RETURN_CODE_TYPE::TIMED_OUT) + fprintf(stderr, "!Failed Receive_Message (rc=%d)\n", retcode); + + return NULL; + } + + _message.entity_id = _sample.entity_id; + _message.seq_num = _sample.seq_num; + _message.timestamp_sec = _sample.timestamp_sec; + _message.timestamp_usec = _sample.timestamp_usec; + _message.latency_ping = _sample.latency_ping; + _message.size = DDS_OctetSeq_get_length((const DDS_OctetSeq*)&_sample.bin_data); + _message.data = (char *) DDS_OctetSeq_get_contiguous_buffer((const DDS_OctetSeq*)&_sample.bin_data); + + return &_message; +} + + +template +void TSSListener::Callback_Handler( + FACE::TSS::CONNECTION_ID_TYPE connection_id, + FACE::TSS::TRANSACTION_ID_TYPE transaction_id, + const Type& sample, + const FACE::TSS::HEADER_TYPE& header, + const FACE::TSS::QoS_EVENT_TYPE& qos_parameters, + FACE::RETURN_CODE_TYPE::Value& return_code) +{ + UNUSED_ARG(connection_id); + UNUSED_ARG(transaction_id); + UNUSED_ARG(header); + UNUSED_ARG(qos_parameters); + UNUSED_ARG(return_code); + + int seq_length = 0; + + _message.entity_id = sample.entity_id; + _message.seq_num = sample.seq_num; + _message.timestamp_sec = sample.timestamp_sec; + _message.timestamp_usec = sample.timestamp_usec; + _message.latency_ping = sample.latency_ping; + seq_length = DDS_OctetSeq_get_length((const DDS_OctetSeq*)&sample.bin_data); + + if (seq_length != _message.size) + { + free(_message.data); + _message.data = (char*)malloc(seq_length); + } + + memcpy(_message.data, sample.bin_data.buffer(), seq_length); + + _message.size = seq_length; + + _callback->process_message(_message); +} + +template +void TSSListenerLoaning::Callback_Handler( + FACE::TSS::CONNECTION_ID_TYPE connection_id, + FACE::TSS::TRANSACTION_ID_TYPE transaction_id, + const Type& sample, + const FACE::TSS::HEADER_TYPE& header, + const FACE::TSS::QoS_EVENT_TYPE& qos_parameters, + FACE::RETURN_CODE_TYPE::Value& return_code) +{ + UNUSED_ARG(connection_id); + UNUSED_ARG(transaction_id); + UNUSED_ARG(header); + UNUSED_ARG(qos_parameters); + UNUSED_ARG(return_code); + + this->_message.entity_id = sample.entity_id; + this->_message.seq_num = sample.seq_num; + this->_message.timestamp_sec = sample.timestamp_sec; + this->_message.timestamp_usec = sample.timestamp_usec; + this->_message.latency_ping = sample.latency_ping; + this->_message.size = DDS_OctetSeq_get_length((const DDS_OctetSeq*)&sample.bin_data); + this->_message.data = (char *) DDS_OctetSeq_get_contiguous_buffer((const DDS_OctetSeq*)&sample.bin_data); + + this->_callback->process_message(this->_message); +} + +template class RTITSSImpl; +template class RTITSSImpl; +template class RTITSSImpl; +template class RTITSSImpl; \ No newline at end of file diff --git a/srcCpp/connextDDS/TSS/RTITSSImpl.h b/srcCpp/connextDDS/TSS/RTITSSImpl.h new file mode 100644 index 00000000..480b8379 --- /dev/null +++ b/srcCpp/connextDDS/TSS/RTITSSImpl.h @@ -0,0 +1,272 @@ +#ifndef __RTITSSIMPL_H__ +#define __RTITSSIMPL_H__ + +#ifdef RTI_PERF_TSS + +#include "Infrastructure_common.h" +#include "MessagingIF.h" + +#include "perftest_cpp.h" +#include "perftest.hpp" +#include "perftestSupport.h" +#include "perftestPlugin.h" +#include "FACE/DM/TestData_t/TypedTS_Impl.hpp" +#include "FACE/DM/TestDataLarge_t/TypedTS_Impl.hpp" +#include "FACE/DM/TestDataKeyed_t/TypedTS_Impl.hpp" +#include "FACE/DM/TestDataKeyedLarge_t/TypedTS_Impl.hpp" +#include "RTI/TSS/Base.hpp" + +#include "CustomQosSupport.hpp" + +#ifdef RTI_CONNEXT_MICRO +#include "dds_c/dds_c_config.h" +#define RTI_TSS_CONNEXT_VERSION "RTI Connext DDS Micro " \ + STR(RTIME_DDS_VERSION_MAJOR) "." \ + STR(RTIME_DDS_VERSION_MINOR) "." \ + STR(RTIME_DDS_VERSION_REVISION) "." \ + STR(RTIME_DDS_VERSION_RELEASE) +#else +#include "ndds/ndds_version.h" +#define STR_HELPER(x_) #x_ +#define STR(x_) STR_HELPER(x_) +#define RTI_TSS_CONNEXT_VERSION "RTI Connext DDS Professional " \ + STR(RTI_DDS_VERSION_MAJOR) "." \ + STR(RTI_DDS_VERSION_MINOR) "." \ + STR(RTI_DDS_VERSION_RELEASE) "." \ + STR(RTI_DDS_VERSION_REVISION) +#endif + +#define RTI_TSS_VERSION "RTI Connext TSS " \ + STR(RTI_TSS_VERSION_MAJOR) "." \ + STR(RTI_TSS_VERSION_MINOR) "." \ + STR(RTI_TSS_VERSION_REVISION) "." \ + STR(RTI_TSS_VERSION_RELEASE) + +#define RTI_TSS_VER_INFO_STR "RTI_TSS_VERSION: " \ + RTI_TSS_VERSION " using " \ + RTI_TSS_CONNEXT_VERSION + +#define RTIPERFTEST_MAX_PEERS 1024 + +const std::string GetMiddlewareVersionString(); + +template +class TSSListener : public TypedCB +{ +protected: + IMessagingCB *_callback; + TestMessage _message; + +public: + TSSListener(IMessagingCB *callback) + : _callback(callback), _message() {} + + virtual void Callback_Handler( + FACE::TSS::CONNECTION_ID_TYPE connection_id, + FACE::TSS::TRANSACTION_ID_TYPE transaction_id, + const Type& sample, + const FACE::TSS::HEADER_TYPE& header, + const FACE::TSS::QoS_EVENT_TYPE& qos_parameters, + FACE::RETURN_CODE_TYPE::Value& return_code); +}; + +template +class TSSListenerLoaning : public TSSListener +{ +public: + TSSListenerLoaning(IMessagingCB *callback) + : TSSListener(callback) {}; + + void Callback_Handler( + FACE::TSS::CONNECTION_ID_TYPE connection_id, + FACE::TSS::TRANSACTION_ID_TYPE transaction_id, + const Type& sample, + const FACE::TSS::HEADER_TYPE& header, + const FACE::TSS::QoS_EVENT_TYPE& qos_parameters, + FACE::RETURN_CODE_TYPE::Value& return_code) override; +}; + +template +class TSSConnection +{ +private: + FACE::TSS::CONNECTION_ID_TYPE _connection_id; + TypedTS *_typedTS; + TSSListener *_typedCB; + + TestMessage _message; + Type _sample; + + unsigned long _num_instances; + long _instancesToBeWritten; + unsigned long _instance_counter; + + void _registerCallBack(IMessagingCB *callback); + +protected: + DDS_DataWriter *_writer; + DDS_DataReader *_reader; + +public: + TSSConnection(FACE::TSS::CONNECTION_ID_TYPE connection_id, + unsigned long num_instances, + long instancesToBeWritten, + bool loaning, + IMessagingCB *callback = NULL); + ~TSSConnection(); + + // Declared in public section because these functions must be accessible + // from the subclasses + inline bool _send(const TestMessage &message, + bool isCftWildCardKey); + inline bool _send_loaning(const TestMessage &message, + bool isCftWildCardKey); + inline TestMessage* _receive(); + inline TestMessage* _receive_loaning(); +}; + +template +class RTITSSImpl : public IMessaging +{ +private: + std::vector _connections; + RTI::TSS::Base *_tss; + PerftestSemaphore *_pong_semaphore; + PerftestTransport _transport; + ParameterManager *_pm; + + FACE::TSS::CONNECTION_ID_TYPE _createConnection( + std::string topic_name, + std::string name, + FACE::RETURN_CODE_TYPE::Value &retcode); + + /* NOTE: This method is type-specific. It has to be + * defined for each type specifically. + */ + int _serializeTyped(Type *data, unsigned int &size); + + const char* _type_name; + + FACE::Configuration* _customConfig; + + std::map _qoSProfileNameMap; + + const std::string get_qos_profile_name(const char *topicName); + + void configure_middleware_verbosity(int verbosity_level); + + long _instanceMaxCountReader; + + bool _isLargeData; + + unsigned long long _maxSynchronousSize; + + DDS_Boolean + GetSystemConfig( + FACE::Configuration *configuration, + const FACE::CONFIGURATION_RESOURCE &name, + RTI_TSS_System_Configuration_T *&sys_cfg); + + DDS_Boolean + SetSystemConfig( + FACE::Configuration *configuration, + const FACE::CONFIGURATION_RESOURCE &name); + + DDS_Boolean + SetDomainParticipantConfig(const char* domain_cfg_name); + + DDS_Boolean + InstrumentConnection( + const FACE::TSS::CONNECTION_NAME_TYPE &connection_name, + const char* topic_name); + + DDS_Boolean + GetConnectionConfig( + const FACE::TSS::CONNECTION_NAME_TYPE &connection_name, + RTI_TSS_Connection_Configuration_T *&connection_config); + +public: + RTITSSImpl(const char* type_name); + + ~RTITSSImpl() { delete _tss; }; + + bool initialize(ParameterManager &PM, perftest_cpp *parent); + + bool validate_input(); + + void shutdown(); + + std::string print_configuration(); + + IMessagingWriter *create_writer(const char *topic_name); + IMessagingReader *create_reader(const char *topic_name, IMessagingCB *callback); + + bool supports_listener() { return true; } + bool supports_discovery() { return true; } + + unsigned long get_initial_burst_size(); +#ifdef RTI_PERF_TSS_PRO + bool get_serialized_overhead_size(unsigned int &overhead_size); +#endif + + bool supports_listeners() { return true; } +}; + +template +class RTITSSPublisher : public IMessagingWriter, + public TSSConnection +{ +private: + PerftestSemaphore *_pong_semaphore; + bool _is_reliable; + + bool (TSSConnection::*_send_function)(const TestMessage&, bool); + +public: + RTITSSPublisher(FACE::TSS::CONNECTION_ID_TYPE connection_id, + unsigned long num_instances, + PerftestSemaphore * pongSemaphore, + long instancesToBeWritten, + bool loaning); + + bool send(const TestMessage &message, bool isCftWildCardKey = false); + void flush() { /* dummy */ } + + void wait_for_ack(int sec, unsigned int nsec); + void wait_for_readers(int numSubscribers); + bool wait_for_ping_response(); + bool wait_for_ping_response(int timeout); + bool notify_ping_response(); + + unsigned int get_pulled_sample_count(); + unsigned int get_sample_count(); + unsigned int get_sample_count_peak(); +}; + +template +class RTITSSSubscriber : public IMessagingReader, + public TSSConnection +{ +private: + PerftestSemaphore *_pong_semaphore; + + TestMessage* (TSSConnection::*_receive_function)(); + +public: + RTITSSSubscriber(FACE::TSS::CONNECTION_ID_TYPE connection_id, + unsigned long num_instances, + PerftestSemaphore * pongSemaphore, + long instancesToBeWritten, + IMessagingCB *callback, + bool loaning); + + TestMessage *receive_message(); + + void wait_for_writers(int numPublishers); + + unsigned int get_sample_count(); + unsigned int get_sample_count_peak(); +}; + +#endif /* RTI_PERF_TSS */ +#endif /* __RTITSSIMPL_H__ */ \ No newline at end of file diff --git a/srcCpp/connextDDS/micro/Infrastructure_micro.cxx b/srcCpp/connextDDS/micro/Infrastructure_micro.cxx index 9f3d3aec..b48d173b 100644 --- a/srcCpp/connextDDS/micro/Infrastructure_micro.cxx +++ b/srcCpp/connextDDS/micro/Infrastructure_micro.cxx @@ -3,7 +3,7 @@ * Subject to Eclipse Public License v1.0; see LICENSE.md for details. */ -#ifdef PERFTEST_RTI_MICRO +#if defined(PERFTEST_RTI_MICRO) || defined(RTI_PERF_TSS_MICRO) #include "Infrastructure_common.h" @@ -172,7 +172,13 @@ bool configureUDPv4Transport( * We will use the same values we use for Pro (XML) for the buffers * these values can be reduced for a smaller memory footprint. */ +#ifndef RTI_PERF_TSS_MICRO UDP_InterfaceFactoryProperty *udp_property = new UDP_InterfaceFactoryProperty(); +#else + UDP_InterfaceFactoryProperty* udp_property = (struct UDP_InterfaceFactoryProperty *) + malloc(sizeof(struct UDP_InterfaceFactoryProperty)); + *udp_property = UDP_INTERFACE_FACTORY_PROPERTY_DEFAULT; +#endif udp_property->max_message_size = 65536; udp_property->max_receive_buffer_size = 2097152; udp_property->max_send_buffer_size = 524288; @@ -194,13 +200,72 @@ bool configureUDPv4Transport( _PM->get("allowInterfaces").c_str()); return false; } +#ifndef RTI_PERF_TSS_MICRO udp_property->allow_interface.maximum(1); udp_property->allow_interface.length(1); *udp_property->allow_interface.get_reference(0) = DDS_String_dup( _PM->get("allowInterfaces").c_str()); +#else + if (!DDS_StringSeq_set_maximum(&udp_property->allow_interface,1)) + { + printf("failed to set allow_interface maximum\n"); + return false; + } + if (!DDS_StringSeq_set_length(&udp_property->allow_interface,1)) + { + printf("failed to set allow_interface length\n"); + return false; + } + *DDS_StringSeq_get_reference(&udp_property->allow_interface,0) = + DDS_String_dup(_PM->get("allowInterfaces").c_str()); +#endif } +#if defined(RTI_PERF_TSS_MICRO) && FACE_COMPLIANCE_LEVEL_SAFETY_BASE_OR_STRICTER + + /* Safety Base or stricter, with Micro, must manually configure available + * interfaces. + * First we disable reading out the interface list. Note that on some + * platforms reading out the interface list has been compiled out, so + * this property could have no effect. + */ + udp_property->disable_auto_interface_config = RTI_TRUE; + + REDA_StringSeq_set_maximum(&udp_property->allow_interface,1); + REDA_StringSeq_set_length(&udp_property->allow_interface,1); + + /* The name of the interface can be the anything, up to + * UDP_INTERFACE_MAX_IFNAME characters including the '\0' character + */ + *DDS_StringSeq_get_reference(&udp_property->allow_interface,0) = + DDS_String_dup("loopback"); + + /* This function takes the following arguments: + * Param 1 is the iftable in the UDP property + * Param 2 is the IP address of the interface in host order + * Param 3 is the Netmask of the interface + * Param 4 is the name of the interface + * Param 5 are flags. The following flags are supported for Security and + * Safety Base (use OR for multiple): + * UDP_INTERFACE_INTERFACE_UP_FLAG - Interface is up + * + * The following flags are supported for non-Security and non-Safety + * Base: + * UDP_INTERFACE_INTERFACE_MULTICAST_FLAG - Interface supports multicast + */ + RTI_BOOL result; + result = UDP_InterfaceTable_add_entry(&udp_property->if_table, + 0x7f000001,0xff000000,"loopback", + UDP_INTERFACE_INTERFACE_UP_FLAG); + + if (!result) + { + printf("failed UDP table add entry!\n"); + return DDS_BOOLEAN_FALSE; + } +#endif + if (!registry->register_component( NETIO_DEFAULT_UDP_NAME, UDPInterfaceFactory::get_interface(), @@ -218,6 +283,8 @@ bool configureUDPv4Transport( dpde_properties.max_samples_per_remote_builtin_endpoint_writer = 1; #endif +// For TSS, this component is already registered +#ifndef RTI_PERF_TSS_MICRO if (!registry->register_component("dpde", DPDEDiscoveryFactory::get_interface(), &dpde_properties._parent, @@ -228,8 +295,13 @@ bool configureUDPv4Transport( } return false; } +#endif +#ifndef RTI_PERF_TSS_MICRO if (!qos.discovery.discovery.name.set_name("dpde")) { +#else + if (!RT_ComponentFactoryId_set_name(&qos.discovery.discovery.name, "dpde")) { +#endif printf("Micro: Failed to set discovery plugin name\n"); if (udp_property != NULL) { delete udp_property; @@ -254,6 +326,10 @@ bool configureUDPv4Transport( qos.resource_limits.remote_participant_allocation = 8; qos.resource_limits.remote_reader_allocation = 8; qos.resource_limits.remote_writer_allocation = 8; +#ifdef RTI_PERF_TSS_MICRO + qos.resource_limits.local_publisher_allocation = 3; + qos.resource_limits.local_subscriber_allocation = 3; +#endif transport.minimumMessageSizeMax = udp_property->max_message_size; diff --git a/srcCpp/connextDDS/micro/Infrastructure_micro.h b/srcCpp/connextDDS/micro/Infrastructure_micro.h index 19d02003..9a345e2b 100644 --- a/srcCpp/connextDDS/micro/Infrastructure_micro.h +++ b/srcCpp/connextDDS/micro/Infrastructure_micro.h @@ -6,7 +6,7 @@ #ifndef INFRASTRUCTURE_MICRO_H_ #define INFRASTRUCTURE_MICRO_H_ -#ifdef PERFTEST_RTI_MICRO +#if defined(PERFTEST_RTI_MICRO) || defined(RTI_PERF_TSS_MICRO) #include "osapi/osapi_semaphore.h" #include "osapi/osapi_thread.h" @@ -15,6 +15,8 @@ #include "dds_cpp/dds_cpp_dpde.hxx" #include "PerftestTransport.h" +#include "Infrastructure_common.h" + #ifdef RTI_SECURE_PERFTEST #include "sec_core/sec_core_cpp.h" #include "PerftestSecurity.h" @@ -121,6 +123,7 @@ bool PerftestConfigureSecurity( ParameterManager *_PM); #endif +#ifndef RTI_PERF_TSS /********************************************************************/ /* The following structures/classes are copied from RTI Connext DDS */ @@ -266,5 +269,6 @@ class NDDSUtility } }; -#endif // PERFTEST_RTI_MICRO +#endif /* RTI_PERF_TSS */ +#endif /* PERFTEST_RTI_MICRO */ #endif /* INFRASTRUCTURE_MICRO_H_ */ diff --git a/srcCpp/perftest_cpp.cxx b/srcCpp/perftest_cpp.cxx index 95b8091a..0a72261f 100644 --- a/srcCpp/perftest_cpp.cxx +++ b/srcCpp/perftest_cpp.cxx @@ -7,7 +7,9 @@ #define TO_STRING(x) STRINGIFY(x) #include "perftest_cpp.h" -#ifdef PERFTEST_RTI_PRO +#ifdef RTI_PERF_TSS + #include "RTITSSImpl.h" +#elif defined(PERFTEST_RTI_PRO) #include "RTIRawTransportImpl.h" #include "RTIDDSImpl.h" #elif defined(PERFTEST_RTI_MICRO) @@ -163,7 +165,7 @@ int perftest_cpp::Run(int argc, char *argv[]) return -1; } - #if defined(PERFTEST_RTI_PRO) || defined(PERFTEST_RTI_MICRO) + #if defined(PERFTEST_RTI_PRO) || defined(PERFTEST_RTI_MICRO) || defined(RTI_PERF_TSS) if (_PM.get("rawTransport")) { #ifdef PERFTEST_RTI_PRO _MessagingImpl = new RTIRawTransportImpl(); @@ -174,62 +176,96 @@ int perftest_cpp::Run(int argc, char *argv[]) mask += _PM.get("flatdata") << 2; mask += _PM.get("zerocopy") << 3; + #ifndef RTI_PERF_TSS switch (mask) { - case 0: // = 0000 (bounded) - _MessagingImpl = new RTIDDSImpl(); - break; + case 0: // = 0000 (bounded) + _MessagingImpl = new RTIDDSImpl(); + break; - case 1: // unbounded = 0001 - _MessagingImpl = new RTIDDSImpl(); - break; + case 1: // unbounded = 0001 + _MessagingImpl = new RTIDDSImpl(); + break; - case 2: // keyed = 0010 - _MessagingImpl = new RTIDDSImpl(); - break; + case 2: // keyed = 0010 + _MessagingImpl = new RTIDDSImpl(); + break; - case 3: // unbounded + keyed = 0011 - _MessagingImpl = new RTIDDSImpl(); - break; - #ifdef RTI_FLATDATA_AVAILABLE - #ifdef RTI_ZEROCOPY_AVAILABLE - case 15: // unbounded + keyed + flat + zero = 1111 - _MessagingImpl = new RTIDDSImpl_FlatData(true); - break; + case 3: // unbounded + keyed = 0011 + _MessagingImpl = new RTIDDSImpl(); + break; - case 14: // keyed + flat + zero = 1110 - _MessagingImpl = new RTIDDSImpl_FlatData(true); - break; + #ifdef RTI_FLATDATA_AVAILABLE + #ifdef RTI_ZEROCOPY_AVAILABLE + case 15: // unbounded + keyed + flat + zero = 1111 + _MessagingImpl = new RTIDDSImpl_FlatData(true); + break; - case 13: // unbounded + flat + zero = 1101 - _MessagingImpl = new RTIDDSImpl_FlatData(true); - break; + case 14: // keyed + flat + zero = 1110 + _MessagingImpl = new RTIDDSImpl_FlatData(true); + break; - case 12: // flat + Zero = 1100 - _MessagingImpl = new RTIDDSImpl_FlatData(true); - break; + case 13: // unbounded + flat + zero = 1101 + _MessagingImpl = new RTIDDSImpl_FlatData(true); + break; + + case 12: // flat + Zero = 1100 + _MessagingImpl = new RTIDDSImpl_FlatData(true); + break; + #endif + case 7: // unbounded + keyed + flat = 0111 + _MessagingImpl = new RTIDDSImpl_FlatData(); + break; + + case 6: // Keyed + flat = 0110 + _MessagingImpl = new RTIDDSImpl_FlatData(); + break; + + case 5: // unbounded + flat = 0101 + _MessagingImpl = new RTIDDSImpl_FlatData(); + break; + + case 4: // flat = 0100 + _MessagingImpl = new RTIDDSImpl_FlatData(); + break; + break; #endif - case 7: // unbounded + keyed + flat = 0111 - _MessagingImpl = new RTIDDSImpl_FlatData(); - break; - case 6: // Keyed + flat = 0110 - _MessagingImpl = new RTIDDSImpl_FlatData(); - break; + default: + break; + } + #else /* RTI_PERF_TSS defined */ + switch (mask) + { + case 0: // = 0000 (bounded) + _MessagingImpl = new RTITSSImpl( + "FACE::DM::TestData_t"); + break; - case 5: // unbounded + flat = 0101 - _MessagingImpl = new RTIDDSImpl_FlatData(); - break; + case 1: // unbounded = 0001 + _MessagingImpl = new RTITSSImpl( + "FACE::DM::TestDataLarge_t"); + break; - case 4: // flat = 0100 - _MessagingImpl = new RTIDDSImpl_FlatData(); - break; - break; - #endif + case 2: // keyed = 0010 + _MessagingImpl = new RTITSSImpl( + "FACE::DM::TestDataKeyed_t"); + break; - default: - break; + case 3: // unbounded + keyed = 0011 + _MessagingImpl = new RTITSSImpl( + "FACE::DM::TestDataKeyedLarge_t"); + break; } + #endif /* RTI_PERF_TSS */ } #else // No middleware is passed as -DPERFTEST_... @@ -335,6 +371,10 @@ perftest_cpp::perftest_cpp() : _PM(Middleware::RTIDDSPRO) #elif defined(PERFTEST_RTI_MICRO) : _PM(Middleware::RTIDDSMICRO) +#elif defined(RTI_PERF_TSS_PRO) + : _PM(Middleware::RTITSSPRO) +#elif defined(RTI_PERF_TSS_MICRO) + : _PM(Middleware::RTITSSMICRO) #else : _PM() #endif @@ -362,7 +402,7 @@ perftest_cpp::perftest_cpp() bool perftest_cpp::validate_input() { // Manage parameter -batchSize for micro - #ifndef PERFTEST_RTI_PRO + #if !defined(PERFTEST_RTI_PRO) && !defined(RTI_PERF_TSS_PRO) _PM.set("batchSize", 0); #endif @@ -885,7 +925,6 @@ class ThroughputListener : public IMessagingCB void process_message(TestMessage &message) { - #ifdef DEBUG_PING_PONG printf("-- ProcessMessage ...\n"); #endif @@ -1543,7 +1582,7 @@ class LatencyListener : public IMessagingCB cpu.initialize(); } - #ifdef PERFTEST_RTI_PRO + #if defined(PERFTEST_RTI_PRO) && !defined(RTI_PERF_TSS) if (_PM->get("serializationTime")) { mask = (_PM->get("unbounded") != 0) << 0; @@ -2004,7 +2043,6 @@ int perftest_cpp::Publisher() reader->wait_for_writers(_PM.get("numSubscribers")); } announcement_reader->wait_for_writers(_PM.get("numSubscribers")); - // We have to wait until every Subscriber sends an announcement message // indicating that it has discovered every Publisher fprintf(stderr,"Waiting for subscribers announcement ...\n"); diff --git a/srcCppCommon/Parameter.cxx b/srcCppCommon/Parameter.cxx index 57401e12..640e0b20 100644 --- a/srcCppCommon/Parameter.cxx +++ b/srcCppCommon/Parameter.cxx @@ -14,11 +14,18 @@ const MiddlewareMask Middleware::RTIDDSPRO = 1 << 0; const MiddlewareMask Middleware::RTIDDSMICRO = 1 << 1; -const MiddlewareMask Middleware::RAWTRANSPORT = 1 << 2; +const MiddlewareMask Middleware::RTITSSPRO = 1 << 2; +const MiddlewareMask Middleware::RTITSSMICRO = 1 << 3; +const MiddlewareMask Middleware::RAWTRANSPORT = 1 << 4; + +const MiddlewareMask Middleware::RTITSS = + Middleware::RTITSSPRO + | Middleware::RTITSSMICRO; const MiddlewareMask Middleware::RTIDDS = Middleware::RTIDDSPRO - | Middleware::RTIDDSMICRO; + | Middleware::RTIDDSMICRO + | Middleware::RTITSS; const MiddlewareMask Middleware::ALLDDS = Middleware::RTIDDS; diff --git a/srcCppCommon/Parameter.h b/srcCppCommon/Parameter.h index 1ce0e7cf..64936490 100644 --- a/srcCppCommon/Parameter.h +++ b/srcCppCommon/Parameter.h @@ -66,6 +66,9 @@ struct Middleware { static const MiddlewareMask RTIDDSPRO; static const MiddlewareMask RTIDDSMICRO; static const MiddlewareMask RTIDDS; + static const MiddlewareMask RTITSSPRO; + static const MiddlewareMask RTITSSMICRO; + static const MiddlewareMask RTITSS; static const MiddlewareMask RAWTRANSPORT; static const MiddlewareMask ALLDDS; static const MiddlewareMask ALL; diff --git a/srcCppCommon/ParameterManager.cxx b/srcCppCommon/ParameterManager.cxx index b74c1374..4b0a68e1 100644 --- a/srcCppCommon/ParameterManager.cxx +++ b/srcCppCommon/ParameterManager.cxx @@ -109,7 +109,8 @@ void ParameterManager::initialize() instanceHashBuckets->set_extra_argument(YES); instanceHashBuckets->set_range(1, 1000000); instanceHashBuckets->set_group(GENERAL); - instanceHashBuckets->set_supported_middleware(Middleware::RTIDDSPRO); + instanceHashBuckets->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("instanceHashBuckets", instanceHashBuckets); Parameter *keyed = new Parameter(false); @@ -129,7 +130,8 @@ void ParameterManager::initialize() noDirectCommunication->set_type(T_BOOL); noDirectCommunication->set_extra_argument(NO); noDirectCommunication->set_group(GENERAL); - noDirectCommunication->set_supported_middleware(Middleware::RTIDDSPRO); + noDirectCommunication->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("noDirectCommunication", noDirectCommunication); Parameter *noPositiveAcks = new Parameter(false); @@ -140,7 +142,8 @@ void ParameterManager::initialize() noPositiveAcks->set_type(T_BOOL); noPositiveAcks->set_extra_argument(NO); noPositiveAcks->set_group(GENERAL); - noPositiveAcks->set_supported_middleware(Middleware::RTIDDSPRO); + noPositiveAcks->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("noPositiveAcks", noPositiveAcks); Parameter *keepDurationUsec = @@ -150,7 +153,8 @@ void ParameterManager::initialize() keepDurationUsec->set_type(T_NUMERIC_LLU); keepDurationUsec->set_extra_argument(YES); keepDurationUsec->set_group(GENERAL); - keepDurationUsec->set_supported_middleware(Middleware::RTIDDSPRO); + keepDurationUsec->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); keepDurationUsec->set_range(1, (unsigned long long)365 * 24 * 60 * 60 * 1000000); // One year in usec @@ -175,7 +179,8 @@ void ParameterManager::initialize() qosFile->set_type(T_STR); qosFile->set_extra_argument(YES); qosFile->set_group(GENERAL); - qosFile->set_supported_middleware(Middleware::RTIDDSPRO); + qosFile->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("qosFile", qosFile); Parameter *qosLibrary = @@ -187,7 +192,8 @@ void ParameterManager::initialize() qosLibrary->set_type(T_STR); qosLibrary->set_extra_argument(YES); qosLibrary->set_group(GENERAL); - qosLibrary->set_supported_middleware(Middleware::RTIDDSPRO); + qosLibrary->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("qosLibrary", qosLibrary); Parameter *noXmlQos = new Parameter(false); @@ -197,7 +203,8 @@ void ParameterManager::initialize() noXmlQos->set_type(T_BOOL); noXmlQos->set_extra_argument(NO); noXmlQos->set_group(GENERAL); - noXmlQos->set_supported_middleware(Middleware::RTIDDSPRO); + noXmlQos->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("noXmlQos", noXmlQos); Parameter *useReadThread = new Parameter(false); @@ -221,7 +228,8 @@ void ParameterManager::initialize() waitsetDelayUsec->set_type(T_NUMERIC_LLU); waitsetDelayUsec->set_extra_argument(YES); waitsetDelayUsec->set_group(GENERAL); - waitsetDelayUsec->set_supported_middleware(Middleware::RTIDDSPRO); + waitsetDelayUsec->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); waitsetDelayUsec->set_range(0, 10000000); create("waitsetDelayUsec", waitsetDelayUsec); @@ -235,7 +243,8 @@ void ParameterManager::initialize() waitsetEventCount->set_type(T_NUMERIC_LD); waitsetEventCount->set_extra_argument(YES); waitsetEventCount->set_group(GENERAL); - waitsetEventCount->set_supported_middleware(Middleware::RTIDDSPRO); + waitsetEventCount->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); waitsetEventCount->set_range(1, LONG_MAX); create("waitsetEventCount", waitsetEventCount); @@ -245,7 +254,8 @@ void ParameterManager::initialize() asynchronous->set_type(T_BOOL); asynchronous->set_extra_argument(NO); asynchronous->set_group(GENERAL); - asynchronous->set_supported_middleware(Middleware::RTIDDSPRO); + asynchronous->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("asynchronous", asynchronous); Parameter *flowController = new Parameter("default"); @@ -261,7 +271,8 @@ void ParameterManager::initialize() flowController->add_valid_str_value("1Gbps"); flowController->add_valid_str_value("10Gbps"); flowController->set_group(GENERAL); - flowController->set_supported_middleware(Middleware::RTIDDSPRO); + flowController->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("flowController", flowController); Parameter *cpu = new Parameter(false); @@ -283,7 +294,8 @@ void ParameterManager::initialize() unbounded->set_extra_argument(POSSIBLE); unbounded->set_range(perftest_cpp::OVERHEAD_BYTES, MAX_BOUNDED_SEQ_SIZE); unbounded->set_group(GENERAL); - unbounded->set_supported_middleware(Middleware::RTIDDSPRO); + unbounded->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("unbounded", unbounded); Parameter *threadPriorities = new Parameter(""); @@ -529,6 +541,19 @@ void ParameterManager::initialize() create("compressionThreshold", compressionThreshold); #endif //defined(RTI_LANGUAGE_CPP_TRADITIONAL) && defined(PERFTEST_CONNEXT_PRO_610) + #ifdef RTI_PERF_TSS + Parameter *loaningSendReceive = new Parameter(false); + loaningSendReceive->set_command_line_argument("-loaningSendReceive", ""); + loaningSendReceive->set_description( + "Enables loaning samples when sending and receiving them.\n" + "Disabled by default."); + loaningSendReceive->set_type(T_BOOL); + loaningSendReceive->set_extra_argument(NO); + loaningSendReceive->set_group(GENERAL); + loaningSendReceive->set_supported_middleware(Middleware::RTITSS); + create("loaningSendReceive", loaningSendReceive); + #endif /* RTI_PERF_TSS */ + //////////////////////////////////////////////////////////////////////////// //PUBLISHER PARAMETER @@ -544,7 +569,8 @@ void ParameterManager::initialize() batchSize->set_group(PUB); batchSize->set_supported_middleware( Middleware::RTIDDSPRO - | Middleware::RAWTRANSPORT); + | Middleware::RAWTRANSPORT + | Middleware::RTITSSPRO); create("batchSize", batchSize); Parameter *enableAutoThrottle = new Parameter(false); @@ -578,7 +604,8 @@ void ParameterManager::initialize() pub->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("pub", pub); Parameter *latencyCount = @@ -660,7 +687,8 @@ void ParameterManager::initialize() numSubscribers->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("numSubscribers", numSubscribers); Parameter *pidMultiPubTest = new Parameter(0); @@ -675,7 +703,8 @@ void ParameterManager::initialize() pidMultiPubTest->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("pidMultiPubTest", pidMultiPubTest); ParameterPair *pubRate = @@ -779,7 +808,8 @@ void ParameterManager::initialize() writerStats->set_group(PUB); writerStats->set_supported_middleware( Middleware::RTIDDSPRO - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("writerStats", writerStats); #endif @@ -800,7 +830,8 @@ void ParameterManager::initialize() lowResolutionClock->set_group(PUB); lowResolutionClock->set_supported_middleware( Middleware::RTIDDSPRO - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("lowResolutionClock", lowResolutionClock); #endif @@ -818,7 +849,8 @@ void ParameterManager::initialize() writeInstance->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("writeInstance", writeInstance); #ifdef RTI_LANGUAGE_CPP_TRADITIONAL @@ -850,7 +882,8 @@ void ParameterManager::initialize() loadDataFromFile->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("loadDataFromFile", loadDataFromFile); Parameter *maximumAllocableBufferSize @@ -869,7 +902,8 @@ void ParameterManager::initialize() maximumAllocableBufferSize->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("maximumAllocableBufferSize", maximumAllocableBufferSize); #endif //RTI_LANGUAGE_CPP_TRADITIONAL @@ -896,7 +930,8 @@ void ParameterManager::initialize() sidMultiSubTest->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("sidMultiSubTest", sidMultiSubTest); Parameter *numPublishers = new Parameter(1); @@ -910,7 +945,8 @@ void ParameterManager::initialize() numPublishers->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("numPublishers", numPublishers); ParameterVector *cft = @@ -927,7 +963,8 @@ void ParameterManager::initialize() cft->set_range(0, MAX_CFT_VALUE - 1); cft->set_parse_method(SPLIT); cft->set_group(SUB); - cft->set_supported_middleware(Middleware::RTIDDSPRO); + cft->set_supported_middleware(Middleware::RTIDDSPRO + | Middleware::RTITSSPRO); create("cft", cft); //////////////////////////////////////////////////////////////////////////// @@ -984,7 +1021,8 @@ void ParameterManager::initialize() peer->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("peer", peer); Parameter *transport = new Parameter("Use XML"); @@ -1017,7 +1055,8 @@ void ParameterManager::initialize() transport->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); transport->add_valid_str_value("UDPv4"); transport->add_valid_str_value("SHMEM"); #if defined(PERFTEST_RTI_PRO) @@ -1050,7 +1089,8 @@ void ParameterManager::initialize() multicast->set_supported_middleware( Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT - | Middleware::RTIDDSMICRO); + | Middleware::RTIDDSMICRO + | Middleware::RTITSS); create("multicast", multicast); Parameter *multicastAddr = new Parameter(); @@ -1071,7 +1111,8 @@ void ParameterManager::initialize() multicastAddr->set_group(TRANSPORT); multicastAddr->set_supported_middleware( Middleware::RTIDDSPRO - | Middleware::RAWTRANSPORT); + | Middleware::RAWTRANSPORT + | Middleware::RTITSSPRO); create("multicastAddr", multicastAddr); Parameter *transportVerbosity = new Parameter(); @@ -1084,7 +1125,7 @@ void ParameterManager::initialize() transportVerbosity->set_extra_argument(YES); transportVerbosity->set_group(TRANSPORT); transportVerbosity->set_supported_middleware( - Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT); + Middleware::RTIDDSPRO | Middleware::RAWTRANSPORT | Middleware::RTITSSPRO); create("transportVerbosity", transportVerbosity); Parameter *transportServerBindPort = diff --git a/srcDoc/command_line_parameters.rst b/srcDoc/command_line_parameters.rst index bd9812d7..7bea8de2 100644 --- a/srcDoc/command_line_parameters.rst +++ b/srcDoc/command_line_parameters.rst @@ -40,6 +40,8 @@ For additional information on setting the parameters, see sections: .. _Test Parameters for Publishing and Subscribing Applications: +.. _section-pubsub_command_line_parameters: + Test Parameters for Publishing and Subscribing Applications ------------------------------------------------------------ @@ -548,6 +550,16 @@ Test Parameters for Publishing and Subscribing Applications | **Default:** Not set: *RTI Perftest* will delete the file +- ``-loaningSendReceive`` + + Only available when compiling for *RTI Connext TSS*. + + Make use of the underlying DDS loan function to avoid copying the sample + at the application level. + + | **Default:** Not set: Perftest will avoid using underlying DDS functions by default. + + Transport-Specific Options -------------------------- @@ -1390,3 +1402,96 @@ is ignored. To achieve the best latency under maximum throughput conditions, use ``-enableAutoThrottle`` and ``-enableTurboMode`` in combination. + +.. _section-not_available_params_tss: + +Perftest parameters not available when using Connext TSS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following parameters are not available when using *Perftest* with *TSS*: + +- ``-dynamicData`` + +- ``-flatData`` + +- ``-zeroCopy`` + +- ``-checkConsistency`` + +- ``-preallocateFragmentedSamples`` + +- ``-flowController `` + +- ``-unbounded`` + +- ``-peer`` + +- ``-threadPriorities`` + +- ``-cacheStats`` + +- ``-compressionId`` + +- ``-compressionLevel`` + +- ``-compressionThreshold`` + +- ``-networkCapture`` + +- ``-doNotDropNetworkCapture`` + +- ``-transportWan`` + +- ``-transportPublicAddress`` + +- ``-transportHostPort`` + +- ``-transportWanServerAddress`` + +- ``-transportWanServerPort`` + +- ``-transportWanId`` + +- ``-transportSecureWan`` + +- ``-transportCertAuthority`` + +- ``-transportCertFile`` + +- ``-transportPrivateKey`` + +- ``-writerStats`` + +- ``-showSerializationTime`` + +- ``-cft`` + +- ``-checkConsistency`` + +- ``-secureEncryptDiscovery`` + +- ``-secureSign`` + +- ``-secureEncryptData`` + +- ``-secureEncryptSM`` + +- ``-secureGovernanceFile `` + +- ``-securePermissionsFile `` + +- ``-secureCertAuthority `` + +- ``-secureCertFile`` + +- ``-securePrivateKey`` + +- ``-secureEncryptionAlgorithm`` + +- ``-rawTransport`` + +- ``-noBlockingSockets`` + +Please keep in mind that *RTI Connext TSS* uses *RTI Connext Pro* or +*RTI Connext Micro* underneath, so any argument that's not available for Pro, +won't be available for TSS + Pro, and the same applies to Micro and TSS + Micro. \ No newline at end of file diff --git a/srcDoc/compatibility.rst b/srcDoc/compatibility.rst index e56b78e0..0d28343d 100644 --- a/srcDoc/compatibility.rst +++ b/srcDoc/compatibility.rst @@ -13,6 +13,10 @@ middleware. It has been compiled and tested against: should also be compatible by adding the `--micro-24x-compatibility` command-line option. +- *RTI Connext TSS* 3.1.2 over *RTI Connext Pro* 6.1.1.4, or over + *RTI Connext Micro* 2.4.13.4. The only supported FACE profile is + GeneralPurpose. + Using Security ~~~~~~~~~~~~~~ diff --git a/srcDoc/compilation.rst b/srcDoc/compilation.rst index 14f6aa9c..dd076a13 100644 --- a/srcDoc/compilation.rst +++ b/srcDoc/compilation.rst @@ -21,6 +21,8 @@ Potentially, ``build.sh`` can generate and compile code for every architecture supported by *rtiddsgen* where a makefile is generated as output when the ``-example`` command-line is specified. +.. _section-prerequisites: + Prerequisites ~~~~~~~~~~~~~ For compiling *RTI Perftest*, there are a few prerequisites; @@ -88,6 +90,27 @@ if you downloaded the executables already compiled, you can skip these steps: will need to link against the OpenSSL/wolfSSL libraries for your architecture. +.. + +- If compiling for *RTI Connext TSS*, make sure that the *TSS* libraries have + been compiled for the GeneralPurpose FACE profile, since that is the profile + that has been tested with *Perftest*. *Perftest* does not currently support + *RTI Connext TSS* built with the SafetyBase profile. + + Before building *Perftest* for *RTI Connext TSS*, the following + environment variables also have to be set: + + - ``RTITSSHOME``: absolute path to an *RTI Connext TSS* installation. + - ``NDDSHOME``: absolute path to an *RTI Connext Pro* installation. Only + needed when compiling for *RTI Connext TSS* over *RTI Connext Pro*. + - ``NDDSARCH`` (optional): architecture of the *RTI Connext Pro* + libraries to use. It should only be used when it is not the + same as the architecture of the *RTI Connext TSS* libraries. + - ``RTIMEHOME``: absolute path to an *RTI Connext Micro* installation. Only + needed when compiling for *RTI Connext TSS* over *RTI Connext Micro*. + - ``RTIMEARCH`` (optional): architecture of the *RTI Connext Micro* + libraries to use. It should only be used when it is not the + same as the architecture of the *RTI Connext TSS* libraries. .. _compilation-parameters-linux: @@ -114,6 +137,10 @@ The ``build.sh`` script accepts the following list of parameters: * - ``--micro-24x-compatibility`` - Optional - Compile *RTI Perftest* against *RTI Connext DDS Micro* 2.4.11 and above. + * - ``--tss`` + - Optional + - Compile *RTI Perftest* against *RTI Connext TSS 3.1.2* over *RTI Connext + Pro 6.1.1.4* or *RTI Connext Micro 2.4.13.4*. * - ``--nddshome`` - Optional - Path to the *RTI Connext DDS Professional* installation. If this parameter @@ -181,7 +208,7 @@ The ``build.sh`` script accepts the following list of parameters: - Optional - Path to the OpenSSL home directory. Needed when compiling using the ``--secure`` option and statically. - * - ``--wolfssl-home`` + * - ``--wolfssl-home`` - Optional - Path to the wolfSSL home directory. Needed when compiling using the ``--secure`` option and statically. @@ -238,6 +265,7 @@ The ``build.sh`` script accepts the following list of parameters: - If this option is present, the ``build.sh`` script will display a help description and exit +.. _section-linux_compilation_examples: Examples Running Build Script ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -322,6 +350,32 @@ examples: ./build.sh --platform x64Darwin14clang6.0 --micro +- Generation and compilation for *RTI Connext TSS* over *RTI Connext Pro* for a + given architecture in debug mode. + + .. code-block:: console + + ./build.sh --platform x64Linux4gcc7.3.0FACE_GP --debug --tss + + .. note:: + + Before building *Perftest* for *RTI Connext TSS* over *RTI Connext + Pro*, some environment variables have to be set. Check + :ref:`section-prerequisites` to know more. + +- Generation and compilation for *RTI Connext TSS* over *RTI Connext Micro* for a + given architecture in release mode. + + .. code-block:: console + + ./build.sh --platform x64Linux4gcc7.3.0FACE_GP --tss --micro + + .. note:: + + Before building *Perftest* for *RTI Connext TSS* over *RTI Connext + Micro*, some environment variables have to be set. Check + :ref:`section-prerequisites` to know more. + - *RTI Perftest* directory clean-up. .. code-block:: console @@ -462,6 +516,8 @@ The ``build.bat`` script accepts the following list of parameters: | ``--cs-build`` | Optional | Only C# code generation and | | | | compilation. | +------------------------+-----------+-----------------------------------+ +| ``--tss`` | Optional | Compile for *RTI Connext TSS* | ++------------------------+-----------+-----------------------------------+ | ``--dynamic`` | Optional | Compile using the *Connext DDS* | | | | dynamic libraries. Default: | | | | static libraries. | @@ -621,4 +677,4 @@ examples: .. code-block:: console - build.bat --clean + build.bat --clean \ No newline at end of file diff --git a/srcDoc/index.rst b/srcDoc/index.rst index 6fc5e23f..236874f3 100644 --- a/srcDoc/index.rst +++ b/srcDoc/index.rst @@ -39,6 +39,8 @@ Features *RTI Perftest* supports the following functionality: - *RTI Connext DDS Professional* and *RTI Connext DDS Micro*. + *Perftest* also supports *RTI Connext TSS* over *RTI Connext DDS Professional* + or over *RTI Connext DDS Micro*. - Multiple platforms, including Windows®, Linux®, macOS®, VxWorks®, and Android™. - Multiple test setups: multicast, one-to-many communication (Pub -> Sub), latency test, throughput test, and latency vs. throughput test. diff --git a/srcDoc/release_notes.rst b/srcDoc/release_notes.rst index 9d7206d3..e6c591c0 100644 --- a/srcDoc/release_notes.rst +++ b/srcDoc/release_notes.rst @@ -17,6 +17,29 @@ Release Notes Develop What's New in Develop ~~~~~~~~~~~~~~~~~~~~~ +Support for **RTI Connext TSS 3.1.2** |newTag| +++++++++++++++++++++++++++++++++++++++++++++++++ + +We have added support for **RTI Connext TSS 3.1.2** compiled against *RTI +Connext Pro 6.1.1.4* or against *RTI Connext Micro 2.4.13.4*. + +This support has been added for *Linux*, since *RTI Connext TSS 3.1.2* does not +support *Windows* as a host or target platform. + +Examples of how to compile *Perftest* for *RTI Connext TSS 3.1.2* can be found +in section :ref:`section-linux_compilation_examples`. + +Running *Perftest* against *RTI Connext TSS 3.1.2* is the same as +running it when compiled against *RTI Connext Pro* or *RTI Connext Micro*, +except for some command-line arguments that are available for *RTI Connext Pro* +and/or *RTI Connext Micro*, but that aren't available for *RTI Connext TSS*. +(See :ref:`section-not_available_params_tss`). The argument +``-loaningSendReceive`` has been added to make *Perftest* use +*RTI Connext Pro*/*RTI Connext Micro* loaning functions for receiving and +sending samples, instead of the pure TSS approach that's followed +by default. Find more information on this argument in section +:ref:`section-pubsub_command_line_parameters`. + Support for **wolfSSL** for *Linux* and *QNX* when using the *Security Plugins* |newTag| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/srcIdl/perftest.idl b/srcIdl/perftest.idl index 4d81c1ca..d5badccd 100644 --- a/srcIdl/perftest.idl +++ b/srcIdl/perftest.idl @@ -25,6 +25,12 @@ const string LATENCY_TOPIC_NAME = "Latency"; const string ANNOUNCEMENT_TOPIC_NAME = "Announcement"; #endif +#if defined(RTI_PERF_TSS) +const string THROUGHPUT_TOPIC_NAME_STRING = "Throughput"; +const string LATENCY_TOPIC_NAME_STRING = "Latency"; +const string ANNOUNCEMENT_TOPIC_NAME_STRING = "Announcement"; +#endif + /* * This idl uses prefix annotations. In order to compile with previous versions * of *Connext DDS Professional* modify the following annotations: @@ -35,6 +41,14 @@ const string ANNOUNCEMENT_TOPIC_NAME = "Announcement"; * */ +/* + * FACE Types need to be inside a FACE::DM module + */ +#ifdef RTI_PERF_TSS +module FACE { +module DM { +#endif + @final struct TestData_t { octet key[KEY_SIZE]; @@ -106,6 +120,11 @@ struct TestDataKeyedLarge_t { #endif }; +#ifdef RTI_PERF_TSS +}; /* DM module */ +}; /* FACE module */ +#endif + /********************************** FLATDATA **********************************/ #ifdef RTI_FLATDATA_AVAILABLE @@ -183,4 +202,4 @@ struct TestDataKeyedLarge_FlatData_t { #endif }; -#endif // RTI_FLATDATA_AVAILABLE +#endif // RTI_FLATDATA_AVAILABLE \ No newline at end of file