summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c')
-rw-r--r--FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c b/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c
new file mode 100644
index 000000000..a7cca7d46
--- /dev/null
+++ b/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c
@@ -0,0 +1,388 @@
+/*
+ * Amazon FreeRTOS POSIX V1.1.0
+ * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/**
+ * @file FreeRTOS_POSIX_utils.c
+ * @brief Implementation of utility functions in utils.h
+ */
+
+/* C standard library includes. */
+#include <stddef.h>
+#include <limits.h>
+
+/* FreeRTOS+POSIX includes. */
+#include "FreeRTOS_POSIX.h"
+#include "FreeRTOS_POSIX/errno.h"
+#include "FreeRTOS_POSIX/utils.h"
+
+/*-----------------------------------------------------------*/
+
+size_t UTILS_strnlen( const char * const pcString,
+ size_t xMaxLength )
+{
+ const char * pcCharPointer = pcString;
+ size_t xLength = 0;
+
+ if( pcString != NULL )
+ {
+ while( ( *pcCharPointer != '\0' ) && ( xLength < xMaxLength ) )
+ {
+ xLength++;
+ pcCharPointer++;
+ }
+ }
+
+ return xLength;
+}
+
+/*-----------------------------------------------------------*/
+
+int UTILS_AbsoluteTimespecToDeltaTicks( const struct timespec * const pxAbsoluteTime,
+ const struct timespec * const pxCurrentTime,
+ TickType_t * const pxResult )
+{
+ int iStatus = 0;
+ struct timespec xDifference = { 0 };
+
+ /* Check parameters. */
+ if( ( pxAbsoluteTime == NULL ) || ( pxCurrentTime == NULL ) || ( pxResult == NULL ) )
+ {
+ iStatus = EINVAL;
+ }
+
+ /* Calculate the difference between the current time and absolute time. */
+ if( iStatus == 0 )
+ {
+ iStatus = UTILS_TimespecSubtract( pxAbsoluteTime, pxCurrentTime, &xDifference );
+
+ if( iStatus == 1 )
+ {
+ /* pxAbsoluteTime was in the past. */
+ iStatus = ETIMEDOUT;
+ }
+ else if( iStatus == -1 )
+ {
+ /* error */
+ iStatus = EINVAL;
+ }
+ }
+
+ /* Convert the time difference to ticks. */
+ if( iStatus == 0 )
+ {
+ iStatus = UTILS_TimespecToTicks( &xDifference, pxResult );
+ }
+
+ return iStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+int UTILS_TimespecToTicks( const struct timespec * const pxTimespec,
+ TickType_t * const pxResult )
+{
+ int iStatus = 0;
+ int64_t llTotalTicks = 0;
+ long lNanoseconds = 0;
+
+ /* Check parameters. */
+ if( ( pxTimespec == NULL ) || ( pxResult == NULL ) )
+ {
+ iStatus = EINVAL;
+ }
+ else if( ( iStatus == 0 ) && ( UTILS_ValidateTimespec( pxTimespec ) == false ) )
+ {
+ iStatus = EINVAL;
+ }
+
+ if( iStatus == 0 )
+ {
+ /* Convert timespec.tv_sec to ticks. */
+ llTotalTicks = ( int64_t ) configTICK_RATE_HZ * ( pxTimespec->tv_sec );
+
+ /* Convert timespec.tv_nsec to ticks. This value does not have to be checked
+ * for overflow because a valid timespec has 0 <= tv_nsec < 1000000000 and
+ * NANOSECONDS_PER_TICK > 1. */
+ lNanoseconds = pxTimespec->tv_nsec / ( long ) NANOSECONDS_PER_TICK + /* Whole nanoseconds. */
+ ( long ) ( pxTimespec->tv_nsec % ( long ) NANOSECONDS_PER_TICK != 0 ); /* Add 1 to round up if needed. */
+
+ /* Add the nanoseconds to the total ticks. */
+ llTotalTicks += ( int64_t ) lNanoseconds;
+
+ /* Check for overflow */
+ if( llTotalTicks < 0 )
+ {
+ iStatus = EINVAL;
+ }
+ else
+ {
+ /* check if TickType_t is 32 bit or 64 bit */
+ uint32_t ulTickTypeSize = sizeof( TickType_t );
+
+ /* check for downcast overflow */
+ if( ulTickTypeSize == sizeof( uint32_t ) )
+ {
+ if( llTotalTicks > UINT_MAX )
+ {
+ iStatus = EINVAL;
+ }
+ }
+ }
+
+ /* Write result. */
+ *pxResult = ( TickType_t ) llTotalTicks;
+ }
+
+ return iStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+void UTILS_NanosecondsToTimespec( int64_t llSource,
+ struct timespec * const pxDestination )
+{
+ long lCarrySec = 0;
+
+ /* Convert to timespec. */
+ pxDestination->tv_sec = ( time_t ) ( llSource / NANOSECONDS_PER_SECOND );
+ pxDestination->tv_nsec = ( long ) ( llSource % NANOSECONDS_PER_SECOND );
+
+ /* Subtract from tv_sec if tv_nsec < 0. */
+ if( pxDestination->tv_nsec < 0L )
+ {
+ /* Compute the number of seconds to carry. */
+ lCarrySec = ( pxDestination->tv_nsec / ( long ) NANOSECONDS_PER_SECOND ) + 1L;
+
+ pxDestination->tv_sec -= ( time_t ) ( lCarrySec );
+ pxDestination->tv_nsec += lCarrySec * ( long ) NANOSECONDS_PER_SECOND;
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+int UTILS_TimespecAdd( const struct timespec * const x,
+ const struct timespec * const y,
+ struct timespec * const pxResult )
+{
+ int64_t llPartialSec = 0;
+ int iStatus = 0;
+
+ /* Check parameters. */
+ if( ( pxResult == NULL ) || ( x == NULL ) || ( y == NULL ) )
+ {
+ iStatus = -1;
+ }
+
+ if( iStatus == 0 )
+ {
+ /* Perform addition. */
+ pxResult->tv_nsec = x->tv_nsec + y->tv_nsec;
+
+ /* check for overflow in case nsec value was invalid */
+ if( pxResult->tv_nsec < 0 )
+ {
+ iStatus = 1;
+ }
+ else
+ {
+ llPartialSec = ( pxResult->tv_nsec ) / NANOSECONDS_PER_SECOND;
+ pxResult->tv_nsec = ( pxResult->tv_nsec ) % NANOSECONDS_PER_SECOND;
+ pxResult->tv_sec = x->tv_sec + y->tv_sec + llPartialSec;
+
+ /* check for overflow */
+ if( pxResult->tv_sec < 0 )
+ {
+ iStatus = 1;
+ }
+ }
+ }
+
+ return iStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+int UTILS_TimespecAddNanoseconds( const struct timespec * const x,
+ int64_t llNanoseconds,
+ struct timespec * const pxResult )
+{
+ int64_t llTotalNSec = 0;
+ int iStatus = 0;
+
+ /* Check parameters. */
+ if( ( pxResult == NULL ) || ( x == NULL ) )
+ {
+ iStatus = -1;
+ }
+
+ if( iStatus == 0 )
+ {
+ /* add nano seconds */
+ llTotalNSec = x->tv_nsec + llNanoseconds;
+
+ /* check for nano seconds overflow */
+ if( llTotalNSec < 0 )
+ {
+ iStatus = 1;
+ }
+ else
+ {
+ pxResult->tv_nsec = llTotalNSec % NANOSECONDS_PER_SECOND;
+ pxResult->tv_sec = x->tv_sec + ( llTotalNSec / NANOSECONDS_PER_SECOND );
+
+ /* check for seconds overflow */
+ if( pxResult->tv_sec < 0 )
+ {
+ iStatus = 1;
+ }
+ }
+ }
+
+ return iStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+int UTILS_TimespecSubtract( const struct timespec * const x,
+ const struct timespec * const y,
+ struct timespec * const pxResult )
+{
+ int iCompareResult = 0;
+ int iStatus = 0;
+
+ /* Check parameters. */
+ if( ( pxResult == NULL ) || ( x == NULL ) || ( y == NULL ) )
+ {
+ iStatus = -1;
+ }
+
+ if( iStatus == 0 )
+ {
+ iCompareResult = UTILS_TimespecCompare( x, y );
+
+ /* if x < y then result would be negative, return 1 */
+ if( iCompareResult == -1 )
+ {
+ iStatus = 1;
+ }
+ else if( iCompareResult == 0 )
+ {
+ /* if times are the same return zero */
+ pxResult->tv_sec = 0;
+ pxResult->tv_nsec = 0;
+ }
+ else
+ {
+ /* If x > y Perform subtraction. */
+ pxResult->tv_sec = x->tv_sec - y->tv_sec;
+ pxResult->tv_nsec = x->tv_nsec - y->tv_nsec;
+
+ /* check if nano seconds value needs to borrow */
+ if( pxResult->tv_nsec < 0 )
+ {
+ /* Based on comparison, tv_sec > 0 */
+ pxResult->tv_sec--;
+ pxResult->tv_nsec += ( long ) NANOSECONDS_PER_SECOND;
+ }
+
+ /* if nano second is negative after borrow, it is an overflow error */
+ if( pxResult->tv_nsec < 0 )
+ {
+ iStatus = -1;
+ }
+ }
+ }
+
+ return iStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+int UTILS_TimespecCompare( const struct timespec * const x,
+ const struct timespec * const y )
+{
+ int iStatus = 0;
+
+ /* Check parameters */
+ if( ( x == NULL ) && ( y == NULL ) )
+ {
+ iStatus = 0;
+ }
+ else if( y == NULL )
+ {
+ iStatus = 1;
+ }
+ else if( x == NULL )
+ {
+ iStatus = -1;
+ }
+ else if( x->tv_sec > y->tv_sec )
+ {
+ iStatus = 1;
+ }
+ else if( x->tv_sec < y->tv_sec )
+ {
+ iStatus = -1;
+ }
+ else
+ {
+ /* seconds are equal compare nano seconds */
+ if( x->tv_nsec > y->tv_nsec )
+ {
+ iStatus = 1;
+ }
+ else if( x->tv_nsec < y->tv_nsec )
+ {
+ iStatus = -1;
+ }
+ else
+ {
+ iStatus = 0;
+ }
+ }
+
+ return iStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+bool UTILS_ValidateTimespec( const struct timespec * const pxTimespec )
+{
+ bool xReturn = false;
+
+ if( pxTimespec != NULL )
+ {
+ /* Verify 0 <= tv_nsec < 1000000000. */
+ if( ( pxTimespec->tv_nsec >= 0 ) &&
+ ( pxTimespec->tv_nsec < NANOSECONDS_PER_SECOND ) )
+ {
+ xReturn = true;
+ }
+ }
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/