From 5ad9c53c1d458c20800b75936c599f6e16e15d35 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 6 Mar 2024 16:55:16 -0500 Subject: [PATCH] Fix #1455, High-resolution timed ops Add API calls equivalent to existing calls that use an absolute timeout as opposed to a relative timeout. The absolute timeout can support resolution of 0.1 usec in the default configuration. Internally this primarily affects the underlying call to select(). Note that per the definition of select() in POSIX, it uses a "struct timeval" which has a resolution of 1 usec. --- src/os/inc/osapi-clock.h | 116 ++++++++++++++++++ src/os/inc/osapi-file.h | 81 +++++++++++- src/os/inc/osapi-sockets.h | 35 +++++- src/os/portable/os-impl-bsd-select.c | 73 +++++------ src/os/portable/os-impl-bsd-sockets.c | 16 +-- src/os/portable/os-impl-no-sockets.c | 6 +- src/os/portable/os-impl-posix-io.c | 8 +- src/os/shared/inc/os-shared-file.h | 4 +- src/os/shared/inc/os-shared-select.h | 5 +- src/os/shared/inc/os-shared-sockets.h | 6 +- src/os/shared/src/osapi-clock.c | 80 ++++++++++++ src/os/shared/src/osapi-file.c | 30 ++++- src/os/shared/src/osapi-select.c | 4 +- src/os/shared/src/osapi-sockets.c | 21 +++- src/tests/network-api-test/network-api-test.c | 2 + .../portable/src/coveragetest-bsd-select.c | 111 ++++++++--------- .../portable/src/coveragetest-bsd-sockets.c | 43 ++++--- .../portable/src/coveragetest-no-sockets.c | 6 +- .../portable/src/coveragetest-posix-io.c | 24 ++-- .../ut-stubs/CMakeLists.txt | 4 +- .../src/os-shared-clock-impl-handlers.c | 52 ++++++++ .../ut-stubs/src/os-shared-clock-impl-stubs.c | 4 +- .../ut-stubs/src/os-shared-file-impl-stubs.c | 8 +- .../src/os-shared-select-impl-stubs.c | 8 +- .../src/os-shared-sockets-impl-stubs.c | 12 +- src/ut-stubs/osapi-clock-stubs.c | 32 +++++ src/ut-stubs/osapi-file-stubs.c | 38 ++++++ src/ut-stubs/osapi-sockets-stubs.c | 21 ++++ 28 files changed, 661 insertions(+), 189 deletions(-) create mode 100644 src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-handlers.c diff --git a/src/os/inc/osapi-clock.h b/src/os/inc/osapi-clock.h index 50cc82c6d..9c8f489b1 100644 --- a/src/os/inc/osapi-clock.h +++ b/src/os/inc/osapi-clock.h @@ -47,6 +47,29 @@ typedef struct int64 ticks; /**< Ticks elapsed since reference point */ } OS_time_t; +/** + * @brief The maximum value for OS_time_t + * + * This is the largest positive (future) time that is representable + * in an OS_time_t value. + */ +#define OS_TIME_MAX ((OS_time_t) {INT64_MAX}) + +/** + * @brief The zero value for OS_time_t + * + * This is a reasonable initializer/placeholder value for an OS_time_t + */ +#define OS_TIME_ZERO ((OS_time_t) {0}) + +/** + * @brief The minimum value for OS_time_t + * + * This is the largest negative (past) time that is representable + * in an OS_time_t value. + */ +#define OS_TIME_MIN ((OS_time_t) {INT64_MIN}) + /** * @brief Multipliers/divisors to convert ticks into standardized units * @@ -102,6 +125,45 @@ int32 OS_GetLocalTime(OS_time_t *time_struct); */ int32 OS_SetLocalTime(const OS_time_t *time_struct); +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Gets an absolute time value relative to the current time + * + * This function adds the given interval, expressed in milliseconds, to the + * current clock and returns the result. + * + * @note This is intended to ease transitioning from a relative timeout value to + * and absolute timeout value. The result can be passed to any function + * that accepts an absolute timeout, to mimic the behavior of a relative timeout. + * + * @param[in] relative_msec A relative time interval, in milliseconds + * + * @returns Absolute time value after adding interval + */ +OS_time_t OS_TimeFromRelativeMilliseconds(int32 relative_msec); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Gets a relative time value from an absolute time + * + * This function computes the number of milliseconds until the given + * absolute time value is reached in the system clock. + * + * @note This is intended to ease transitioning from a relative timeout value to + * and absolute timeout value. The result can be passed to any function + * that accepts a relative timeout, to mimic the behavior of an absolute timeout. + * + * The return value of this function is intended to be compatible with the relative + * timeout parameter of various OSAL APIs e.g. OS_TimedRead() / OS_TimedWrite() + * + * @param[in] time An absolute time value + * + * @returns Milliseconds until time value will be reached + * @retval OS_CHECK (0) if time is the current time or is in the past + * @retval OS_PEND (-1) if time is far in the future (not expressable as an int32) + */ +int32 OS_TimeToRelativeMilliseconds(OS_time_t time); + /*-------------------------------------------------------------------------------------*/ /* * Accessor / Unit Conversion routines for OS_time_t @@ -485,6 +547,60 @@ static inline OS_time_t OS_TimeSubtract(OS_time_t time1, OS_time_t time2) return ostm; } +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Checks if two time values are equal + * + * @param[in] time1 The first time value + * @param[in] time2 The second time value + * + * @retval true if the two values are equal + * @retval false if the two values are not equal + */ +static inline bool OS_TimeEqual(OS_time_t time1, OS_time_t time2) +{ + return (time1.ticks == time2.ticks); +} + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Checks the sign of the time value + * + * @param[in] time The time to check + * + * @retval -1 if the time value is negative / below 0 + * @retval 0 if the time value is 0 + * @retval 1 if the time value is positive / above 0 + */ +static inline int8_t OS_TimeGetSign(OS_time_t time) +{ + if (time.ticks > 0) + { + return 1; + } + if (time.ticks < 0) + { + return -1; + } + return 0; +} + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Compares two time values + * + * @param[in] time1 The first time + * @param[in] time2 The second time + * + * @retval -1 if the time1 < time2 + * @retval 0 if the times are equal + * @retval 1 if the time1 > time2 + */ +static inline int8_t OS_TimeCompare(OS_time_t time1, OS_time_t time2) +{ + return OS_TimeGetSign(OS_TimeSubtract(time1, time2)); +} + /**@}*/ #endif /* OSAPI_CLOCK_H */ diff --git a/src/os/inc/osapi-file.h b/src/os/inc/osapi-file.h index e039f2bfc..280482dcf 100644 --- a/src/os/inc/osapi-file.h +++ b/src/os/inc/osapi-file.h @@ -237,7 +237,49 @@ int32 OS_write(osal_id_t filedes, const void *buffer, size_t nbytes); * @param[in] filedes The handle ID to operate on * @param[out] buffer Storage location for file data @nonnull * @param[in] nbytes Maximum number of bytes to read @nonzero - * @param[in] timeout Maximum time to wait, in milliseconds (OS_PEND = forever) + * @param[in] abstime Absolute time at which this function should return, if no data is readable + * + * @returns Byte count on success or appropriate error code, see @ref OSReturnCodes + * @retval #OS_ERROR_TIMEOUT if no data became available during timeout period + * @retval #OS_ERR_INVALID_ID if the file descriptor passed in is invalid + * @retval #OS_ERR_INVALID_SIZE if the passed-in size is not valid + * @retval #OS_INVALID_POINTER if the passed-in buffer is not valid + * @retval 0 if at end of file/stream data + */ +int32 OS_AbsTimedRead(osal_id_t filedes, void *buffer, size_t nbytes, OS_time_t abstime); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief File/Stream input read with a timeout + * + * This implements a time-limited read and is primarily intended for use with + * sockets but may also work with any other stream-like resource that the underlying + * OS supports, such as pipes or special devices. + * + * If data is immediately available on the file/socket, this will return that data + * along with the actual number of bytes that were immediately available. It will + * not block. + * + * If the file position is at the end of file or end of stream data (e.g. if the remote + * end has closed the connection), then this function will immediately return 0 without + * blocking for the timeout period. + * + * If no data is immediately available, but the underlying resource/stream is still + * connected to a peer, this will wait up to the given timeout for additional + * data to appear. If no data appears within the timeout period, then this returns + * the #OS_ERROR_TIMEOUT status code. This allows the caller to differentiate + * an open (but idle) socket connection from a connection which has been closed + * by the remote peer. + * + * In all cases this will return successfully as soon as at least 1 byte of actual + * data is available. It will not attempt to read the entire input buffer. + * + * If an EOF condition occurs prior to timeout, this function returns zero. + * + * @param[in] filedes The handle ID to operate on + * @param[out] buffer Storage location for file data @nonnull + * @param[in] nbytes Maximum number of bytes to read @nonzero + * @param[in] timeout Maximum time to wait, in milliseconds, relative to current time (OS_PEND = forever) * * @returns Byte count on success or appropriate error code, see @ref OSReturnCodes * @retval #OS_ERROR_TIMEOUT if no data became available during timeout period @@ -272,7 +314,42 @@ int32 OS_TimedRead(osal_id_t filedes, void *buffer, size_t nbytes, int32 timeout * @param[in] filedes The handle ID to operate on * @param[in] buffer Source location for file data @nonnull * @param[in] nbytes Maximum number of bytes to read @nonzero - * @param[in] timeout Maximum time to wait, in milliseconds (OS_PEND = forever) + * @param[in] abstime Absolute time at which this function should return, if no data is readable + * + * @return A non-negative byte count or appropriate error code, see @ref OSReturnCodes + * @retval #OS_ERROR_TIMEOUT if no data became available during timeout period + * @retval #OS_ERR_INVALID_ID if the file descriptor passed in is invalid + * @retval #OS_ERR_INVALID_SIZE if the passed-in size is not valid + * @retval #OS_INVALID_POINTER if the passed-in buffer is not valid + * @retval 0 if file/stream cannot accept any more data + */ +int32 OS_AbsTimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, OS_time_t abstime); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief File/Stream output write with a timeout + * + * This implements a time-limited write and is primarily intended for use with + * sockets but may also work with any other stream-like resource that the underlying + * OS supports. + * + * If output buffer space is immediately available on the file/socket, this will + * place data into the buffer and return the actual number of bytes that were + * queued for output. It will not block. + * + * If no output buffer space is immediately available, this will wait up to the + * given timeout for space to become available. If no space becomes available within + * the timeout period, then this returns an error code (not zero). + * + * In all cases this will return successfully as soon as at least 1 byte of actual + * data is output. It will _not_ attempt to write the entire output buffer. + * + * If an EOF condition occurs prior to timeout, this function returns zero. + * + * @param[in] filedes The handle ID to operate on + * @param[in] buffer Source location for file data @nonnull + * @param[in] nbytes Maximum number of bytes to read @nonzero + * @param[in] timeout Maximum time to wait, in milliseconds, relative to current time (OS_PEND = forever) * * @return A non-negative byte count or appropriate error code, see @ref OSReturnCodes * @retval #OS_ERROR_TIMEOUT if no data became available during timeout period diff --git a/src/os/inc/osapi-sockets.h b/src/os/inc/osapi-sockets.h index 93d046527..f461dedc4 100644 --- a/src/os/inc/osapi-sockets.h +++ b/src/os/inc/osapi-sockets.h @@ -28,6 +28,7 @@ /* NOTE - osconfig.h may optionally specify the value for OS_SOCADDR_MAX_LEN */ #include "osconfig.h" #include "common_types.h" +#include "osapi-clock.h" /* * The absolute maximum size of a network address @@ -408,11 +409,43 @@ int32 OS_SocketAccept(osal_id_t sock_id, osal_id_t *connsock_id, OS_SockAddr_t * * If a message is already available on the socket, this should immediately return * that data without blocking. Otherwise, it may block up to the given timeout. * + * This API is identical to OS_SocketRecvFrom() except for the timeout parameter. In + * this call, timeout is expressed as an absolute value of the OS clock, in the same + * time domain as obtained via OS_GetLocalTime(). This allows for a more precise + * timeout than what is possible via the normal OS_SocketRecvFrom(). + * * @param[in] sock_id The socket ID, previously bound using OS_SocketBind() * @param[out] buffer Pointer to message data receive buffer @nonnull * @param[in] buflen The maximum length of the message data to receive @nonzero * @param[out] RemoteAddr Buffer to store the remote network address (may be NULL) - * @param[in] timeout The maximum amount of time to wait, or OS_PEND to wait forever + * @param[in] abs_timeout The absolute time at which the call should return if nothing received + * + * @return Count of actual bytes received or error status, see @ref OSReturnCodes + * @retval #OS_INVALID_POINTER if argument is NULL + * @retval #OS_ERR_INVALID_SIZE if passed-in buflen is not valid + * @retval #OS_ERR_INVALID_ID if the sock_id parameter is not valid + * @retval #OS_ERR_INCORRECT_OBJ_TYPE if the handle is not a socket + */ +int32 OS_AbsSocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, + OS_time_t abs_timeout); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Reads data from a message-oriented (datagram) socket + * + * If a message is already available on the socket, this should immediately return + * that data without blocking. Otherwise, it may block up to the given timeout. + * + * The timeout is expressed in milliseconds, relative to the time that the API was + * invoked. Use OS_AbsSocketRecvFrom() for higher timing precision. + * + * @param[in] sock_id The socket ID, previously bound using OS_SocketBind() + * @param[out] buffer Pointer to message data receive buffer @nonnull + * @param[in] buflen The maximum length of the message data to receive @nonzero + * @param[out] RemoteAddr Buffer to store the remote network address (may be NULL) + * @param[in] timeout The maximum amount of time to wait or OS_PEND to wait forever + * + * @sa OS_AbsSocketRecvFrom() * * @return Count of actual bytes received or error status, see @ref OSReturnCodes * @retval #OS_INVALID_POINTER if argument is NULL diff --git a/src/os/portable/os-impl-bsd-select.c b/src/os/portable/os-impl-bsd-select.c index baa516797..162909b04 100644 --- a/src/os/portable/os-impl-bsd-select.c +++ b/src/os/portable/os-impl-bsd-select.c @@ -41,6 +41,7 @@ #include #include "os-impl-select.h" +#include "os-shared-clock.h" #include "os-shared-select.h" #include "os-shared-idmap.h" @@ -163,68 +164,52 @@ static void OS_FdSet_ConvertOut_Impl(fd_set *OS_set, OS_FdSet *OSAL_set) * Actual implementation of select() call * Used by SelectSingle and SelectMultiple implementations (below) *-----------------------------------------------------------------*/ -static int32 OS_DoSelect(int maxfd, fd_set *rd_set, fd_set *wr_set, int32 msecs) +static int32 OS_DoSelect(int maxfd, fd_set *rd_set, fd_set *wr_set, OS_time_t abs_timeout) { int os_status; int32 return_code; struct timeval tv; struct timeval *tvptr; - struct timespec ts_now; - struct timespec ts_end; + OS_time_t curr_time; - if (msecs > 0) + /* Implementations may pass OS_TIME_MAX to mean wait forever */ + if (OS_TimeEqual(abs_timeout, OS_TIME_MAX)) { - clock_gettime(CLOCK_MONOTONIC, &ts_now); - ts_end.tv_sec = ts_now.tv_sec + (msecs / 1000); - ts_end.tv_nsec = ts_now.tv_nsec + (1000000 * (msecs % 1000)); - if (ts_end.tv_nsec >= 1000000000) - { - ++ts_end.tv_sec; - ts_end.tv_nsec -= 1000000000; - } + tvptr = NULL; } else { - /* Zero for consistency and to avoid possible confusion if not cleared */ - memset(&ts_end, 0, sizeof(ts_end)); + /* Not waiting forever, some form of timeout will be calculated */ + tvptr = &tv; } + curr_time = abs_timeout; + do { - if (msecs < 0) - { - tvptr = NULL; - } - else if (msecs == 0) - { - tvptr = &tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - } - else + if (tvptr != NULL) { - tvptr = &tv; - - clock_gettime(CLOCK_MONOTONIC, &ts_now); - - /* note that the tv_sec and tv_usec/tv_nsec values are all signed longs, so OK to subtract */ - tv.tv_sec = ts_end.tv_sec - ts_now.tv_sec; - tv.tv_usec = (ts_end.tv_nsec - ts_now.tv_nsec) / 1000; - - if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec < 0)) + if (OS_TimeGetSign(abs_timeout) > 0) { - os_status = 0; - break; + OS_GetLocalTime_Impl(&curr_time); + curr_time = OS_TimeSubtract(abs_timeout, curr_time); } - - if (tv.tv_usec < 0) + if (OS_TimeGetSign(curr_time) <= 0) { - tv.tv_usec += 1000000; - --tv.tv_sec; + /* timeout has already passed - this will still poll, but not block */ + tv.tv_sec = 0; + tv.tv_usec = 0; + } + else + { + /* timeout is in the future */ + tv.tv_sec = OS_TimeGetTotalSeconds(curr_time); + tv.tv_usec = OS_TimeGetMicrosecondsPart(curr_time); } } os_status = select(maxfd + 1, rd_set, wr_set, NULL, tvptr); + } while (os_status < 0 && (errno == EINTR || errno == EAGAIN)); if (os_status < 0) @@ -253,7 +238,7 @@ static int32 OS_DoSelect(int maxfd, fd_set *rd_set, fd_set *wr_set, int32 msecs) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, int32 msecs) +int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, OS_time_t abs_timeout) { int32 return_code; fd_set wr_set; @@ -290,7 +275,7 @@ int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, FD_SET(impl->fd, &wr_set); } - return_code = OS_DoSelect(impl->fd, &rd_set, &wr_set, msecs); + return_code = OS_DoSelect(impl->fd, &rd_set, &wr_set, abs_timeout); if (return_code == OS_SUCCESS) { @@ -323,7 +308,7 @@ int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) +int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, OS_time_t abs_timeout) { fd_set wr_set; fd_set rd_set; @@ -352,7 +337,7 @@ int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) if (maxfd >= 0) { - return_code = OS_DoSelect(maxfd, &rd_set, &wr_set, msecs); + return_code = OS_DoSelect(maxfd, &rd_set, &wr_set, abs_timeout); } else { diff --git a/src/os/portable/os-impl-bsd-sockets.c b/src/os/portable/os-impl-bsd-sockets.c index de03b270a..3102d0aac 100644 --- a/src/os/portable/os-impl-bsd-sockets.c +++ b/src/os/portable/os-impl-bsd-sockets.c @@ -52,6 +52,7 @@ #include #include "os-impl-sockets.h" +#include "os-shared-clock.h" #include "os-shared-file.h" #include "os-shared-select.h" #include "os-shared-sockets.h" @@ -284,7 +285,7 @@ int32 OS_SocketListen_Impl(const OS_object_token_t *token) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, int32 timeout) +int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, OS_time_t abs_timeout) { int32 return_code; int os_status; @@ -345,7 +346,7 @@ int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t operation = OS_STREAM_STATE_WRITABLE; if (impl->selectable) { - return_code = OS_SelectSingle_Impl(token, &operation, timeout); + return_code = OS_SelectSingle_Impl(token, &operation, abs_timeout); } if (return_code == OS_SUCCESS) { @@ -422,7 +423,7 @@ int32 OS_SocketShutdown_Impl(const OS_object_token_t *token, OS_SocketShutdownMo * *-----------------------------------------------------------------*/ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_token_t *conn_token, - OS_SockAddr_t *Addr, int32 timeout) + OS_SockAddr_t *Addr, OS_time_t abs_timeout) { int32 return_code; uint32 operation; @@ -436,7 +437,7 @@ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_ operation = OS_STREAM_STATE_READABLE; if (sock_impl->selectable) { - return_code = OS_SelectSingle_Impl(sock_token, &operation, timeout); + return_code = OS_SelectSingle_Impl(sock_token, &operation, abs_timeout); } else { @@ -476,7 +477,7 @@ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_ * *-----------------------------------------------------------------*/ int32 OS_SocketRecvFrom_Impl(const OS_object_token_t *token, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, - int32 timeout) + OS_time_t abs_timeout) { int32 return_code; int os_result; @@ -507,11 +508,12 @@ int32 OS_SocketRecvFrom_Impl(const OS_object_token_t *token, void *buffer, size_ if (impl->selectable) { waitflags = MSG_DONTWAIT; - return_code = OS_SelectSingle_Impl(token, &operation, timeout); + return_code = OS_SelectSingle_Impl(token, &operation, abs_timeout); } else { - if (timeout == 0) + /* This is a backup option - check if the abs timeout would be a poll/check op */ + if (OS_TimeToRelativeMilliseconds(abs_timeout) == OS_CHECK) { waitflags = MSG_DONTWAIT; } diff --git a/src/os/portable/os-impl-no-sockets.c b/src/os/portable/os-impl-no-sockets.c index 0d14700d2..3c7f15f23 100644 --- a/src/os/portable/os-impl-no-sockets.c +++ b/src/os/portable/os-impl-no-sockets.c @@ -74,7 +74,7 @@ int32 OS_SocketListen_Impl(const OS_object_token_t *token) * * See prototype for argument/return detail *-----------------------------------------------------------------*/ -int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, int32 timeout) +int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, OS_time_t abs_timeout) { return OS_ERR_NOT_IMPLEMENTED; } @@ -95,7 +95,7 @@ int32 OS_SocketShutdown_Impl(const OS_object_token_t *token, OS_SocketShutdownMo * See prototype for argument/return detail *-----------------------------------------------------------------*/ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_token_t *conn_token, - OS_SockAddr_t *Addr, int32 timeout) + OS_SockAddr_t *Addr, OS_time_t abs_timeout) { return OS_ERR_NOT_IMPLEMENTED; } @@ -106,7 +106,7 @@ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_ * See prototype for argument/return detail *-----------------------------------------------------------------*/ int32 OS_SocketRecvFrom_Impl(const OS_object_token_t *token, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, - int32 timeout) + OS_time_t abs_timeout) { return OS_ERR_NOT_IMPLEMENTED; } diff --git a/src/os/portable/os-impl-posix-io.c b/src/os/portable/os-impl-posix-io.c index 5d9dc3b1e..9a0da4d8b 100644 --- a/src/os/portable/os-impl-posix-io.c +++ b/src/os/portable/os-impl-posix-io.c @@ -162,7 +162,7 @@ int32 OS_GenericSeek_Impl(const OS_object_token_t *token, int32 offset, uint32 w * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t nbytes, int32 timeout) +int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t nbytes, OS_time_t abs_timeout) { int32 return_code; ssize_t os_result; @@ -187,7 +187,7 @@ int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t n */ if (impl->selectable) { - return_code = OS_SelectSingle_Impl(token, &operation, timeout); + return_code = OS_SelectSingle_Impl(token, &operation, abs_timeout); } if (return_code == OS_SUCCESS && (operation & OS_STREAM_STATE_READABLE) != 0) @@ -215,7 +215,7 @@ int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t n * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, size_t nbytes, int32 timeout) +int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, size_t nbytes, OS_time_t abs_timeout) { int32 return_code; ssize_t os_result; @@ -240,7 +240,7 @@ int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, s */ if (impl->selectable) { - return_code = OS_SelectSingle_Impl(token, &operation, timeout); + return_code = OS_SelectSingle_Impl(token, &operation, abs_timeout); } if (return_code == OS_SUCCESS && (operation & OS_STREAM_STATE_WRITABLE) != 0) diff --git a/src/os/shared/inc/os-shared-file.h b/src/os/shared/inc/os-shared-file.h index 8c21f3bb4..a96797a74 100644 --- a/src/os/shared/inc/os-shared-file.h +++ b/src/os/shared/inc/os-shared-file.h @@ -85,7 +85,7 @@ int32 OS_GenericSeek_Impl(const OS_object_token_t *token, int32 offset, uint32 w Returns: Number of bytes read (non-negative) on success, or relevant error code (negative) ------------------------------------------------------------------*/ -int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t nbytes, int32 timeout); +int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t nbytes, OS_time_t abs_timeout); /*---------------------------------------------------------------- @@ -94,7 +94,7 @@ int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t n Returns: Number of bytes written (non-negative) on success, or relevant error code (negative) ------------------------------------------------------------------*/ -int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, size_t nbytes, int32 timeout); +int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, size_t nbytes, OS_time_t abs_timeout); /*---------------------------------------------------------------- diff --git a/src/os/shared/inc/os-shared-select.h b/src/os/shared/inc/os-shared-select.h index a2123762e..6d610e9b1 100644 --- a/src/os/shared/inc/os-shared-select.h +++ b/src/os/shared/inc/os-shared-select.h @@ -26,6 +26,7 @@ #ifndef OS_SHARED_SELECT_H #define OS_SHARED_SELECT_H +#include "osapi-clock.h" #include "osapi-select.h" #include "os-shared-globaldefs.h" @@ -48,7 +49,7 @@ Returns: OS_SUCCESS on success, or relevant error code OS_ERR_OPERATION_NOT_SUPPORTED if the specified file handle does not support select ------------------------------------------------------------------*/ -int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, int32 msecs); +int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, OS_time_t abs_timeout); /*---------------------------------------------------------------- @@ -71,6 +72,6 @@ int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, Returns: OS_SUCCESS on success, or relevant error code OS_ERR_OPERATION_NOT_SUPPORTED if the specified file handle(s) do not support select ------------------------------------------------------------------*/ -int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs); +int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, OS_time_t abs_timeout); #endif /* OS_SHARED_SELECT_H */ diff --git a/src/os/shared/inc/os-shared-sockets.h b/src/os/shared/inc/os-shared-sockets.h index 547d011f6..c1989bd92 100644 --- a/src/os/shared/inc/os-shared-sockets.h +++ b/src/os/shared/inc/os-shared-sockets.h @@ -75,7 +75,7 @@ int32 OS_SocketListen_Impl(const OS_object_token_t *token); Returns: OS_SUCCESS on success, or relevant error code ------------------------------------------------------------------*/ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_token_t *conn_token, - OS_SockAddr_t *Addr, int32 timeout); + OS_SockAddr_t *Addr, OS_time_t abs_timeout); /*---------------------------------------------------------------- @@ -84,7 +84,7 @@ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_ Returns: OS_SUCCESS on success, or relevant error code ------------------------------------------------------------------*/ -int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, int32 timeout); +int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, OS_time_t abs_timeout); /*---------------------------------------------------------------- @@ -105,7 +105,7 @@ int32 OS_SocketShutdown_Impl(const OS_object_token_t *token, OS_SocketShutdownMo Returns: OS_SUCCESS on success, or relevant error code ------------------------------------------------------------------*/ int32 OS_SocketRecvFrom_Impl(const OS_object_token_t *token, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, - int32 timeout); + OS_time_t abs_timeout); /*---------------------------------------------------------------- diff --git a/src/os/shared/src/osapi-clock.c b/src/os/shared/src/osapi-clock.c index bd42eb0c7..2cd0b0448 100644 --- a/src/os/shared/src/osapi-clock.c +++ b/src/os/shared/src/osapi-clock.c @@ -65,3 +65,83 @@ int32 OS_SetLocalTime(const OS_time_t *time_struct) return OS_SetLocalTime_Impl(time_struct); } + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + * Helper function to convert a relative timeout to absolute time + * + *-----------------------------------------------------------------*/ +OS_time_t OS_TimeFromRelativeMilliseconds(int32 relative_msec) +{ + OS_time_t abs_time; + + if (relative_msec == OS_CHECK) + { + abs_time = OS_TIME_ZERO; + } + else if (relative_msec > 0) + { + OS_GetLocalTime_Impl(&abs_time); + abs_time = OS_TimeAdd(abs_time, OS_TimeFromTotalMilliseconds(relative_msec)); + } + else + { + abs_time = OS_TIME_MAX; + } + + return abs_time; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + * Helper function to convert an absolute time to relative timeout + * + *-----------------------------------------------------------------*/ +int32 OS_TimeToRelativeMilliseconds(OS_time_t time) +{ + int64 relative_msec; + OS_time_t curr_time; + + /* + * This is an optimization that assumes all negative time values are + * in the past - no need to read the clock to figure that out. + * + * Also OS_TIME_MAX is equivalent to pend forever, and does not + * need to read the clock either. + */ + if (OS_TimeGetSign(time) <= 0 || OS_TimeEqual(time, OS_TIME_MAX)) + { + curr_time = time; + } + else + { + OS_GetLocalTime_Impl(&curr_time); + curr_time = OS_TimeSubtract(time, curr_time); + } + + if (OS_TimeGetSign(curr_time) <= 0) + { + /* map this to a polling op (OS_CHECK) */ + relative_msec = OS_CHECK; + } + else + { + /* note this result is 64 bits, as this can exceed int32 potentially */ + relative_msec = OS_TimeGetTotalMilliseconds(curr_time); + + /* Just in case: cap the value at INT32_MAX */ + if (relative_msec > INT32_MAX) + { + /* map this to an indefinite block (OS_PEND) */ + relative_msec = OS_PEND; + } + } + + return relative_msec; +} diff --git a/src/os/shared/src/osapi-file.c b/src/os/shared/src/osapi-file.c index da5eb7a05..994ff217c 100644 --- a/src/os/shared/src/osapi-file.c +++ b/src/os/shared/src/osapi-file.c @@ -182,7 +182,7 @@ int32 OS_close(osal_id_t filedes) * See description in API and header file for detail * *-----------------------------------------------------------------*/ -int32 OS_TimedRead(osal_id_t filedes, void *buffer, size_t nbytes, int32 timeout) +int32 OS_AbsTimedRead(osal_id_t filedes, void *buffer, size_t nbytes, OS_time_t abstime) { OS_object_token_t token; int32 return_code; @@ -194,7 +194,7 @@ int32 OS_TimedRead(osal_id_t filedes, void *buffer, size_t nbytes, int32 timeout return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, LOCAL_OBJID_TYPE, filedes, &token); if (return_code == OS_SUCCESS) { - return_code = OS_GenericRead_Impl(&token, buffer, nbytes, timeout); + return_code = OS_GenericRead_Impl(&token, buffer, nbytes, abstime); OS_ObjectIdRelease(&token); } @@ -208,7 +208,18 @@ int32 OS_TimedRead(osal_id_t filedes, void *buffer, size_t nbytes, int32 timeout * See description in API and header file for detail * *-----------------------------------------------------------------*/ -int32 OS_TimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, int32 timeout) +int32 OS_TimedRead(osal_id_t filedes, void *buffer, size_t nbytes, int32 timeout) +{ + return OS_AbsTimedRead(filedes, buffer, nbytes, OS_TimeFromRelativeMilliseconds(timeout)); +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_AbsTimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, OS_time_t abstime) { OS_object_token_t token; int32 return_code; @@ -220,13 +231,24 @@ int32 OS_TimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, int32 return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, LOCAL_OBJID_TYPE, filedes, &token); if (return_code == OS_SUCCESS) { - return_code = OS_GenericWrite_Impl(&token, buffer, nbytes, timeout); + return_code = OS_GenericWrite_Impl(&token, buffer, nbytes, abstime); OS_ObjectIdRelease(&token); } return return_code; } +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_TimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, int32 timeout) +{ + return OS_AbsTimedWrite(filedes, buffer, nbytes, OS_TimeFromRelativeMilliseconds(timeout)); +} + /*---------------------------------------------------------------- * * Purpose: Implemented per public OSAL API diff --git a/src/os/shared/src/osapi-select.c b/src/os/shared/src/osapi-select.c index 21778cfb1..9d3ff5ca9 100644 --- a/src/os/shared/src/osapi-select.c +++ b/src/os/shared/src/osapi-select.c @@ -65,7 +65,7 @@ int32 OS_SelectSingle(osal_id_t objid, uint32 *StateFlags, int32 msecs) return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, OS_OBJECT_TYPE_OS_STREAM, objid, &token); if (return_code == OS_SUCCESS) { - return_code = OS_SelectSingle_Impl(&token, StateFlags, msecs); + return_code = OS_SelectSingle_Impl(&token, StateFlags, OS_TimeFromRelativeMilliseconds(msecs)); OS_ObjectIdRelease(&token); } @@ -94,7 +94,7 @@ int32 OS_SelectMultiple(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) * That means a file/socket can be closed while actively inside a * OS_SelectMultiple() call in another thread. */ - return_code = OS_SelectMultiple_Impl(ReadSet, WriteSet, msecs); + return_code = OS_SelectMultiple_Impl(ReadSet, WriteSet, OS_TimeFromRelativeMilliseconds(msecs)); return return_code; } diff --git a/src/os/shared/src/osapi-sockets.c b/src/os/shared/src/osapi-sockets.c index 6e47ffe1d..7b9e62381 100644 --- a/src/os/shared/src/osapi-sockets.c +++ b/src/os/shared/src/osapi-sockets.c @@ -342,7 +342,8 @@ int32 OS_SocketAccept(osal_id_t sock_id, osal_id_t *connsock_id, OS_SockAddr_t * OS_SocketAddrInit_Impl(Addr, sock->socket_domain); - return_code = OS_SocketAccept_Impl(&sock_token, &conn_token, Addr, timeout); + return_code = + OS_SocketAccept_Impl(&sock_token, &conn_token, Addr, OS_TimeFromRelativeMilliseconds(timeout)); if (return_code == OS_SUCCESS) { @@ -393,7 +394,7 @@ int32 OS_SocketConnect(osal_id_t sock_id, const OS_SockAddr_t *Addr, int32 Timeo } else { - return_code = OS_SocketConnect_Impl(&token, Addr, Timeout); + return_code = OS_SocketConnect_Impl(&token, Addr, OS_TimeFromRelativeMilliseconds(Timeout)); if (return_code == OS_SUCCESS) { @@ -467,7 +468,8 @@ int32 OS_SocketShutdown(osal_id_t sock_id, OS_SocketShutdownMode_t Mode) * See description in API and header file for detail * *-----------------------------------------------------------------*/ -int32 OS_SocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, int32 timeout) +int32 OS_AbsSocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, + OS_time_t abs_timeout) { OS_stream_internal_record_t *stream; OS_object_token_t token; @@ -497,7 +499,7 @@ int32 OS_SocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockA } else { - return_code = OS_SocketRecvFrom_Impl(&token, buffer, buflen, RemoteAddr, timeout); + return_code = OS_SocketRecvFrom_Impl(&token, buffer, buflen, RemoteAddr, abs_timeout); } OS_ObjectIdRelease(&token); @@ -506,6 +508,17 @@ int32 OS_SocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockA return return_code; } +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, int32 timeout) +{ + return OS_AbsSocketRecvFrom(sock_id, buffer, buflen, RemoteAddr, OS_TimeFromRelativeMilliseconds(timeout)); +} + /*---------------------------------------------------------------- * * Purpose: Implemented per public OSAL API diff --git a/src/tests/network-api-test/network-api-test.c b/src/tests/network-api-test/network-api-test.c index f2426c3e2..e206feb2d 100644 --- a/src/tests/network-api-test/network-api-test.c +++ b/src/tests/network-api-test/network-api-test.c @@ -378,6 +378,8 @@ void Server_Fn(void) ServerFn_AcceptStatus = OS_SocketAccept(s_socket_id, &connsock_id, &addr, OS_PEND); if (ServerFn_AcceptStatus != OS_SUCCESS) { + snprintf(ServerFn_ErrorString, sizeof(ServerFn_ErrorString), "OS_SocketAccept() iter=%u, return code=%d", + (unsigned int)iter, (int)Status); break; } diff --git a/src/unit-test-coverage/portable/src/coveragetest-bsd-select.c b/src/unit-test-coverage/portable/src/coveragetest-bsd-select.c index 8a6fcb24e..06579d772 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-bsd-select.c +++ b/src/unit-test-coverage/portable/src/coveragetest-bsd-select.c @@ -23,6 +23,7 @@ */ #include "os-portable-coveragetest.h" #include "ut-adaptor-portable-posix-io.h" +#include "os-shared-clock.h" #include "os-shared-select.h" #include "os-shared-idmap.h" @@ -34,89 +35,81 @@ void Test_OS_SelectSingle_Impl(void) /* Test Case For: * int32 OS_SelectSingle_Impl(uint32 stream_id, uint32 *SelectFlags, int32 msecs) */ - uint32 SelectFlags; - OS_object_token_t token; - struct OCS_timespec nowtime; - struct OCS_timespec latertime; - struct OCS_timespec latertime2; + uint32 SelectFlags; + OS_object_token_t token; + OS_time_t nowtime; + OS_time_t latertime; + OS_time_t timeout; memset(&token, 0, sizeof(token)); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, false); SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, OS_TIME_MIN), OS_ERR_OPERATION_NOT_SUPPORTED); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true); - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, OS_TIME_MIN), OS_SUCCESS); /* Cover FD_ISSET true branches and pend */ UT_SetDeferredRetcode(UT_KEY(OCS_FD_ISSET), 1, true); UT_SetDeferredRetcode(UT_KEY(OCS_FD_ISSET), 1, true); SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, -1), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, OS_TIME_MAX), OS_SUCCESS); /* No flags and non-read/write flag branches */ SelectFlags = 0; - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, OS_TIME_MIN), OS_SUCCESS); SelectFlags = OS_STREAM_STATE_BOUND; - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, OS_TIME_MIN), OS_SUCCESS); /* try a case where select() needs to be repeated to achieve the desired wait time */ - UT_ResetState(UT_KEY(OCS_clock_gettime)); UT_ResetState(UT_KEY(OCS_select)); UT_SetDefaultReturnValue(UT_KEY(OCS_select), -1); OCS_errno = OCS_EINTR; UT_SetDeferredRetcode(UT_KEY(OCS_select), 2, 0); - SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; - nowtime.tv_sec = 1; - nowtime.tv_nsec = 0; - latertime.tv_sec = 1; - latertime.tv_nsec = 800000000; - latertime2.tv_sec = 2; - latertime2.tv_nsec = 200000000; - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &nowtime, sizeof(nowtime), false); - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime, sizeof(latertime), false); - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime2, sizeof(latertime2), false); - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 1200), OS_ERROR_TIMEOUT); - UtAssert_STUB_COUNT(OCS_clock_gettime, 3); + SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; + nowtime = OS_TimeFromTotalMilliseconds(1000); + latertime = OS_TimeFromTotalMilliseconds(1800); + timeout = OS_TimeFromTotalMilliseconds(1200); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &nowtime, sizeof(nowtime), false); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &latertime, sizeof(latertime), false); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, timeout), OS_ERROR_TIMEOUT); + UtAssert_STUB_COUNT(OS_GetLocalTime_Impl, 2); UtAssert_STUB_COUNT(OCS_select, 2); /* Repeated select with alternate branches */ - OCS_errno = OCS_EAGAIN; - SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; - latertime2.tv_nsec = 300000000; - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &nowtime, sizeof(nowtime), false); - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime, sizeof(latertime), false); - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime2, sizeof(latertime2), false); - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 1200), OS_ERROR_TIMEOUT); - UtAssert_STUB_COUNT(OCS_clock_gettime, 6); - UtAssert_STUB_COUNT(OCS_select, 3); + OCS_errno = OCS_EAGAIN; + SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; + UT_SetDeferredRetcode(UT_KEY(OCS_select), 2, 0); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &nowtime, sizeof(nowtime), false); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &latertime, sizeof(latertime), false); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, timeout), OS_ERROR_TIMEOUT); + UtAssert_STUB_COUNT(OS_GetLocalTime_Impl, 4); + UtAssert_STUB_COUNT(OCS_select, 4); UT_SetDefaultReturnValue(UT_KEY(OCS_select), 0); - SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; - nowtime.tv_sec = 1; - nowtime.tv_nsec = 500000000; - latertime.tv_sec = 10; - latertime.tv_nsec = 0; - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &nowtime, sizeof(nowtime), false); - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime, sizeof(latertime), false); - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 999), OS_ERROR_TIMEOUT); + SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; + nowtime = OS_TimeFromTotalMilliseconds(1500); + latertime = OS_TimeFromTotalMilliseconds(10000); + timeout = OS_TimeFromTotalMilliseconds(999); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &nowtime, sizeof(nowtime), false); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &latertime, sizeof(latertime), false); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, timeout), OS_ERROR_TIMEOUT); UT_SetDefaultReturnValue(UT_KEY(OCS_select), -1); - OCS_errno = OCS_ETIMEDOUT; - SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; - nowtime.tv_sec = 1; - nowtime.tv_nsec = 0; - latertime.tv_sec = 2; - latertime.tv_nsec = 600000000; - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &nowtime, sizeof(nowtime), false); - UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime, sizeof(latertime), false); - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 2100), OS_ERROR); + OCS_errno = OCS_ETIMEDOUT; + SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; + nowtime = OS_TimeFromTotalMilliseconds(1000); + latertime = OS_TimeFromTotalMilliseconds(2600); + timeout = OS_TimeFromTotalMilliseconds(2100); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &nowtime, sizeof(nowtime), false); + UT_SetDataBuffer(UT_KEY(OS_GetLocalTime_Impl), &latertime, sizeof(latertime), false); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, timeout), OS_ERROR); /* Test cases where the FD exceeds FD_SETSIZE */ SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE; UT_PortablePosixIOTest_Set_FD(UT_INDEX_0, OCS_FD_SETSIZE); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true); - OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, OS_TIME_MIN), OS_ERR_OPERATION_NOT_SUPPORTED); } void Test_OS_SelectMultiple_Impl(void) @@ -134,9 +127,9 @@ void Test_OS_SelectMultiple_Impl(void) memset(&ReadSet, 0, sizeof(ReadSet)); memset(&WriteSet, 0, sizeof(WriteSet)); WriteSet.object_ids[0] = 1; - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (NULL, &WriteSet, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (NULL, &WriteSet, OS_TIME_MIN), OS_SUCCESS); ReadSet.object_ids[0] = 1; - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, NULL, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, NULL, OS_TIME_MIN), OS_SUCCESS); /* Branches for processing the set */ UT_SetDeferredRetcode(UT_KEY(OCS_FD_ISSET), 1, true); @@ -144,37 +137,37 @@ void Test_OS_SelectMultiple_Impl(void) UT_PortablePosixIOTest_Set_FD(OSAL_INDEX_C(2), -1); UT_PortablePosixIOTest_Set_FD(OSAL_INDEX_C(3), 0); UT_PortablePosixIOTest_Set_Selectable(OSAL_INDEX_C(3), true); - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, OS_TIME_MIN), OS_SUCCESS); memset(&ReadSet, 0, sizeof(ReadSet)); memset(&WriteSet, 0, sizeof(WriteSet)); ReadSet.object_ids[0] = 1; UT_SetDeferredRetcode(UT_KEY(OCS_select), 1, 0); - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 1), OS_ERROR_TIMEOUT); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, OS_TIME_MAX), OS_ERROR_TIMEOUT); /* Test where the FD set is empty */ memset(&ReadSet, 0, sizeof(ReadSet)); memset(&WriteSet, 0, sizeof(WriteSet)); - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (NULL, NULL, 0), OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (NULL, NULL, OS_TIME_MIN), OS_ERR_INVALID_ID); /* Test cases where the FD exceeds FD_SETSIZE in the read set */ UT_PortablePosixIOTest_Set_FD(UT_INDEX_0, OCS_FD_SETSIZE); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true); memset(&ReadSet, 0xff, sizeof(ReadSet)); memset(&WriteSet, 0, sizeof(WriteSet)); - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, OS_TIME_MIN), OS_ERR_OPERATION_NOT_SUPPORTED); /* Test cases where the FD exceeds FD_SETSIZE in the write set */ memset(&ReadSet, 0, sizeof(ReadSet)); memset(&WriteSet, 0xff, sizeof(WriteSet)); - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, OS_TIME_MIN), OS_ERR_OPERATION_NOT_SUPPORTED); /* Test cases where additional bits are set in the OS_FdSet */ UT_PortablePosixIOTest_Set_FD(UT_INDEX_0, 0); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true); memset(&ReadSet, 0xff, sizeof(ReadSet)); memset(&WriteSet, 0xff, sizeof(WriteSet)); - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, OS_TIME_MIN), OS_ERR_OPERATION_NOT_SUPPORTED); /* * Cover OS_FdSet_ConvertOut_Impl for id < OS_MAX_NUM_OPEN_FILES, requires no errors from in conversion @@ -184,7 +177,7 @@ void Test_OS_SelectMultiple_Impl(void) { UT_PortablePosixIOTest_Set_FD(OSAL_INDEX_C(i), -1); } - OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, OS_TIME_MIN), OS_SUCCESS); } /* ------------------- End of test cases --------------------------------------*/ diff --git a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c index 90c8459bd..eaa227855 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c +++ b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c @@ -188,16 +188,16 @@ void Test_OS_SocketConnect_Impl(void) /* Default family case */ sa->sa_family = -1; addr.ActualLength = sizeof(struct OCS_sockaddr_in); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_ERR_BAD_ADDRESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_ERR_BAD_ADDRESS); /* Successful connect */ sa->sa_family = OCS_AF_INET; - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_SUCCESS); /* Fail connect, errno ! EINPROGRESS */ OCS_errno = ~OCS_EINPROGRESS; UT_SetDefaultReturnValue(UT_KEY(OCS_connect), -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_ERROR); /* Fail OS_SelectSingle_Impl, errno == EINPROGRESS */ OCS_errno = OCS_EINPROGRESS; @@ -205,30 +205,30 @@ void Test_OS_SocketConnect_Impl(void) addr.ActualLength = sizeof(struct OCS_sockaddr_in6); OS_impl_filehandle_table[0].selectable = true; UT_SetDeferredRetcode(UT_KEY(OS_SelectSingle_Impl), 1, UT_ERR_UNIQUE); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), UT_ERR_UNIQUE); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), UT_ERR_UNIQUE); /* Timeout error by clearing select flags with hook */ selectflags = 0; UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), UT_Hook_OS_SelectSingle_Impl, &selectflags); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_ERROR_TIMEOUT); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_ERROR_TIMEOUT); UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), NULL, NULL); /* Fail getsockopt status */ UT_SetDeferredRetcode(UT_KEY(OCS_getsockopt), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_ERROR); /* Nonzero getsockopt sockopt */ sockopt = 1; UT_SetHookFunction(UT_KEY(OCS_getsockopt), UT_Hook_OCS_getsockopt, &sockopt); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_ERROR); UT_SetHookFunction(UT_KEY(OCS_getsockopt), NULL, NULL); /* Success case with selectable */ - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_SUCCESS); /* Success case with not selectable */ OS_impl_filehandle_table[0].selectable = false; - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (&token, &addr, OS_TIME_MIN), OS_SUCCESS); } void Test_OS_SocketShutdown_Impl(void) @@ -262,21 +262,21 @@ void Test_OS_SocketAccept_Impl(void) /* Fail OS_SelectSingle_Impl with sock_token selectable */ OS_impl_filehandle_table[0].selectable = true; UT_SetDeferredRetcode(UT_KEY(OS_SelectSingle_Impl), 1, UT_ERR_UNIQUE); - OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), UT_ERR_UNIQUE); + OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, OS_TIME_MIN), UT_ERR_UNIQUE); /* Timeout by clearing select flags with hook */ selectflags = 0; UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), UT_Hook_OS_SelectSingle_Impl, &selectflags); - OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), OS_ERROR_TIMEOUT); + OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, OS_TIME_MIN), OS_ERROR_TIMEOUT); UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), NULL, NULL); /* Clear selectable and fail accept */ OS_impl_filehandle_table[0].selectable = false; UT_SetDeferredRetcode(UT_KEY(OCS_accept), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, OS_TIME_MIN), OS_ERROR); /* Success case */ - OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (&sock_token, &conn_token, &addr, OS_TIME_MIN), OS_SUCCESS); } void Test_OS_SocketRecvFrom_Impl(void) @@ -292,35 +292,38 @@ void Test_OS_SocketRecvFrom_Impl(void) /* NULL RemoteAddr, selectable, fail OS_SelectSingle_Impl */ OS_impl_filehandle_table[0].selectable = true; UT_SetDeferredRetcode(UT_KEY(OS_SelectSingle_Impl), 1, UT_ERR_UNIQUE); - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), NULL, 0), UT_ERR_UNIQUE); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), NULL, OS_TIME_MIN), UT_ERR_UNIQUE); /* Timeout by clearing select flags with hook */ selectflags = 0; UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), UT_Hook_OS_SelectSingle_Impl, &selectflags); - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, 0), OS_ERROR_TIMEOUT); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, OS_TIME_MIN), + OS_ERROR_TIMEOUT); UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), NULL, NULL); /* Not selectable, 0 timeout, EAGAIN error from recvfrom error */ OS_impl_filehandle_table[0].selectable = false; OCS_errno = OCS_EAGAIN; UT_SetDeferredRetcode(UT_KEY(OCS_recvfrom), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, 0), OS_QUEUE_EMPTY); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, OS_TIME_MIN), + OS_QUEUE_EMPTY); /* With timeout, other error from recvfrom error */ OCS_errno = 0; UT_SetDeferredRetcode(UT_KEY(OCS_recvfrom), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, 1), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, OS_TIME_MAX), OS_ERROR); /* With timeout, EWOULDBLOCK error from recvfrom error */ OCS_errno = OCS_EWOULDBLOCK; UT_SetDeferredRetcode(UT_KEY(OCS_recvfrom), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, 1), OS_QUEUE_EMPTY); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, OS_TIME_MAX), + OS_QUEUE_EMPTY); /* Success with NULL RemoteAddr */ - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), NULL, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), NULL, OS_TIME_MIN), OS_SUCCESS); /* Success with non-NULL RemoteAddr */ - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (&token, buffer, sizeof(buffer), &addr, OS_TIME_MIN), OS_SUCCESS); } void Test_OS_SocketSendTo_Impl(void) diff --git a/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c b/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c index 71a274180..6013b9637 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c +++ b/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c @@ -29,10 +29,10 @@ void Test_No_Sockets(void) OSAPI_TEST_FUNCTION_RC(OS_SocketOpen_Impl, (NULL), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketBindAddress_Impl, (NULL, NULL), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketListen_Impl, (NULL), OS_ERR_NOT_IMPLEMENTED); - OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (NULL, NULL, 0), OS_ERR_NOT_IMPLEMENTED); - OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (NULL, NULL, NULL, 0), OS_ERR_NOT_IMPLEMENTED); + OSAPI_TEST_FUNCTION_RC(OS_SocketConnect_Impl, (NULL, NULL, OS_TIME_MIN), OS_ERR_NOT_IMPLEMENTED); + OSAPI_TEST_FUNCTION_RC(OS_SocketAccept_Impl, (NULL, NULL, NULL, OS_TIME_MIN), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketShutdown_Impl, (NULL, 0), OS_ERR_NOT_IMPLEMENTED); - OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (NULL, NULL, 0, NULL, 0), OS_ERR_NOT_IMPLEMENTED); + OSAPI_TEST_FUNCTION_RC(OS_SocketRecvFrom_Impl, (NULL, NULL, 0, NULL, OS_TIME_MIN), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketSendTo_Impl, (NULL, NULL, 0, NULL), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketGetInfo_Impl, (NULL, NULL), OS_SUCCESS); OSAPI_TEST_FUNCTION_RC(OS_SocketAddrInit_Impl, (NULL, 0), OS_ERR_NOT_IMPLEMENTED); diff --git a/src/unit-test-coverage/portable/src/coveragetest-posix-io.c b/src/unit-test-coverage/portable/src/coveragetest-posix-io.c index e6a5a7708..737689978 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-posix-io.c +++ b/src/unit-test-coverage/portable/src/coveragetest-posix-io.c @@ -115,30 +115,30 @@ void Test_OS_GenericRead_Impl(void) UT_SetDataBuffer(UT_KEY(OCS_read), SrcData, sizeof(SrcData), false); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, false); - OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), 0), sizeof(DestData)); + OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), OS_TIME_MIN), sizeof(DestData)); UtAssert_MemCmp(SrcData, DestData, sizeof(SrcData), "read() data Valid"); /* test invocation of select() in nonblocking mode */ UT_ResetState(UT_KEY(OCS_read)); UT_SetDataBuffer(UT_KEY(OCS_read), SrcData, sizeof(SrcData), false); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true); - OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), 0), sizeof(DestData)); + OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), OS_TIME_MIN), sizeof(DestData)); UtAssert_True(UT_GetStubCount(UT_KEY(OS_SelectSingle_Impl)) == 1, "OS_SelectSingle() called"); /* Read 0 bytes */ - OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, 0, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, 0, OS_TIME_MIN), OS_SUCCESS); /* read() failure */ UT_SetDefaultReturnValue(UT_KEY(OCS_read), -1); - OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), 0), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), OS_TIME_MIN), OS_ERROR); /* Fail select */ UT_SetDeferredRetcode(UT_KEY(OS_SelectSingle_Impl), 1, OS_ERROR_TIMEOUT); - OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), 0), OS_ERROR_TIMEOUT); + OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), OS_TIME_MIN), OS_ERROR_TIMEOUT); /* Not readable */ UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), UT_Hook_OS_SelectSingle_Impl, NULL); - OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_GenericRead_Impl, (&token, DestData, sizeof(DestData), OS_TIME_MIN), OS_SUCCESS); UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), NULL, NULL); } @@ -156,30 +156,30 @@ void Test_OS_GenericWrite_Impl(void) UT_SetDataBuffer(UT_KEY(OCS_write), DestData, sizeof(DestData), false); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, false); - OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), 0), sizeof(SrcData)); + OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), OS_TIME_MIN), sizeof(SrcData)); UtAssert_MemCmp(SrcData, DestData, sizeof(SrcData), "write() data valid"); /* test invocation of select() in nonblocking mode */ UT_ResetState(UT_KEY(OCS_write)); UT_SetDataBuffer(UT_KEY(OCS_write), DestData, sizeof(DestData), false); UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true); - OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), 0), sizeof(SrcData)); + OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), OS_TIME_MIN), sizeof(SrcData)); UtAssert_True(UT_GetStubCount(UT_KEY(OS_SelectSingle_Impl)) == 1, "OS_SelectSingle() called"); /* Fail select */ UT_SetDeferredRetcode(UT_KEY(OS_SelectSingle_Impl), 1, OS_ERROR_TIMEOUT); - OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), 0), OS_ERROR_TIMEOUT); + OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), OS_TIME_MIN), OS_ERROR_TIMEOUT); /* Write 0 bytes */ - OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, 0, 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, 0, OS_TIME_MIN), OS_SUCCESS); /* write() failure */ UT_SetDefaultReturnValue(UT_KEY(OCS_write), -1); - OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, DestData, sizeof(DestData), 0), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, DestData, sizeof(DestData), OS_TIME_MIN), OS_ERROR); /* Not writeable */ UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), UT_Hook_OS_SelectSingle_Impl, NULL); - OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), 0), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_GenericWrite_Impl, (&token, SrcData, sizeof(SrcData), OS_TIME_MIN), OS_SUCCESS); UT_SetHookFunction(UT_KEY(OS_SelectSingle_Impl), NULL, NULL); } diff --git a/src/unit-test-coverage/ut-stubs/CMakeLists.txt b/src/unit-test-coverage/ut-stubs/CMakeLists.txt index b970cf8a2..d96eef819 100644 --- a/src/unit-test-coverage/ut-stubs/CMakeLists.txt +++ b/src/unit-test-coverage/ut-stubs/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(ut_osapi_stub_headers INTERFACE) target_include_directories(ut_osapi_stub_headers INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/inc ) -target_link_libraries(ut_osapi_stub_headers INTERFACE +target_link_libraries(ut_osapi_stub_headers INTERFACE ut_assert ) @@ -163,6 +163,7 @@ add_custom_target(generate_osal_coverage_stubs # and are not public API calls. This is only compiled if used. add_library(ut_osapi_impl_stubs STATIC EXCLUDE_FROM_ALL src/os-shared-binsem-impl-stubs.c + src/os-shared-clock-impl-handlers.c src/os-shared-clock-impl-stubs.c src/os-shared-common-impl-stubs.c src/os-shared-condvar-impl-stubs.c @@ -275,4 +276,3 @@ add_library(ut_bsp_impl_stubs STATIC EXCLUDE_FROM_ALL target_link_libraries(ut_bsp_impl_stubs PUBLIC ut_osapi_stub_headers ) - diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-handlers.c b/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-handlers.c new file mode 100644 index 000000000..6eda3b25f --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-handlers.c @@ -0,0 +1,52 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * Stub implementations for the functions defined in the OSAL API + * + * The stub implementation can be used for unit testing applications built + * on top of OSAL. The stubs do not do any real function, but allow + * the return code to be crafted such that error paths in the application + * can be executed. + */ + +#include "osapi-clock.h" /* OSAL public API for this subsystem */ +#include "os-shared-clock.h" +#include "utstubs.h" + +/* + * ----------------------------------------------------------------- + * Default handler implementation for 'OS_GetLocalTime_Impl' stub + * ----------------------------------------------------------------- + */ +void UT_DefaultHandler_OS_GetLocalTime_Impl(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + OS_time_t *time_struct = UT_Hook_GetArgValueByName(Context, "time_struct", OS_time_t *); + int32 status; + + UT_Stub_GetInt32StatusCode(Context, &status); + + if (status == OS_SUCCESS && + UT_Stub_CopyToLocal(UT_KEY(OS_GetLocalTime_Impl), time_struct, sizeof(*time_struct)) < sizeof(*time_struct)) + { + memset(time_struct, 0, sizeof(*time_struct)); + } +} diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c index 4e7c64470..e8f2160a2 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c @@ -25,6 +25,8 @@ #include "os-shared-clock.h" #include "utgenstub.h" +void UT_DefaultHandler_OS_GetLocalTime_Impl(void *, UT_EntryKey_t, const UT_StubContext_t *); + /* * ---------------------------------------------------- * Generated stub function for OS_GetLocalTime_Impl() @@ -36,7 +38,7 @@ int32 OS_GetLocalTime_Impl(OS_time_t *time_struct) UT_GenStub_AddParam(OS_GetLocalTime_Impl, OS_time_t *, time_struct); - UT_GenStub_Execute(OS_GetLocalTime_Impl, Basic, NULL); + UT_GenStub_Execute(OS_GetLocalTime_Impl, Basic, UT_DefaultHandler_OS_GetLocalTime_Impl); return UT_GenStub_GetReturnValue(OS_GetLocalTime_Impl, int32); } diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c index 75c5bebf6..87c418997 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c @@ -135,14 +135,14 @@ int32 OS_GenericClose_Impl(const OS_object_token_t *token) * Generated stub function for OS_GenericRead_Impl() * ---------------------------------------------------- */ -int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t nbytes, int32 timeout) +int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t nbytes, OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_GenericRead_Impl, int32); UT_GenStub_AddParam(OS_GenericRead_Impl, const OS_object_token_t *, token); UT_GenStub_AddParam(OS_GenericRead_Impl, void *, buffer); UT_GenStub_AddParam(OS_GenericRead_Impl, size_t, nbytes); - UT_GenStub_AddParam(OS_GenericRead_Impl, int32, timeout); + UT_GenStub_AddParam(OS_GenericRead_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_GenericRead_Impl, Basic, UT_DefaultHandler_OS_GenericRead_Impl); @@ -172,14 +172,14 @@ int32 OS_GenericSeek_Impl(const OS_object_token_t *token, int32 offset, uint32 w * Generated stub function for OS_GenericWrite_Impl() * ---------------------------------------------------- */ -int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, size_t nbytes, int32 timeout) +int32 OS_GenericWrite_Impl(const OS_object_token_t *token, const void *buffer, size_t nbytes, OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_GenericWrite_Impl, int32); UT_GenStub_AddParam(OS_GenericWrite_Impl, const OS_object_token_t *, token); UT_GenStub_AddParam(OS_GenericWrite_Impl, const void *, buffer); UT_GenStub_AddParam(OS_GenericWrite_Impl, size_t, nbytes); - UT_GenStub_AddParam(OS_GenericWrite_Impl, int32, timeout); + UT_GenStub_AddParam(OS_GenericWrite_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_GenericWrite_Impl, Basic, UT_DefaultHandler_OS_GenericWrite_Impl); diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-select-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-select-impl-stubs.c index e166537d2..9ba9a554d 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-select-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-select-impl-stubs.c @@ -30,13 +30,13 @@ * Generated stub function for OS_SelectMultiple_Impl() * ---------------------------------------------------- */ -int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) +int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_SelectMultiple_Impl, int32); UT_GenStub_AddParam(OS_SelectMultiple_Impl, OS_FdSet *, ReadSet); UT_GenStub_AddParam(OS_SelectMultiple_Impl, OS_FdSet *, WriteSet); - UT_GenStub_AddParam(OS_SelectMultiple_Impl, int32, msecs); + UT_GenStub_AddParam(OS_SelectMultiple_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_SelectMultiple_Impl, Basic, NULL); @@ -48,13 +48,13 @@ int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) * Generated stub function for OS_SelectSingle_Impl() * ---------------------------------------------------- */ -int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, int32 msecs) +int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_SelectSingle_Impl, int32); UT_GenStub_AddParam(OS_SelectSingle_Impl, const OS_object_token_t *, token); UT_GenStub_AddParam(OS_SelectSingle_Impl, uint32 *, SelectFlags); - UT_GenStub_AddParam(OS_SelectSingle_Impl, int32, msecs); + UT_GenStub_AddParam(OS_SelectSingle_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_SelectSingle_Impl, Basic, NULL); diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c index 5ec3ea0f9..5e258b095 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c @@ -45,14 +45,14 @@ void OS_SetSocketDefaultFlags_Impl(const OS_object_token_t *token) * ---------------------------------------------------- */ int32 OS_SocketAccept_Impl(const OS_object_token_t *sock_token, const OS_object_token_t *conn_token, - OS_SockAddr_t *Addr, int32 timeout) + OS_SockAddr_t *Addr, OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_SocketAccept_Impl, int32); UT_GenStub_AddParam(OS_SocketAccept_Impl, const OS_object_token_t *, sock_token); UT_GenStub_AddParam(OS_SocketAccept_Impl, const OS_object_token_t *, conn_token); UT_GenStub_AddParam(OS_SocketAccept_Impl, OS_SockAddr_t *, Addr); - UT_GenStub_AddParam(OS_SocketAccept_Impl, int32, timeout); + UT_GenStub_AddParam(OS_SocketAccept_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_SocketAccept_Impl, Basic, NULL); @@ -167,13 +167,13 @@ int32 OS_SocketBindAddress_Impl(const OS_object_token_t *token, const OS_SockAdd * Generated stub function for OS_SocketConnect_Impl() * ---------------------------------------------------- */ -int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, int32 timeout) +int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t *Addr, OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_SocketConnect_Impl, int32); UT_GenStub_AddParam(OS_SocketConnect_Impl, const OS_object_token_t *, token); UT_GenStub_AddParam(OS_SocketConnect_Impl, const OS_SockAddr_t *, Addr); - UT_GenStub_AddParam(OS_SocketConnect_Impl, int32, timeout); + UT_GenStub_AddParam(OS_SocketConnect_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_SocketConnect_Impl, Basic, NULL); @@ -235,7 +235,7 @@ int32 OS_SocketOpen_Impl(const OS_object_token_t *token) * ---------------------------------------------------- */ int32 OS_SocketRecvFrom_Impl(const OS_object_token_t *token, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, - int32 timeout) + OS_time_t abs_timeout) { UT_GenStub_SetupReturnBuffer(OS_SocketRecvFrom_Impl, int32); @@ -243,7 +243,7 @@ int32 OS_SocketRecvFrom_Impl(const OS_object_token_t *token, void *buffer, size_ UT_GenStub_AddParam(OS_SocketRecvFrom_Impl, void *, buffer); UT_GenStub_AddParam(OS_SocketRecvFrom_Impl, size_t, buflen); UT_GenStub_AddParam(OS_SocketRecvFrom_Impl, OS_SockAddr_t *, RemoteAddr); - UT_GenStub_AddParam(OS_SocketRecvFrom_Impl, int32, timeout); + UT_GenStub_AddParam(OS_SocketRecvFrom_Impl, OS_time_t, abs_timeout); UT_GenStub_Execute(OS_SocketRecvFrom_Impl, Basic, NULL); diff --git a/src/ut-stubs/osapi-clock-stubs.c b/src/ut-stubs/osapi-clock-stubs.c index 4d3b11bc8..27914ea91 100644 --- a/src/ut-stubs/osapi-clock-stubs.c +++ b/src/ut-stubs/osapi-clock-stubs.c @@ -59,3 +59,35 @@ int32 OS_SetLocalTime(const OS_time_t *time_struct) return UT_GenStub_GetReturnValue(OS_SetLocalTime, int32); } + +/* + * ---------------------------------------------------- + * Generated stub function for OS_TimeFromRelativeMilliseconds() + * ---------------------------------------------------- + */ +OS_time_t OS_TimeFromRelativeMilliseconds(int32 relative_msec) +{ + UT_GenStub_SetupReturnBuffer(OS_TimeFromRelativeMilliseconds, OS_time_t); + + UT_GenStub_AddParam(OS_TimeFromRelativeMilliseconds, int32, relative_msec); + + UT_GenStub_Execute(OS_TimeFromRelativeMilliseconds, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_TimeFromRelativeMilliseconds, OS_time_t); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_TimeToRelativeMilliseconds() + * ---------------------------------------------------- + */ +int32 OS_TimeToRelativeMilliseconds(OS_time_t time) +{ + UT_GenStub_SetupReturnBuffer(OS_TimeToRelativeMilliseconds, int32); + + UT_GenStub_AddParam(OS_TimeToRelativeMilliseconds, OS_time_t, time); + + UT_GenStub_Execute(OS_TimeToRelativeMilliseconds, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_TimeToRelativeMilliseconds, int32); +} diff --git a/src/ut-stubs/osapi-file-stubs.c b/src/ut-stubs/osapi-file-stubs.c index de52a1570..3a211cc51 100644 --- a/src/ut-stubs/osapi-file-stubs.c +++ b/src/ut-stubs/osapi-file-stubs.c @@ -35,6 +35,44 @@ void UT_DefaultHandler_OS_read(void *, UT_EntryKey_t, const UT_StubContext_t *); void UT_DefaultHandler_OS_stat(void *, UT_EntryKey_t, const UT_StubContext_t *); void UT_DefaultHandler_OS_write(void *, UT_EntryKey_t, const UT_StubContext_t *); +/* + * ---------------------------------------------------- + * Generated stub function for OS_AbsTimedRead() + * ---------------------------------------------------- + */ +int32 OS_AbsTimedRead(osal_id_t filedes, void *buffer, size_t nbytes, OS_time_t abstime) +{ + UT_GenStub_SetupReturnBuffer(OS_AbsTimedRead, int32); + + UT_GenStub_AddParam(OS_AbsTimedRead, osal_id_t, filedes); + UT_GenStub_AddParam(OS_AbsTimedRead, void *, buffer); + UT_GenStub_AddParam(OS_AbsTimedRead, size_t, nbytes); + UT_GenStub_AddParam(OS_AbsTimedRead, OS_time_t, abstime); + + UT_GenStub_Execute(OS_AbsTimedRead, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_AbsTimedRead, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_AbsTimedWrite() + * ---------------------------------------------------- + */ +int32 OS_AbsTimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, OS_time_t abstime) +{ + UT_GenStub_SetupReturnBuffer(OS_AbsTimedWrite, int32); + + UT_GenStub_AddParam(OS_AbsTimedWrite, osal_id_t, filedes); + UT_GenStub_AddParam(OS_AbsTimedWrite, const void *, buffer); + UT_GenStub_AddParam(OS_AbsTimedWrite, size_t, nbytes); + UT_GenStub_AddParam(OS_AbsTimedWrite, OS_time_t, abstime); + + UT_GenStub_Execute(OS_AbsTimedWrite, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_AbsTimedWrite, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_CloseAllFiles() diff --git a/src/ut-stubs/osapi-sockets-stubs.c b/src/ut-stubs/osapi-sockets-stubs.c index d8676076a..3c8940056 100644 --- a/src/ut-stubs/osapi-sockets-stubs.c +++ b/src/ut-stubs/osapi-sockets-stubs.c @@ -280,6 +280,27 @@ int32 OS_SocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockA return UT_GenStub_GetReturnValue(OS_SocketRecvFrom, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_AbsSocketRecvFrom() + * ---------------------------------------------------- + */ +int32 OS_AbsSocketRecvFrom(osal_id_t sock_id, void *buffer, size_t buflen, OS_SockAddr_t *RemoteAddr, + OS_time_t abs_timeout) +{ + UT_GenStub_SetupReturnBuffer(OS_AbsSocketRecvFrom, int32); + + UT_GenStub_AddParam(OS_AbsSocketRecvFrom, osal_id_t, sock_id); + UT_GenStub_AddParam(OS_AbsSocketRecvFrom, void *, buffer); + UT_GenStub_AddParam(OS_AbsSocketRecvFrom, size_t, buflen); + UT_GenStub_AddParam(OS_AbsSocketRecvFrom, OS_SockAddr_t *, RemoteAddr); + UT_GenStub_AddParam(OS_AbsSocketRecvFrom, OS_time_t, abs_timeout); + + UT_GenStub_Execute(OS_AbsSocketRecvFrom, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_AbsSocketRecvFrom, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketSendTo()