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