Skip to content

Commit

Permalink
(Draft) Fix nasa#1455, High-res timed stream ops
Browse files Browse the repository at this point in the history
Implement high-res timed operations for streams.  This uses an absolute
time via the OS_time_t value, which has a default resolution of 0.1usec
but is configurable.
  • Loading branch information
jphickey committed Mar 6, 2024
1 parent 342d7e3 commit 9fe43bc
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 4 deletions.
81 changes: 79 additions & 2 deletions src/os/inc/osapi-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
49 changes: 47 additions & 2 deletions src/os/shared/src/osapi-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,29 @@ int32 OS_FileIteratorClose(osal_id_t filedes, void *arg)
return OS_close(filedes);
}

/*----------------------------------------------------------------
*
* Helper function to convert a relative timeout to absolute time
*
*-----------------------------------------------------------------*/
OS_time_t OS_TimeFromRelative(int32 relative_msec)
{
OS_time_t AbsTime;

if (relative_msec > 0)
{
OS_GetLocalTime(&AbsTime);
OS_TimeAdd(AbsTime, OS_TimeFromTotalMilliseconds(relative_msec));
}
else
{
AbsTime = OS_TIME_MAX;
}

return AbsTime;
}


/****************************************************************************************
FILE API
***************************************************************************************/
Expand Down Expand Up @@ -182,7 +205,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;
Expand All @@ -208,7 +231,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_TimeFromRelative(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;
Expand All @@ -227,6 +261,17 @@ int32 OS_TimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, int32
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_TimeFromRelative(timeout));
}

/*----------------------------------------------------------------
*
* Purpose: Implemented per public OSAL API
Expand Down

0 comments on commit 9fe43bc

Please sign in to comment.