/* * (c) Copyright, Real-Time Innovations, 2023. * 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 rtitest_time_h #define rtitest_time_h #include "rtitest/test_types.h" #include "rtitest/test_dll.h" #ifdef __cplusplus extern "C" { #endif typedef struct RTITestTime { /* Seconds. */ unsigned int sec; /* Fraction of a second in 1/2^32 form. */ unsigned int frac; } RTITestTime; extern RTITestDllExport RTIBool RTITest_sleep(const RTITestTime *timeIn); #ifdef RTI_RUNNING_VALGRIND #define RTI_TEST_DEFAULT_WAIT_TIME 20 #define RTI_TEST_DEFAULT_LONG_WAIT_TIME 200 #else #define RTI_TEST_DEFAULT_WAIT_TIME 10 #define RTI_TEST_DEFAULT_LONG_WAIT_TIME 120 #endif /** * @brief Wait for a given number of seconds. * @param maxSeconds The number of seconds to wait. */ #define RTITest_wait(maxSeconds__) \ { \ const struct RTITestTime sleepTime__ = { 0, 429496730 }; \ int sleeps__ = 0; \ while (sleeps__ < ((int) (maxSeconds__)) * 10) { \ RTITest_sleep(&sleepTime__); \ ++sleeps__; \ } \ } /** * @internal * @ingroup RTITestUtilities * @brief Wait for a condition to be true. * @param cond__ The condition to wait for. * @param maxSeconds__ The maximum number of seconds to wait. * @param additionalSleepTimeSec__ Additional number of seconds to wait. */ #define RTITest_waitForConditionNoFailureEx( \ cond__, \ maxSeconds__, \ additionalSleepTimeSec__) \ { \ /* 100 ms */ \ struct RTITestTime sleepTime__ = { 0, 429496730 }; \ unsigned int sleeps__ = 0; \ unsigned int maxSleeps__ = ((unsigned int) (maxSeconds__) * 10) \ / (((unsigned int) (additionalSleepTimeSec__) * 10) + 1); \ \ sleepTime__.sec = (additionalSleepTimeSec__); \ while (!(cond__) && sleeps__ < maxSleeps__) { \ RTITest_sleep(&sleepTime__); \ ++sleeps__; \ } \ } /** @internal * @ingroup RTITestUtilities * @brief Wait for a condition to be true. * Otherwise, run the given action. * @param cond__ The condition to wait for. * @param maxSeconds__ The maximum number of seconds to wait. * @param additionalSleepTimeSec__ Additional number of seconds to wait. * @param action__ The action to run if the condition is not true. */ #define RTITest_waitForConditionWithActionEx( \ cond__, \ maxSeconds__, \ additionalSleepTimeSec__, \ action__) \ { \ /* 100 ms */ \ struct RTITestTime sleepTime__ = { 0, 429496730 }; \ unsigned int sleeps__ = 0; \ int condEv__; \ unsigned int maxSleeps__ = ((unsigned int) (maxSeconds__) * 10) \ / (((unsigned int) (additionalSleepTimeSec__) * 10) + 1); \ \ sleepTime__.sec = (additionalSleepTimeSec__); \ while (!(condEv__ = (cond__)) && sleeps__ < maxSleeps__) { \ RTITest_sleep(&sleepTime__); \ ++sleeps__; \ } \ if (!condEv__) { \ RTITest_assertLog( \ &RTI_TEST_LOG_EMPTY_TEMPLATE, \ "[%s:%d] wait for condition failed: %s", \ __FILE__, \ __LINE__, \ #cond__); \ action__; \ } \ } /** * @ingroup RTITestUtilities * @brief Wait for a condition to be true. * @param cond__ The condition to wait for. * @param maxSeconds__ The maximum number of seconds to wait. */ #define RTITest_waitForConditionNoFailure(cond__, maxSeconds__) \ RTITest_waitForConditionNoFailureEx( \ cond__, \ maxSeconds__, \ 0 /* additionalSleepTimeSec__ */) /** * @ingroup RTITestUtilities * @brief Wait for a condition to be true. * Otherwise, run the given action. * @param cond__ The condition to wait for. * @param maxSeconds__ The maximum number of seconds to wait. * @param action__ The action to run if the condition is not true. */ #define RTITest_waitForConditionWithAction(cond__, maxSeconds__, action__) \ RTITest_waitForConditionWithActionEx( \ cond__, \ maxSeconds__, \ 0, /* additionalSleepTimeSec__ */ \ action__) /** @internal * @ingroup RTITestUtilities * @brief Wait for a condition to be true. * @param cond__ The condition to wait for. * @param maxSeconds__ The maximum number of seconds to wait. * @param additionalSleepTimeSec__ Additional number of seconds to wait * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForConditionEx( \ cond__, \ maxSeconds__, \ additionalSleepTimeSec__) \ RTITest_waitForConditionWithActionEx( \ cond__, \ maxSeconds__, \ additionalSleepTimeSec__, \ goto done) #define RTI_TEST_TIME_ZERO {0, 0} /** * @ingroup RTITestUtilities * @brief Wait for a condition to be true. * @param cond__ The condition to wait for. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForCondition(cond__, maxSeconds__) \ RTITest_waitForConditionEx(cond__, maxSeconds__, 0) /** * @ingroup RTITestUtilities * @brief Wait for a DDS_ReturnCode_t return code to be DDS_RETCODE_OK. * @param retcode__ The DDS_ReturnCode_t code to wait for. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForOk(retcode__, maxSeconds__) \ RTITest_waitForConditionEx((retcode__) == DDS_RETCODE_OK, (maxSeconds__), 0) /** * @ingroup RTITestUtilities * @brief Wait while a condition is true for a given number of seconds. * If the condition becomes false, run the given action. * @param cond__ Wait while this condition is true. * @param maxSeconds__ The maximum number of seconds to wait. * @param action__ The action to run if the condition becomes false. */ #define RTITest_waitWhileConditionMatchWithAction( \ cond__, \ maxSeconds__, \ action__) \ { \ const struct RTITestTime sleepTime__ = { 0, 429496730 }; \ int sleeps__ = 0; \ int condEv__; \ while ((condEv__ = (cond__)) && sleeps__ < ((maxSeconds__) * 10)) { \ RTITest_sleep(&sleepTime__); \ ++sleeps__; \ } \ if (!condEv__) { \ RTITest_assertLog( \ &RTI_TEST_LOG_EMPTY_TEMPLATE, \ "[%s:%d] wait while condition match failed: %s", \ __FILE__, \ __LINE__, \ #cond__); \ action__; \ } \ } /** * @ingroup RTITestUtilities * @brief Wait while a condition is true for a given number of seconds. * @param cond__ Wait while this condition is true. * @param maxSeconds__ The maximum number of seconds to wait. */ #define RTITest_waitWhileConditionMatch(cond__, maxSeconds__) \ RTITest_waitWhileConditionMatchWithAction(cond__, maxSeconds__, goto done) /** @internal * @brief Wait for a condition to be true. * @param expected__ The expected value. * @param actual__ The actual value. * @param cond__ The condition to wait for. * @param typeFormat__ The format string for the type of the values. * @param maxSeconds__ The maximum number of seconds to wait. */ #define RTITest_waitForEquals( \ expected__, \ actual__, \ cond__, \ typeFormat__, \ maxSeconds__) \ { \ const struct RTITestTime sleepTime__ = { 0, 429496730 }; \ int sleeps__ = 0; \ int condEv__; \ while (!(condEv__ = (cond__)) && sleeps__ < (maxSeconds__) * 10) { \ RTITest_sleep(&sleepTime__); \ ++sleeps__; \ } \ if (!condEv__) { \ RTITest_assertLog( \ &RTI_TEST_LOG_EMPTY_TEMPLATE, \ "[%s:%d] wait for condition failed: %s(" #typeFormat__ \ ") == %s(" #typeFormat__ ")", \ __FILE__, \ __LINE__, \ #expected__, \ (expected__), \ #actual__, \ (actual__)); \ goto done; \ } \ } /* * Used for more complex conditions that may require doing some work * within the sleep loop while waiting for a condition. * * Useful when waiting for a statistic, for example, because we need to call * 'get_status' over and over until the statistic we're waiting on is the * expected value: * * RTITest_waitForGreaterThanIntExt( * RTITest_assertOk(DDS_DataWriter_get_datawriter_protocol_status( * (DDS_DataWriter *)writer, * &writerStatus)), * nackCount, * writerStatus.received_nack_count, * RTI_TEST_DEFAULT_WAIT_TIME * ) * * This assert allows the caller to perform an action and then use the output * of that action in the break condition. * * This macro should not be used directly, use (or add if it's not * there) one of the specialized ones below that calls this one with the * correct operation and testAssert */ #define RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ operation__, \ testAssert__) \ { \ struct RTITestTime sleepTime__ = { 0, 42949672 }; \ int i__, count__ = (int) (maxSeconds__) * 100; \ for (i__ = 0; i__ < count__; i__++) { \ action__; \ if ((actual__) operation__ (expected__)) { \ break; \ } \ RTITest_sleep(&sleepTime__); \ } \ \ if (i__ == count__) { \ testAssert__(expected__, actual__); \ } \ } /* * Like RTITest_waitForConditionExtImpl, this is used for more complex * conditions that may require doing some work within the sleep loop while * waiting for a condition. However this lets you pass a generic condition into * the macro instead of requiring an operator. This is intended to be used for * when you need to wait for multiple conditions to be true before continuing * or conditions that do not require an operator, such as returning true * from a function. * * Useful when waiting for a case where multiple variables are updated. * * RTITest_waitForConditionExt( * RTITest_assertOk(DDS_DataWriter_assert_liveliness(manualWriter), * manualPacketsSent >= expectedManualPackets * && autoPackets >= expectedAutoPackets, * RTI_TEST_DEFAULT_WAIT_TIME * ) * * Calls `goto done` if the condition is never met. Therefore, this macro * requires a `done` label to be defined in the method that this macro is called * in. */ #define RTITest_waitForConditionExt(action__, condition__, maxSeconds__) \ { \ struct RTITestTime sleepTime__ = { 0, 42949672 }; \ int i__, count__ = (maxSeconds__) * 100; \ for (i__ = 0; i__ < count__; i__++) { \ action__; \ if ((condition__)) { \ break; \ } \ RTITest_sleep(&sleepTime__); \ } \ \ if (i__ == count__) { \ RTITest_assert(condition__); \ } \ } /* * Same as RTITest_waitForConditionExt but, upon failure, does not make the test * fail. This is useful when you want to wait for a condition to be true but * you don't want to fail the test if it's not true after the timeout. */ #define RTITest_waitForConditionNoFailureExt( \ action__, \ condition__, \ maxSeconds__) \ { \ struct RTITestTime sleepTime__ = { 0, 42949672 }; \ int i__, count__ = (maxSeconds__) *100; \ for (i__ = 0; i__ < count__; i__++) { \ action__; \ if ((condition__)) { \ break; \ } \ RTITest_sleep(&sleepTime__); \ } \ } /** @internal * @ingroup RTITestUtilities * @brief Wait for two given integers to be equal after executing an action * multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsIntExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ ==, \ RTITest_assertEqualsInt) /** @internal * @ingroup RTITestUtilities * @brief Wait for a given integer to become greater than another one after * executing an action multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterThanIntExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ >, \ RTITest_assertGreaterThanInt) /** @internal * @ingroup RTITestUtilities * @brief Wait for a given integer to become equal to or greater than another * one after executing an action multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterOrEqualsIntExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ >=, \ RTITest_assertGreaterOrEqualsInt) /** @internal * @ingroup RTITestUtilities * @brief Wait for a given integer to become less than or equal to another one * after executing an action multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForLessThanOrEqualsIntExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ <=, \ RTITest_assertGreaterOrEqualsInt) /** * @ingroup RTITestUtilities * @brief Wait for a given integer to become greater than another one. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterThanInt(expected__, actual__, maxSeconds__) \ RTITest_waitForGreaterThanIntExt( \ ((void) 0), \ expected__, \ actual__, \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for an integer to become equal to or greater than another one. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterOrEqualsInt(expected__, actual__, maxSeconds__) \ RTITest_waitForGreaterOrEqualsIntExt( \ ((void) 0), \ expected__, \ actual__, \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for a given integer to become less than or equal to another one. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForLessThanOrEqualsInt(expected__, actual__, maxSeconds__) \ RTITest_waitForLessThanOrEqualsIntExt( \ ((void) 0), \ expected__, \ actual__, \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for two given integers to become equal. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsInt(expected__, actual__, maxSeconds__) \ RTITest_waitForEquals( \ expected__, \ actual__, \ ((expected__) == (actual__)), \ "%d", \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for two given long integers to become equal. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsLong(expected__, actual__, maxSeconds__) \ RTITest_waitForEquals( \ expected__, \ actual__, \ ((expected__) == (actual__)), \ "%ld", \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for two given long long integers to become equal. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsLongLong(expected__, actual__, maxSeconds__) \ RTITest_waitForEquals( \ expected__, \ actual__, \ ((expected__) == (actual__)), \ "%lld", \ maxSeconds__) /** @internal * @ingroup RTITestUtilities * @brief Wait for two given unsigned integers to become equal after executing * an action multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterThanLongLongExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ >, \ RTITest_assertGreaterThanLongLong) /** * @ingroup RTITestUtilities * @brief Wait for a long long integer to become greater than another one. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterThanLongLong(expected__, actual__, maxSeconds__) \ RTITest_waitForGreaterThanLongLongExt( \ ((void) 0), \ expected__, \ actual__, \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for two given unsigned integers to become equal. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsUnsignedInt(expected__, actual__, maxSeconds__) \ RTITest_waitForEquals( \ expected__, \ actual__, \ ((expected__) == (actual__)), \ "%u", \ maxSeconds__) /** * @ingroup RTITestUtilities * @brief Wait for two given unsigned long long integers to become equal. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsUnsignedLongLong( \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForEquals( \ expected__, \ actual__, \ ((expected__) == (actual__)), \ "%llu", \ maxSeconds__) /** @internal * @ingroup RTITestUtilities * @brief Wait for two given unsigned long long integers to become equal after * executing an action multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForEqualsUnsignedLongLongExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ ==, \ RTITest_assertEqualsUnsignedLongLong) /** @internal * @ingroup RTITestUtilities * @brief Wait for a given unsigned long long to become equal to or greater than * another one after executing an action multiple times. * @param action__ The action to execute in a loop. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterOrEqualsUnsignedLongLongExt( \ action__, \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForConditionExtImpl( \ action__, \ expected__, \ actual__, \ maxSeconds__, \ >=, \ RTITest_assertGreaterOrEqualsUnsignedLongLong) /** @internal * @ingroup RTITestUtilities * @brief Wait for a given unsigned long long to become equal to or greater than * another one. * @param expected__ The expected value. * @param actual__ The actual value. * @param maxSeconds__ The maximum number of seconds to wait. * @details Calls `goto done` if the condition is never met. Therefore, this * macro requires a `done` label to be defined in the method that this * macro is called in. */ #define RTITest_waitForGreaterOrEqualsUnsignedLongLong( \ expected__, \ actual__, \ maxSeconds__) \ RTITest_waitForGreaterOrEqualsUnsignedLongLongExt( \ ((void) 0), \ expected__, \ actual__, \ maxSeconds__) #define RTI_TEST_TIME_SEC_MAX 0xFFFFFFFFU #define RTI_TEST_TIME_FRAC_MAX 0xFFFFFFFFU #define RTI_TEST_TIME_FRAC_TO_SEC 0x100000000U #define RTI_TEST_TIME_SEC_TO_MILLISECONDS 1000U #define RTI_TEST_TIME_SEC_TO_MICROSECONDS 1000000U #define RTI_TEST_TIME_SEC_TO_NANOSECONDS 1000000000U /** @internal * @ingroup RTITestUtilities * @brief Convert RTITestTime into seconds and value (value expressed in msec/usec/nsec). * @param s__ \b Out. The seconds field of the RTITestTime. * @param value__ \b Out. The value of the fraction of RTITestTime expressed in msec/usec/nsec. * @param time__ \b In. The input RTITestTime. * @param conversion_factor__ \b In. How many `value__`s there are in a second. * @warning This macro should never be called directly, please use `RTITestTime_toMilliseconds`, * `RTITestTime_toMicroseconds`, and `RTITestTime_toNanoseconds` instead. * @details This macro converts RTITestTime into seconds and a `value__`. This * `value__` is the fraction of RTITestTime interpreted as: * * Milliseconds if the conversion factor is 1000. * * Microseconds if the conversion factor is 1000000. * * Nanoseconds if the conversion factor is 1000000000. * You may use a different conversion factor to implement new macros * for different time units. */ #define RTITestTime_toPrecision(s__, value__, time__, conversion_factor__) \ do { \ unsigned long long unitTemp__ = (unsigned long long) (time__).frac; \ s__ = (time__).sec; \ unitTemp__ = \ (unitTemp__ * (conversion_factor__)) / (RTI_TEST_TIME_FRAC_TO_SEC); \ value__ = (unsigned int) unitTemp__; \ if (unitTemp__ >= (conversion_factor__) && (s__) != RTI_TEST_TIME_SEC_MAX) { \ (s__)++; \ value__ = (unsigned int) (unitTemp__ - conversion_factor__); \ } \ } while(0) /** * @ingroup RTITestUtilities * @brief Convert RTITestTime into seconds and milliseconds. * @param s__ \b Out. The seconds field of the RTITestTime. * @param msec__ \b Out. The fraction of the RTITestTime expressed in milliseconds. * @param time__ \b In. The input RTITestTime. */ #define RTITestTime_toMilliseconds(s__, msec__, time__) \ RTITestTime_toPrecision( \ s__, \ msec__, \ time__, \ RTI_TEST_TIME_SEC_TO_MILLISECONDS); /** * @ingroup RTITestUtilities * @brief Convert RTITestTime into seconds and microseconds. * @param s__ \b Out. The seconds field of the RTITestTime. * @param usec__ \b Out. The fraction of the RTITestTime expressed in microseconds. * @param time__ \b In. The input RTITestTime. */ #define RTITestTime_toMicroseconds(s__, usec__, time__) \ RTITestTime_toPrecision( \ s__, \ usec__, \ time__, \ RTI_TEST_TIME_SEC_TO_MICROSECONDS); /** * @ingroup RTITestUtilities * @brief Convert RTITestTime into seconds and nanoseconds. * @param s__ \b Out. The seconds field of the RTITestTime. * @param nsec__ \b Out. The fraction of the RTITestTime expressed in nanoseconds. * @param time__ \b In. The input RTITestTime. */ #define RTITestTime_toNanoseconds(s__, nsec__, time__) \ RTITestTime_toPrecision( \ s__, \ nsec__, \ time__, \ RTI_TEST_TIME_SEC_TO_NANOSECONDS); /** @internal * @ingroup RTITestUtilities * @brief Convert seconds and value (value expressed in msec/usec/nsec) into RTITestTime. * @param time__ \b Out. The output RTITestTime. * @param s__ \b In. The amount of seconds. * @param value__ \b In. The amount of milliseconds/microseconds/nanoseconds. * @param conversion_factor__ \b In. How many `value__`s there are in a second. * @warning This macro should never be called directly, please use `RTITestTime_fromMilliseconds`, * `RTITestTime_fromMicroseconds` and `RTITestTime_fromNanoseconds` instead. * @details This macro converts seconds and a `value__` into RTITestTime. `value__` * is the amount of: * * Milliseconds if the conversion factor is 1000. * * Microseconds if the conversion factor is 1000000. * * Nanoseconds if the conversion factor is 1000000000. * You may use a different conversion factor to implement new macros * for different time units. */ #define RTITestTime_fromPrecision(time__, s__, value__, conversion_factor__) \ do { \ unsigned long long unitTemp__ = (unsigned long long) (value__); \ (time__).sec = (unsigned int) (s__); \ if ((time__).sec != RTI_TEST_TIME_SEC_MAX) { \ (time__).sec += (unsigned int) (unitTemp__ / conversion_factor__); \ } \ unitTemp__ = unitTemp__ % conversion_factor__; \ (time__).frac = \ (unsigned int) ((unitTemp__ * RTI_TEST_TIME_FRAC_MAX) / conversion_factor__); \ } while(0) /** * @ingroup RTITestUtilities * @brief Convert seconds and milliseconds into RTITestTime. * @param time__ \b Out. The output RTITestTime. * @param s__ \b In. The amount of seconds. * @param msec__ \b In. The amount of milliseconds. */ #define RTITestTime_fromMilliseconds(time__, s__, msec__) \ RTITestTime_fromPrecision( \ time__, \ s__, \ msec__, \ RTI_TEST_TIME_SEC_TO_MILLISECONDS) /** * @ingroup RTITestUtilities * @brief Convert seconds and microseconds into RTITestTime. * @param time__ \b Out. The output RTITestTime. * @param s__ \b In. The amount of seconds. * @param usec__ \b In. The amount of microseconds. */ #define RTITestTime_fromMicroseconds(time__, s__, usec__) \ RTITestTime_fromPrecision( \ time__, \ s__, \ usec__, \ RTI_TEST_TIME_SEC_TO_MICROSECONDS) /** * @ingroup RTITestUtilities * @brief Convert seconds and nanoseconds into RTITestTime. * @param time__ \b Out. The output RTITestTime. * @param s__ \b In. The amount of seconds. * @param nsec__ \b In. The amount of nanoseconds. */ #define RTITestTime_fromNanoseconds(time__, s__, nsec__) \ RTITestTime_fromPrecision( \ time__, \ s__, \ nsec__, \ RTI_TEST_TIME_SEC_TO_NANOSECONDS) #ifdef __cplusplus } /* extern "C" */ #endif #endif