diff --git a/FreeRTOS/Source b/FreeRTOS/Source index 4b7ac8411e8..eb8c2a7138a 160000 --- a/FreeRTOS/Source +++ b/FreeRTOS/Source @@ -1 +1 @@ -Subproject commit 4b7ac8411e896301f679d2ff328139a96fc5d872 +Subproject commit eb8c2a7138aede84a63da4b09a3c0e2ad7943768 diff --git a/FreeRTOS/Test/CMock/smp/Makefile b/FreeRTOS/Test/CMock/smp/Makefile index 4d33f50a5b8..65e8b1db06b 100644 --- a/FreeRTOS/Test/CMock/smp/Makefile +++ b/FreeRTOS/Test/CMock/smp/Makefile @@ -18,7 +18,6 @@ SUITES += config_assert # SUITS for granular lock feature SUITES += granular_lock -SUITES += granular_lock_timer # PROJECT and SUITE variables are determined based on path like so: # $(UT_ROOT_DIR)/$(PROJECT)/$(SUITE) diff --git a/FreeRTOS/Test/CMock/smp/global_vars.h b/FreeRTOS/Test/CMock/smp/global_vars.h index 377cc274f9e..a39e5de5142 100644 --- a/FreeRTOS/Test/CMock/smp/global_vars.h +++ b/FreeRTOS/Test/CMock/smp/global_vars.h @@ -61,47 +61,56 @@ typedef BaseType_t TaskRunning_t; +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { - volatile StackType_t * pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + volatile StackType_t * pxTopOfStack; /**< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ #if ( portUSING_MPU_WRAPPERS == 1 ) - xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + xMPU_SETTINGS xMPUSettings; /**< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ #endif #if ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 ) - UBaseType_t uxCoreAffinityMask; /*< Used to link the task to certain cores. UBaseType_t must have greater than or equal to the number of bits as confNUM_CORES. */ + UBaseType_t uxCoreAffinityMask; /**< Used to link the task to certain cores. UBaseType_t must have greater than or equal to the number of bits as configNUMBER_OF_CORES. */ #endif - ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ - ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ - UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ - StackType_t * pxStack; /*< Points to the start of the stack. */ + ListItem_t xStateListItem; /**< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /**< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /**< The priority of the task. 0 is the lowest priority. */ + StackType_t * pxStack; /**< Points to the start of the stack. */ #if ( configNUMBER_OF_CORES > 1 ) - volatile TaskRunning_t xTaskRunState; /*< Used to identify the core the task is running on, if the task is running. Otherwise, identifies the task's state - not running or yielding. */ - UBaseType_t uxTaskAttributes; /*< Task's attributes - currently used to identify the idle tasks. */ + volatile BaseType_t xTaskRunState; /**< Used to identify the core the task is running on, if the task is running. Otherwise, identifies the task's state - not running or yielding. */ + UBaseType_t uxTaskAttributes; /**< Task's attributes - currently used to identify the idle tasks. */ #endif - char pcTaskName[ configMAX_TASK_NAME_LEN ]; /*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ]; /**< Descriptive name given to the task when created. Facilitates debugging only. */ #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - BaseType_t xPreemptionDisable; /*< Used to prevent the task from being preempted. */ + UBaseType_t uxPreemptionDisable; /**< Used to prevent the task from being preempted. */ + #endif + + #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) + UBaseType_t uxDeferredStateChange; /**< Used to indicate if the task's state change is deferred. */ #endif #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) - StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */ + StackType_t * pxEndOfStack; /**< Points to the highest valid address for the stack. */ #endif #if ( portCRITICAL_NESTING_IN_TCB == 1 ) - UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + UBaseType_t uxCriticalNesting; /**< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ #endif #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ - UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + UBaseType_t uxTCBNumber; /**< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /**< Stores a number specifically for use by third party trace code. */ #endif #if ( configUSE_MUTEXES == 1 ) - UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxBasePriority; /**< The priority last assigned to the task - used by the priority inheritance mechanism. */ UBaseType_t uxMutexesHeld; #endif @@ -114,11 +123,11 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) - configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /**< Stores the amount of time the task has spent in the Running state. */ #endif - #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) - configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */ + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + configTLS_BLOCK_TYPE xTLSBlock; /**< Memory block used as Thread Local Storage (TLS) Block for the task. */ #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) @@ -128,8 +137,8 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to /* See the comments in FreeRTOS.h with the definition of * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ - #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ - uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ #endif #if ( INCLUDE_xTaskAbortDelay == 1 ) @@ -145,4 +154,62 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to * below to enable the use of older kernel aware debuggers. */ typedef tskTCB TCB_t; + +typedef struct QueuePointers +{ + int8_t * pcTail; /**< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t * pcReadFrom; /**< Points to the last place that a queued item was read from when the structure is used as a queue. */ +} QueuePointers_t; + +typedef struct SemaphoreData +{ + TaskHandle_t xMutexHolder; /**< The handle of the task that holds the mutex. */ + UBaseType_t uxRecursiveCallCount; /**< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ +} SemaphoreData_t; + +typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + int8_t * pcHead; /**< Points to the beginning of the queue storage area. */ + int8_t * pcWriteTo; /**< Points to the free next place in the storage area. */ + + union + { + QueuePointers_t xQueue; /**< Data required exclusively when this structure is used as a queue. */ + SemaphoreData_t xSemaphore; /**< Data required exclusively when this structure is used as a semaphore. */ + } u; + + List_t xTasksWaitingToSend; /**< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /**< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting; /**< The number of items currently in the queue. */ + UBaseType_t uxLength; /**< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /**< The size of each items that the queue will hold. */ + + volatile int8_t cRxLock; /**< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /**< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition * pxQueueSetContainer; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + + #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + portSPINLOCK_TYPE xTaskSpinlock; + portSPINLOCK_TYPE xISRSpinlock; + #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t + * name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + + #endif /* ifndef GLOBAL_VARS_H */ diff --git a/FreeRTOS/Test/CMock/smp/granular_lock/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/smp/granular_lock/FreeRTOSConfig.h index a2504e8a522..16c710be8ea 100644 --- a/FreeRTOS/Test/CMock/smp/granular_lock/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/smp/granular_lock/FreeRTOSConfig.h @@ -25,132 +25,132 @@ */ -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -#include "fake_assert.h" - -/*----------------------------------------------------------- -* Application specific definitions. -* -* These definitions should be adjusted for your particular hardware and -* application requirements. -* -* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE -* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See -* https://www.FreeRTOS.org/a00110.html -*----------------------------------------------------------*/ - -/* SMP test specific configuration */ -#define configRUN_MULTIPLE_PRIORITIES 1 -#define configNUMBER_OF_CORES 16 -#define configUSE_CORE_AFFINITY 0 -#define configUSE_TIME_SLICING 0 -#define configUSE_TASK_PREEMPTION_DISABLE 1 -#define configTICK_CORE 0 - -/* OS Configuration */ -#define configUSE_PREEMPTION 1 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 -#define configTICK_RATE_HZ ( 1000 ) -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) -#define configMAX_TASK_NAME_LEN ( 12 ) -#define configUSE_TRACE_FACILITY 1 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configCHECK_FOR_STACK_OVERFLOW 0 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 20 -#define configUSE_MALLOC_FAILED_HOOK 1 -#define configUSE_APPLICATION_TASK_TAG 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 -#define configUSE_QUEUE_SETS 1 -#define configUSE_TASK_NOTIFICATIONS 1 -#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) -#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 -#define portREMOVE_STATIC_QUALIFIER 1 -#define portCRITICAL_NESTING_IN_TCB 0 -#define portSTACK_GROWTH ( 1 ) -#define configUSE_PASSIVE_IDLE_HOOK 0 -#define configUSE_TICKLESS_IDLE 1 -#define configSTACK_DEPTH_TYPE uint32_t - -/* Software timer related configuration options. */ -#define configUSE_TIMERS 0 -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) -#define configTIMER_QUEUE_LENGTH 20 -#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) - -#define configMAX_PRIORITIES ( 7 ) - -/* Run time stats gathering configuration options. */ -unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ -void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() -#define portUSING_MPU_WRAPPERS 0 -#define portHAS_STACK_OVERFLOW_CHECKING 0 -#define configENABLE_MPU 0 - -/* Co-routine related configuration options. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) - -/* This demo makes use of one or more example stats formatting functions. These - * format the raw data provided by the uxTaskGetSystemState() function in to human - * readable ASCII form. See the notes in the implementation of vTaskList() within - * FreeRTOS/Source/tasks.c for limitations. */ -#define configUSE_STATS_FORMATTING_FUNCTIONS 1 - -/* Set the following definitions to 1 to include the API function, or zero - * to exclude the API function. In most cases the linker will remove unused - * functions anyway. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 0 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 -#define INCLUDE_xTaskGetIdleTaskHandle 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_xTaskGetHandle 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xSemaphoreGetMutexHolder 1 -#define INCLUDE_xTimerPendFunctionCall 0 -#define INCLUDE_xTaskAbortDelay 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 - -/* It is a good idea to define configASSERT() while developing. configASSERT() - * uses the same semantics as the standard C assert() macro. */ -#define configASSERT( x ) \ - do \ - { \ - if( x ) \ - { \ - vFakeAssert( true, __FILE__, __LINE__ ); \ - } \ - else \ - { \ - vFakeAssert( false, __FILE__, __LINE__ ); \ - } \ - } while( 0 ) - -#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 -#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 ) - extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ); - #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) -#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */ - -#endif /* FREERTOS_CONFIG_H */ + #ifndef FREERTOS_CONFIG_H + #define FREERTOS_CONFIG_H + + #include "fake_assert.h" + + /*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See + * https://www.FreeRTOS.org/a00110.html + *----------------------------------------------------------*/ + + /* SMP test specific configuration */ + #define configRUN_MULTIPLE_PRIORITIES 1 + #define configNUMBER_OF_CORES 16 + #define configUSE_CORE_AFFINITY 0 + #define configUSE_TIME_SLICING 0 + #define configUSE_TASK_PREEMPTION_DISABLE 1 + #define configTICK_CORE 0 + + /* OS Configuration */ + #define configUSE_PREEMPTION 1 + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 + #define configUSE_IDLE_HOOK 0 + #define configUSE_TICK_HOOK 0 + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + #define configTICK_RATE_HZ ( 1000 ) + #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) + #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) + #define configMAX_TASK_NAME_LEN ( 12 ) + #define configUSE_TRACE_FACILITY 1 + #define configUSE_16_BIT_TICKS 0 + #define configIDLE_SHOULD_YIELD 1 + #define configUSE_MUTEXES 1 + #define configCHECK_FOR_STACK_OVERFLOW 0 + #define configUSE_RECURSIVE_MUTEXES 1 + #define configQUEUE_REGISTRY_SIZE 20 + #define configUSE_MALLOC_FAILED_HOOK 1 + #define configUSE_APPLICATION_TASK_TAG 1 + #define configUSE_COUNTING_SEMAPHORES 1 + #define configUSE_ALTERNATIVE_API 0 + #define configUSE_QUEUE_SETS 1 + #define configUSE_TASK_NOTIFICATIONS 1 + #define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 + #define configSUPPORT_STATIC_ALLOCATION 0 + #define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) + #define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 + #define portREMOVE_STATIC_QUALIFIER 1 + #define portCRITICAL_NESTING_IN_TCB 0 + #define portSTACK_GROWTH ( 1 ) + #define configUSE_PASSIVE_IDLE_HOOK 0 + #define configUSE_TICKLESS_IDLE 1 + + /* Software timer related configuration options. */ + #define configUSE_TIMERS 1 + #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) + #define configTIMER_QUEUE_LENGTH 20 + #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + + #define configMAX_PRIORITIES ( 7 ) + + /* Run time stats gathering configuration options. */ + unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ + void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ + #define configGENERATE_RUN_TIME_STATS 0 + #define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() + #define portUSING_MPU_WRAPPERS 0 + #define portHAS_STACK_OVERFLOW_CHECKING 0 + #define configENABLE_MPU 0 + + /* Co-routine related configuration options. */ + #define configUSE_CO_ROUTINES 0 + #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + + /* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. */ + #define configUSE_STATS_FORMATTING_FUNCTIONS 1 + + /* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. In most cases the linker will remove unused + * functions anyway. */ + #define INCLUDE_vTaskPrioritySet 1 + #define INCLUDE_uxTaskPriorityGet 1 + #define INCLUDE_vTaskDelete 1 + #define INCLUDE_vTaskCleanUpResources 0 + #define INCLUDE_vTaskSuspend 1 + #define INCLUDE_vTaskDelayUntil 1 + #define INCLUDE_vTaskDelay 1 + #define INCLUDE_uxTaskGetStackHighWaterMark 1 + #define INCLUDE_xTaskGetSchedulerState 1 + #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 + #define INCLUDE_xTaskGetIdleTaskHandle 1 + #define INCLUDE_xTaskGetCurrentTaskHandle 1 + #define INCLUDE_xTaskGetHandle 1 + #define INCLUDE_eTaskGetState 1 + #define INCLUDE_xSemaphoreGetMutexHolder 1 + #define INCLUDE_xTimerPendFunctionCall 1 + #define INCLUDE_xTaskAbortDelay 1 + #define INCLUDE_xTaskGetCurrentTaskHandle 1 + + /* It is a good idea to define configASSERT() while developing. configASSERT() + * uses the same semantics as the standard C assert() macro. */ + #define configASSERT( x ) \ + do \ + { \ + if( x ) \ + { \ + vFakeAssert( true, __FILE__, __LINE__ ); \ + } \ + else \ + { \ + vFakeAssert( false, __FILE__, __LINE__ ); \ + } \ + } while( 0 ) + + #define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 + #if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 ) + extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ); + #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) + #endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */ + + #endif /* FREERTOS_CONFIG_H */ + \ No newline at end of file diff --git a/FreeRTOS/Test/CMock/smp/granular_lock/Makefile b/FreeRTOS/Test/CMock/smp/granular_lock/Makefile index 1480b81cc04..95763734cbb 100644 --- a/FreeRTOS/Test/CMock/smp/granular_lock/Makefile +++ b/FreeRTOS/Test/CMock/smp/granular_lock/Makefile @@ -6,7 +6,7 @@ MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST))) include ../../makefile.in # PROJECT_SRC lists the .c files under test -PROJECT_SRC := tasks.c queue.c stream_buffer.c event_groups.c +PROJECT_SRC := tasks.c queue.c stream_buffer.c event_groups.c timers.c # PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files # Files in PROJECT_DEPS_SRC are excluded from coverage measurements @@ -16,11 +16,12 @@ PROJECT_DEPS_SRC := list.c PROJECT_HEADER_DEPS := FreeRTOS.h # SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c) -SUITE_UT_SRC := granular_lock_utest.c +SUITE_UT_SRC := granular_lock_timers_utest.c # SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases. # Paths are relative to PROJECT_DIR SUITE_SUPPORT_SRC := smp_utest_common.c +SUITE_SUPPORT_SRC += granular_lock_utest_common.c # List the headers used by PROJECT_SRC that you would like to mock MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h diff --git a/FreeRTOS/Test/CMock/smp/granular_lock/granular_lock_timers_utest.c b/FreeRTOS/Test/CMock/smp/granular_lock/granular_lock_timers_utest.c new file mode 100644 index 00000000000..02cb96bfb18 --- /dev/null +++ b/FreeRTOS/Test/CMock/smp/granular_lock/granular_lock_timers_utest.c @@ -0,0 +1,193 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 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. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ +/*! @file granular_lock_timers_utest.c */ + +/* C runtime includes. */ +#include +#include +#include +#include + +/* Task includes */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" +#include "event_groups.h" +#include "queue.h" +#include "semphr.h" +#include "timers.h" + +/* Test includes. */ +#include "unity.h" +#include "unity_memory.h" +#include "../global_vars.h" +//#include "../smp_utest_common.h" +#include "../granular_lock_utest_common.h" + +/* Mock includes. */ +#include "mock_fake_assert.h" +#include "mock_fake_port.h" +#include "mock_portmacro.h" + +/* =========================== EXTERN VARIABLES =========================== */ +extern portSPINLOCK_TYPE xTimerTaskSpinlock; +extern portSPINLOCK_TYPE xTimerISRSpinlock; + +/* ============================ Unity Fixtures ============================ */ + +/*! called before each testcase */ +void setUp( void ) +{ + /* Use the common setup for the testing. */ + granularLocksSetUp(); + + xTimerTaskSpinlock.uxLockCount = 0; + xTimerTaskSpinlock.xOwnerCore = -1; + xTimerISRSpinlock.uxLockCount = 0; + xTimerISRSpinlock.xOwnerCore = -1; + +} + +/*! called after each testcase */ +void tearDown( void ) +{ + granularLocksTearDown(); +} + +/*! called at the beginning of the whole suite */ +void suiteSetUp() +{ +} + +/*! called at the end of the whole suite */ +int suiteTearDown( int numFailures ) +{ + return numFailures; +} + +/* ============================== Test Cases ============================== */ + +void test_granular_locks_timers_critical_section_independence( void ) +{ + granular_locks_critical_section_independence( &xTimerTaskSpinlock, &xTimerISRSpinlock); +} + +void test_granular_locks_timers_mutual_exclusion( void ) +{ + granular_locks_mutual_exclusion( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_critical_section_nesting( void ) +{ + granular_locks_critical_section_nesting( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_deletion( void ) +{ + granular_locks_state_protection_deletion( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_suspension( void ) +{ + granular_locks_state_protection_suspension( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_deletion_suspension( void ) +{ + granular_locks_state_protection_deletion_suspension( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_suspension_deletion( void ) +{ + granular_locks_state_protection_suspension_deletion( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_suspension_resumption_test( void ) //=> Currently fails +{ + granular_locks_state_protection_suspension_resumption_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventList_blocked_deletion_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventList_blocked_deletion_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventList_blocked_suspension_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventList_blocked_suspension_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnUnorderedEventList_blocked_deletion_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_blocked_deletion( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnUnorderedEventList_blocked_suspension_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_blocked_suspension_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventListRestricted_blocked_deletion_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventListRestricted_blocked_deletion_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventListRestricted_blocked_suspension_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventListRestricted_blocked_suspension_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventList_deletion_blocked_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventList_deletion_blocked_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventList_suspension_blocked_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventList_suspension_blocked_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnUnorderedEventList_deletion_blocked_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_deletion_blocked_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnUnorderedEventList_suspension_blocked_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_suspension_blocked_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventListRestricted_deletion_blocked_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventListRestricted_deletion_blocked_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + +void test_granular_locks_timers_state_protection_vTaskPlaceOnEventListRestricted_suspension_blocked_test( void ) +{ + granular_locks_state_protection_vTaskPlaceOnEventListRestricted_suspension_blocked_test( &xTimerTaskSpinlock, &xTimerISRSpinlock ); +} + + diff --git a/FreeRTOS/Test/CMock/smp/granular_lock/granular_lock_utest.c b/FreeRTOS/Test/CMock/smp/granular_lock/granular_lock_utest.c deleted file mode 100644 index 927f6782720..00000000000 --- a/FreeRTOS/Test/CMock/smp/granular_lock/granular_lock_utest.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 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. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ -/*! @file granular_lock_utest.c */ - -/* C runtime includes. */ -#include -#include -#include -#include - -/* Task includes */ -#include "FreeRTOS.h" -#include "FreeRTOSConfig.h" -#include "event_groups.h" -#include "queue.h" -#include "semphr.h" - -/* Test includes. */ -#include "unity.h" -#include "unity_memory.h" -#include "../global_vars.h" -#include "../smp_utest_common.h" - -/* Mock includes. */ -//#include "mock_timers.h" -#include "mock_fake_assert.h" -#include "mock_fake_port.h" -#include "mock_portmacro.h" - -/* =========================== EXTERN VARIABLES =========================== */ -extern portSPINLOCK_TYPE xTaskSpinlock; -extern portSPINLOCK_TYPE xISRSpinlock; - -/* =========================== GLOBAL VARIABLES =========================== */ - -static TaskHandle_t xTaskHandles[ configNUMBER_OF_CORES ] = { NULL }; -uint32_t xPortCriticalNestingCount[ configNUMBER_OF_CORES ] = { 0U }; - -static BaseType_t xCoreYields[ configNUMBER_OF_CORES ] = { 0 }; - -static UBaseType_t xInterruptMaskCount[ configNUMBER_OF_CORES ] = { 0U }; -static BaseType_t xInterruptDisableStatus[ configNUMBER_OF_CORES ] = { 0U }; - -/* ============================ Callback Functions ============================ */ -static void vFakePortInitSpinlock_callback( portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) -{ - TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); - - pxSpinlock->uxLockCount = 0; - pxSpinlock->xOwnerCore = -1; -} - -static void vYieldCores( void ) -{ - BaseType_t i; - BaseType_t xPreviousCoreId = portGET_CORE_ID(); - - if( ( xTaskSpinlock.uxLockCount == 0U ) && ( xISRSpinlock.uxLockCount == 0U ) ) - { - for( i = 0; i < configNUMBER_OF_CORES; i++ ) - { - if( ( xCoreYields[ i ] == pdTRUE ) && - ( xInterruptMaskCount[ i ] == 0 ) && - ( xInterruptDisableStatus[ i ] == pdFALSE ) ) - { - vSetCurrentCore( i ); - xCoreYields[ i ] = pdFALSE; - vTaskSwitchContext( i ); - } - } - - vSetCurrentCore( xPreviousCoreId ); - } -} - -static void vFakePortReleaseSpinlock_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) -{ - TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); - TEST_ASSERT_NOT_EQUAL( -1, pxSpinlock->xOwnerCore ); - TEST_ASSERT_NOT_EQUAL( 0, pxSpinlock->uxLockCount ); - TEST_ASSERT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); - - pxSpinlock->uxLockCount = pxSpinlock->uxLockCount - 1U; - if( pxSpinlock->uxLockCount == 0U ) - { - pxSpinlock->xOwnerCore = -1; - } - - /* Check if and pending core yield. */ - vYieldCores(); -} - -static void vFakePortGetSpinlock_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) -{ - TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); - - if( pxSpinlock->uxLockCount == 0 ) - { - // TEST_ASSERT_EQUAL( -1, pxSpinlock->xOwnerCore ); - pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; - pxSpinlock->xOwnerCore = xCoreID; - } - else - { - TEST_ASSERT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); - pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; - } -} - -static void vFakePortYieldCore_callback( int xCoreID, - int cmock_num_calls ) -{ - BaseType_t xCoreInCritical = pdFALSE; - BaseType_t xPreviousCoreId; - - /* Check if the lock is acquired by any core. */ - if( ( xTaskSpinlock.uxLockCount != 0U ) || ( xISRSpinlock.uxLockCount != 0U ) ) - { - xCoreInCritical = pdTRUE; - } - - if( xCoreInCritical == pdTRUE ) - { - /* If a task is in the critical section, pend the core yield until the - * spinlock is released. */ - xCoreYields[ xCoreID ] = pdTRUE; - } - else - { - /* No task is in the critical section. We can yield this core. */ - xPreviousCoreId = portGET_CORE_ID(); - vSetCurrentCore( xCoreID ); - vTaskSwitchContext( xCoreID ); - vSetCurrentCore( xPreviousCoreId ); - } -} - -static UBaseType_t ulFakePortSetInterruptMaskFromISR_callback( int cmock_num_calls ) -{ - ( void )cmock_num_calls; - xInterruptMaskCount[ portGET_CORE_ID() ]++; - return xInterruptMaskCount[ portGET_CORE_ID() ]; -} - -static void vFakePortClearInterruptMaskFromISR_callback( UBaseType_t uxNewMaskValue, int cmock_num_calls ) -{ - ( void )uxNewMaskValue; - ( void )cmock_num_calls; - TEST_ASSERT_EQUAL( uxNewMaskValue, xInterruptMaskCount[ portGET_CORE_ID() ] ); - TEST_ASSERT_NOT_EQUAL( 0, xInterruptMaskCount[ portGET_CORE_ID() ] ); - xInterruptMaskCount[ portGET_CORE_ID() ]--; - - /* Check if and pending core yield. */ - vYieldCores(); -} - -static UBaseType_t ulFakePortSetInterruptMask_callback( int cmock_num_calls ) -{ - ( void )cmock_num_calls; - xInterruptMaskCount[ portGET_CORE_ID() ]++; - return xInterruptMaskCount[ portGET_CORE_ID() ]; -} - -static void vFakePortClearInterruptMask_callback( UBaseType_t uxNewMaskValue, int cmock_num_calls ) -{ - ( void )uxNewMaskValue; - ( void )cmock_num_calls; - TEST_ASSERT_EQUAL( uxNewMaskValue, xInterruptMaskCount[ portGET_CORE_ID() ] ); - TEST_ASSERT_NOT_EQUAL( 0, xInterruptMaskCount[ portGET_CORE_ID() ] ); - xInterruptMaskCount[ portGET_CORE_ID() ]--; - - /* Check if and pending core yield. */ - vYieldCores(); -} - -static uint32_t vFakePortDisableInterrupts_callback( int cmock_num_calls ) -{ - xInterruptDisableStatus[ portGET_CORE_ID() ] = pdTRUE; - return 0; -} - -static void vFakePortEnableInterrupts_callback( int cmock_num_calls ) -{ - xInterruptDisableStatus[ portGET_CORE_ID() ] = pdFALSE; - - /* Check if and pending core yield. */ - vYieldCores(); -} - -/* ============================ Unity Fixtures ============================ */ - -/*! called before each testcase */ -void setUp( void ) -{ - /* Use the common setup for the testing. */ - commonSetUp(); - /* Specify the granular lock specific implementation. */ - vFakePortInitSpinlock_Stub( vFakePortInitSpinlock_callback ); - vFakePortReleaseSpinlock_Stub( vFakePortReleaseSpinlock_callback ); - vFakePortGetSpinlock_Stub( vFakePortGetSpinlock_callback ); - vFakePortYieldCore_Stub( vFakePortYieldCore_callback ); - - /* Interrupt masks. */ - memset( xInterruptMaskCount, 0, sizeof( UBaseType_t ) * configNUMBER_OF_CORES ); - ulFakePortSetInterruptMaskFromISR_StopIgnore(); - ulFakePortSetInterruptMaskFromISR_Stub( ulFakePortSetInterruptMaskFromISR_callback ); - vFakePortClearInterruptMaskFromISR_StopIgnore(); - vFakePortClearInterruptMaskFromISR_Stub( vFakePortClearInterruptMaskFromISR_callback ); - - ulFakePortSetInterruptMask_StopIgnore(); - ulFakePortSetInterruptMask_Stub( ulFakePortSetInterruptMask_callback ); - vFakePortClearInterruptMask_StopIgnore(); - vFakePortClearInterruptMask_Stub( vFakePortClearInterruptMask_callback ); - - memset( xInterruptDisableStatus, 0, sizeof( BaseType_t ) * configNUMBER_OF_CORES ); - vFakePortDisableInterrupts_StopIgnore(); - vFakePortDisableInterrupts_Stub( vFakePortDisableInterrupts_callback ); - vFakePortEnableInterrupts_StopIgnore(); - vFakePortEnableInterrupts_Stub( vFakePortEnableInterrupts_callback ); -} - -/*! called after each testcase */ -void tearDown( void ) -{ - commonTearDown(); -} - -/*! called at the beginning of the whole suite */ -void suiteSetUp() -{ -} - -/*! called at the end of the whole suite */ -int suiteTearDown( int numFailures ) -{ - return numFailures; -} - -/* ============================== Test Cases ============================== */ - -void test_granular_locks_smoke(void) -{ - uint32_t i; - - /* Create configNUMBER_OF_CORES tasks of equal priority */ - for( i = 0; i < configNUMBER_OF_CORES; i++ ){ - xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandles[ i ] ); - } - - vTaskStartScheduler(); - - /* Verify all configNUMBER_OF_CORES tasks are in the running state */ - for( i = 0; i < configNUMBER_OF_CORES ; i++ ) - { - verifySmpTask( &xTaskHandles[ i ], eRunning, i ); - } -} diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_timer/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/smp/granular_lock_timer/FreeRTOSConfig.h deleted file mode 100644 index 92e610c36cc..00000000000 --- a/FreeRTOS/Test/CMock/smp/granular_lock_timer/FreeRTOSConfig.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 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. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - - #ifndef FREERTOS_CONFIG_H - #define FREERTOS_CONFIG_H - - #include "fake_assert.h" - - /*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See - * https://www.FreeRTOS.org/a00110.html - *----------------------------------------------------------*/ - - /* SMP test specific configuration */ - #define configRUN_MULTIPLE_PRIORITIES 1 - #define configNUMBER_OF_CORES 16 - #define configUSE_CORE_AFFINITY 0 - #define configUSE_TIME_SLICING 0 - #define configUSE_TASK_PREEMPTION_DISABLE 1 - #define configTICK_CORE 0 - - /* OS Configuration */ - #define configUSE_PREEMPTION 1 - #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 - #define configUSE_IDLE_HOOK 0 - #define configUSE_TICK_HOOK 0 - #define configUSE_DAEMON_TASK_STARTUP_HOOK 1 - #define configTICK_RATE_HZ ( 1000 ) - #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) - #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) - #define configMAX_TASK_NAME_LEN ( 12 ) - #define configUSE_TRACE_FACILITY 1 - #define configUSE_16_BIT_TICKS 0 - #define configIDLE_SHOULD_YIELD 1 - #define configUSE_MUTEXES 1 - #define configCHECK_FOR_STACK_OVERFLOW 0 - #define configUSE_RECURSIVE_MUTEXES 1 - #define configQUEUE_REGISTRY_SIZE 20 - #define configUSE_MALLOC_FAILED_HOOK 1 - #define configUSE_APPLICATION_TASK_TAG 1 - #define configUSE_COUNTING_SEMAPHORES 1 - #define configUSE_ALTERNATIVE_API 0 - #define configUSE_QUEUE_SETS 1 - #define configUSE_TASK_NOTIFICATIONS 1 - #define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 - #define configSUPPORT_STATIC_ALLOCATION 0 - #define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) - #define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 - #define portREMOVE_STATIC_QUALIFIER 1 - #define portCRITICAL_NESTING_IN_TCB 0 - #define portSTACK_GROWTH ( 1 ) - #define configUSE_PASSIVE_IDLE_HOOK 0 - #define configUSE_TICKLESS_IDLE 1 - - /* Software timer related configuration options. */ - #define configUSE_TIMERS 1 - #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) - #define configTIMER_QUEUE_LENGTH 20 - #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) - - #define configMAX_PRIORITIES ( 7 ) - - /* Run time stats gathering configuration options. */ - unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ - void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ - #define configGENERATE_RUN_TIME_STATS 0 - #define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() - #define portUSING_MPU_WRAPPERS 0 - #define portHAS_STACK_OVERFLOW_CHECKING 0 - #define configENABLE_MPU 0 - - /* Co-routine related configuration options. */ - #define configUSE_CO_ROUTINES 0 - #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) - - /* This demo makes use of one or more example stats formatting functions. These - * format the raw data provided by the uxTaskGetSystemState() function in to human - * readable ASCII form. See the notes in the implementation of vTaskList() within - * FreeRTOS/Source/tasks.c for limitations. */ - #define configUSE_STATS_FORMATTING_FUNCTIONS 1 - - /* Set the following definitions to 1 to include the API function, or zero - * to exclude the API function. In most cases the linker will remove unused - * functions anyway. */ - #define INCLUDE_vTaskPrioritySet 1 - #define INCLUDE_uxTaskPriorityGet 1 - #define INCLUDE_vTaskDelete 1 - #define INCLUDE_vTaskCleanUpResources 0 - #define INCLUDE_vTaskSuspend 1 - #define INCLUDE_vTaskDelayUntil 1 - #define INCLUDE_vTaskDelay 1 - #define INCLUDE_uxTaskGetStackHighWaterMark 1 - #define INCLUDE_xTaskGetSchedulerState 1 - #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 - #define INCLUDE_xTaskGetIdleTaskHandle 1 - #define INCLUDE_xTaskGetCurrentTaskHandle 1 - #define INCLUDE_xTaskGetHandle 1 - #define INCLUDE_eTaskGetState 1 - #define INCLUDE_xSemaphoreGetMutexHolder 1 - #define INCLUDE_xTimerPendFunctionCall 1 - #define INCLUDE_xTaskAbortDelay 1 - #define INCLUDE_xTaskGetCurrentTaskHandle 1 - - /* It is a good idea to define configASSERT() while developing. configASSERT() - * uses the same semantics as the standard C assert() macro. */ - #define configASSERT( x ) \ - do \ - { \ - if( x ) \ - { \ - vFakeAssert( true, __FILE__, __LINE__ ); \ - } \ - else \ - { \ - vFakeAssert( false, __FILE__, __LINE__ ); \ - } \ - } while( 0 ) - - #define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 - #if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 ) - extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ); - #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) - #endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */ - - #endif /* FREERTOS_CONFIG_H */ - \ No newline at end of file diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_timer/Makefile b/FreeRTOS/Test/CMock/smp/granular_lock_timer/Makefile deleted file mode 100644 index ceb2b9213bb..00000000000 --- a/FreeRTOS/Test/CMock/smp/granular_lock_timer/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# indent with spaces -.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX) - -# Do not move this line below the include -MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST))) -include ../../makefile.in - -# PROJECT_SRC lists the .c files under test -PROJECT_SRC := timers.c - -# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files -# Files in PROJECT_DEPS_SRC are excluded from coverage measurements -PROJECT_DEPS_SRC := list.c tasks.c queue.c - -# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements. -PROJECT_HEADER_DEPS := FreeRTOS.h - -# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c) -SUITE_UT_SRC := granular_lock_timers_utest.c - -# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases. -# Paths are relative to PROJECT_DIR -SUITE_SUPPORT_SRC := smp_utest_common.c - -# List the headers used by PROJECT_SRC that you would like to mock -MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h -MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h -MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -MOCK_FILES_FP += $(UT_ROOT_DIR)//smp/granular_lock/portmacro.h - -# List any addiitonal flags needed by the preprocessor -CPPFLAGS += - -# List any addiitonal flags needed by the compiler -CFLAGS += - -# Try not to edit beyond this line unless necessary. - -# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT) -PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH)/../)))) -SUITE := $(lastword $(subst /, ,$(dir $(MAKEFILE_ABSPATH)))) - -# Make variables available to included makefile -export - -include ../../testdir.mk - - diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_timer/granular_lock.yml b/FreeRTOS/Test/CMock/smp/granular_lock_timer/granular_lock.yml deleted file mode 100644 index e149b08f25f..00000000000 --- a/FreeRTOS/Test/CMock/smp/granular_lock_timer/granular_lock.yml +++ /dev/null @@ -1,32 +0,0 @@ -:cmock: - :mock_prefix: mock_ - :when_no_prototypes: :warn - :when_ptr: :compare_ptr - :treat_externs: :include - :enforce_strict_ordering: TRUE - :plugins: - - :ignore - - :ignore_arg - - :expect_any_args - - :callback - - :return_thru_ptr - :callback_include_count: true # include a count arg when calling the callback - :callback_after_arg_check: false # check arguments before calling the callback - :treat_as: - uint8: HEX8 - uint16: HEX16 - uint32: UINT32 - int8: INT8 - bool: UINT8 - :includes: # This will add these includes to each mock. - - - - "FreeRTOS.h" - :treat_externs: :exclude # Now the extern-ed functions will be mocked. - :weak: __attribute__((weak)) - :verbosity: 3 - :attributes: - - PRIVILEGED_FUNCTION - :strippables: - - PRIVILEGED_FUNCTION - - portDONT_DISCARD - :treat_externs: :include diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_timer/granular_lock_timers_utest.c b/FreeRTOS/Test/CMock/smp/granular_lock_timer/granular_lock_timers_utest.c deleted file mode 100644 index 0327bbb32b7..00000000000 --- a/FreeRTOS/Test/CMock/smp/granular_lock_timer/granular_lock_timers_utest.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 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. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ -/*! @file granular_lock_timers_utest.c */ - -/* C runtime includes. */ -#include -#include -#include -#include - -/* Task includes */ -#include "FreeRTOS.h" -#include "FreeRTOSConfig.h" -#include "event_groups.h" -#include "queue.h" -#include "semphr.h" - -/* Test includes. */ -#include "unity.h" -#include "unity_memory.h" -#include "../global_vars.h" -#include "../smp_utest_common.h" - -/* Mock includes. */ -#include "mock_fake_assert.h" -#include "mock_fake_port.h" -#include "mock_portmacro.h" - -/* =========================== EXTERN VARIABLES =========================== */ -extern portSPINLOCK_TYPE xTaskSpinlock; -extern portSPINLOCK_TYPE xISRSpinlock; - -/* =========================== GLOBAL VARIABLES =========================== */ - -static TaskHandle_t xTaskHandles[ configNUMBER_OF_CORES ] = { NULL }; -uint32_t xPortCriticalNestingCount[ configNUMBER_OF_CORES ] = { 0U }; - -static BaseType_t xCoreYields[ configNUMBER_OF_CORES ] = { 0 }; - -static UBaseType_t xInterruptMaskCount[ configNUMBER_OF_CORES ] = { 0U }; -static BaseType_t xInterruptDisableStatus[ configNUMBER_OF_CORES ] = { 0U }; - -/* ============================ Callback Functions ============================ */ -static void vFakePortInitSpinlock_callback( portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) -{ - TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); - - pxSpinlock->uxLockCount = 0; - pxSpinlock->xOwnerCore = -1; -} - -static void vYieldCores( void ) -{ - BaseType_t i; - BaseType_t xPreviousCoreId = portGET_CORE_ID(); - - if( ( xTaskSpinlock.uxLockCount == 0U ) && ( xISRSpinlock.uxLockCount == 0U ) ) - { - for( i = 0; i < configNUMBER_OF_CORES; i++ ) - { - if( ( xCoreYields[ i ] == pdTRUE ) && - ( xInterruptMaskCount[ i ] == 0 ) && - ( xInterruptDisableStatus[ i ] == pdFALSE ) ) - { - vSetCurrentCore( i ); - xCoreYields[ i ] = pdFALSE; - vTaskSwitchContext( i ); - } - } - - vSetCurrentCore( xPreviousCoreId ); - } -} - -static void vFakePortReleaseSpinlock_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) -{ - TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); - TEST_ASSERT_NOT_EQUAL( -1, pxSpinlock->xOwnerCore ); - TEST_ASSERT_NOT_EQUAL( 0, pxSpinlock->uxLockCount ); - TEST_ASSERT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); - - pxSpinlock->uxLockCount = pxSpinlock->uxLockCount - 1U; - if( pxSpinlock->uxLockCount == 0U ) - { - pxSpinlock->xOwnerCore = -1; - } - - /* Check if and pending core yield. */ - vYieldCores(); -} - -static void vFakePortGetSpinlock_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) -{ - TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); - - if( pxSpinlock->uxLockCount == 0 ) - { - // TEST_ASSERT_EQUAL( -1, pxSpinlock->xOwnerCore ); - pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; - pxSpinlock->xOwnerCore = xCoreID; - } - else - { - TEST_ASSERT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); - pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; - } -} - -static void vFakePortYieldCore_callback( int xCoreID, - int cmock_num_calls ) -{ - BaseType_t xCoreInCritical = pdFALSE; - BaseType_t xPreviousCoreId; - - /* Check if the lock is acquired by any core. */ - if( ( xTaskSpinlock.uxLockCount != 0U ) || ( xISRSpinlock.uxLockCount != 0U ) ) - { - xCoreInCritical = pdTRUE; - } - - if( xCoreInCritical == pdTRUE ) - { - /* If a task is in the critical section, pend the core yield until the - * spinlock is released. */ - xCoreYields[ xCoreID ] = pdTRUE; - } - else - { - /* No task is in the critical section. We can yield this core. */ - xPreviousCoreId = portGET_CORE_ID(); - vSetCurrentCore( xCoreID ); - vTaskSwitchContext( xCoreID ); - vSetCurrentCore( xPreviousCoreId ); - } -} - -static UBaseType_t ulFakePortSetInterruptMaskFromISR_callback( int cmock_num_calls ) -{ - ( void )cmock_num_calls; - xInterruptMaskCount[ portGET_CORE_ID() ]++; - return xInterruptMaskCount[ portGET_CORE_ID() ]; -} - -static void vFakePortClearInterruptMaskFromISR_callback( UBaseType_t uxNewMaskValue, int cmock_num_calls ) -{ - ( void )uxNewMaskValue; - ( void )cmock_num_calls; - TEST_ASSERT_EQUAL( uxNewMaskValue, xInterruptMaskCount[ portGET_CORE_ID() ] ); - TEST_ASSERT_NOT_EQUAL( 0, xInterruptMaskCount[ portGET_CORE_ID() ] ); - xInterruptMaskCount[ portGET_CORE_ID() ]--; - - /* Check if and pending core yield. */ - vYieldCores(); -} - -static UBaseType_t ulFakePortSetInterruptMask_callback( int cmock_num_calls ) -{ - ( void )cmock_num_calls; - xInterruptMaskCount[ portGET_CORE_ID() ]++; - return xInterruptMaskCount[ portGET_CORE_ID() ]; -} - -static void vFakePortClearInterruptMask_callback( UBaseType_t uxNewMaskValue, int cmock_num_calls ) -{ - ( void )uxNewMaskValue; - ( void )cmock_num_calls; - TEST_ASSERT_EQUAL( uxNewMaskValue, xInterruptMaskCount[ portGET_CORE_ID() ] ); - TEST_ASSERT_NOT_EQUAL( 0, xInterruptMaskCount[ portGET_CORE_ID() ] ); - xInterruptMaskCount[ portGET_CORE_ID() ]--; - - /* Check if and pending core yield. */ - vYieldCores(); -} - -static uint32_t vFakePortDisableInterrupts_callback( int cmock_num_calls ) -{ - xInterruptDisableStatus[ portGET_CORE_ID() ] = pdTRUE; - return 0; -} - -static void vFakePortEnableInterrupts_callback( int cmock_num_calls ) -{ - xInterruptDisableStatus[ portGET_CORE_ID() ] = pdFALSE; - - /* Check if and pending core yield. */ - vYieldCores(); -} - -/* ============================ Unity Fixtures ============================ */ - -/*! called before each testcase */ -void setUp( void ) -{ - /* Use the common setup for the testing. */ - commonSetUp(); - - /* Specify the granular lock specific implementation. */ - vFakePortInitSpinlock_Stub( vFakePortInitSpinlock_callback ); - vFakePortReleaseSpinlock_Stub( vFakePortReleaseSpinlock_callback ); - vFakePortGetSpinlock_Stub( vFakePortGetSpinlock_callback ); - vFakePortYieldCore_Stub( vFakePortYieldCore_callback ); - - /* Interrupt masks. */ - memset( xInterruptMaskCount, 0, sizeof( UBaseType_t ) * configNUMBER_OF_CORES ); - ulFakePortSetInterruptMaskFromISR_StopIgnore(); - ulFakePortSetInterruptMaskFromISR_Stub( ulFakePortSetInterruptMaskFromISR_callback ); - vFakePortClearInterruptMaskFromISR_StopIgnore(); - vFakePortClearInterruptMaskFromISR_Stub( vFakePortClearInterruptMaskFromISR_callback ); - - ulFakePortSetInterruptMask_StopIgnore(); - ulFakePortSetInterruptMask_Stub( ulFakePortSetInterruptMask_callback ); - vFakePortClearInterruptMask_StopIgnore(); - vFakePortClearInterruptMask_Stub( vFakePortClearInterruptMask_callback ); - - memset( xInterruptDisableStatus, 0, sizeof( BaseType_t ) * configNUMBER_OF_CORES ); - vFakePortDisableInterrupts_StopIgnore(); - vFakePortDisableInterrupts_Stub( vFakePortDisableInterrupts_callback ); - vFakePortEnableInterrupts_StopIgnore(); - vFakePortEnableInterrupts_Stub( vFakePortEnableInterrupts_callback ); -} - -/*! called after each testcase */ -void tearDown( void ) -{ - commonTearDown(); -} - -/*! called at the beginning of the whole suite */ -void suiteSetUp() -{ -} - -/*! called at the end of the whole suite */ -int suiteTearDown( int numFailures ) -{ - return numFailures; -} - -/* ============================== Test Cases ============================== */ - -void test_granular_locks_timers_smoke(void) -{ - uint32_t i; - - /* Create configNUMBER_OF_CORES - 1 tasks of equal priority */ - for( i = 1; i < configNUMBER_OF_CORES; i++ ){ - xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandles[ i ] ); - } - - vTaskStartScheduler(); - - /* Timer task at core 0 */ - - /* Verify all configNUMBER_OF_CORES tasks are in the running state */ - for( i = 1; i < configNUMBER_OF_CORES ; i++ ) - { - verifySmpTask( &xTaskHandles[ i ], eRunning, i ); - } -} diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_timer/portmacro.h b/FreeRTOS/Test/CMock/smp/granular_lock_timer/portmacro.h deleted file mode 100644 index 10db0b8676f..00000000000 --- a/FreeRTOS/Test/CMock/smp/granular_lock_timer/portmacro.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 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. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Changes from V3.2.3 - * - + Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1. - + - + Changes from V3.2.4 - + - + Removed the use of the %0 parameter within the assembler macros and - + replaced them with hard coded registers. This will ensure the - + assembler does not select the link register as the temp register as - + was occasionally happening previously. - + - + The assembler statements are now included in a single asm block rather - + than each line having its own asm block. - + - + Changes from V4.5.0 - + - + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros - + and replaced them with portYield_FROM_ISR() macro. Application code - + should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT() - + macros as per the V4.5.1 demo code. - */ - -#ifndef PORTMACRO_H -#define PORTMACRO_H - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ - -#include - -/* Type definitions. */ -#define portCHAR char -#define portFLOAT float -#define portDOUBLE double -#define portLONG long -#define portSHORT short -#define portSTACK_TYPE uint32_t -#define portBASE_TYPE long - -typedef portSTACK_TYPE StackType_t; -typedef long BaseType_t; -typedef unsigned long UBaseType_t; - - -#if ( configUSE_16_BIT_TICKS == 1 ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff -#else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL -#endif -#define portPOINTER_SIZE_TYPE uint64_t -/*-----------------------------------------------------------*/ - -/* Requires definition of UBaseType_t */ -#include "fake_port.h" -#include - -/* Hardware specifics. */ -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 8 -#define portNOP() __asm volatile ( "NOP" ) - -/* - * These define the timer to use for generating the tick interrupt. - * They are put in this file so they can be shared between "port.c" - * and "portisr.c". - */ -#define portTIMER_REG_BASE_PTR -#define portTIMER_CLK_ENABLE_BIT -#define portTIMER_AIC_CHANNEL - -/*-----------------------------------------------------------*/ - -/* Task utilities. */ - -/* - * portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR - * and portEXIT_SWITCHING_ISR can only be called from ARM mode, but - * are included here for efficiency. An attempt to call one from - * THUMB mode code will result in a compile time error. - */ - -#define portRESTORE_CONTEXT() -/*-----------------------------------------------------------*/ - -#define portSAVE_CONTEXT() -#define portYIELD() vFakePortYield() -#define portYIELD_WITHIN_API() vFakePortYieldWithinAPI() -#define portYIELD_FROM_ISR() vFakePortYieldFromISR() - -/* Critical section handling. */ -#define portDISABLE_INTERRUPTS() vFakePortDisableInterrupts() -#define portENABLE_INTERRUPTS() vFakePortEnableInterrupts() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) \ - vFakePortClearInterruptMaskFromISR( x ) -#define portSET_INTERRUPT_MASK_FROM_ISR() \ - ulFakePortSetInterruptMaskFromISR() -#define portSET_INTERRUPT_MASK() ulFakePortSetInterruptMask() -#define portCLEAR_INTERRUPT_MASK( x ) vFakePortClearInterruptMask( x ) -#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() \ - vFakePortAssertIfInterruptPriorityInvalid() -#define portENTER_CRITICAL() vFakePortEnterCriticalSection() -#define portEXIT_CRITICAL() vFakePortExitCriticalSection() - -#define portCHECK_IF_IN_ISR() vFakePortCheckIfInISR() -#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) \ - vPortCurrentTaskDying( ( pvTaskToDelete ), ( pxPendYield ) ) -#define portSETUP_TCB( pxTCB ) portSetupTCB_CB( pxTCB ); -#define portASSERT_IF_IN_ISR() vFakePortAssertIfISR(); - -#define portGET_CORE_ID() vFakePortGetCoreID() -#define portYIELD_CORE( x ) vFakePortYieldCore( x ) - -#define portENTER_CRITICAL_FROM_ISR vFakePortEnterCriticalFromISR -#define portEXIT_CRITICAL_FROM_ISR vFakePortExitCriticalFromISR - -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - -/* We need to define it here because CMock does not recognize the - * #if ( portUSING_MPU_WRAPPERS == 1 ) guard around xTaskGetMPUSettings - * and then complains about the missing xMPU_SETTINGS type in the - * generated mocks. */ -typedef struct MPU_SETTINGS -{ - uint32_t ulDummy; -} xMPU_SETTINGS; - -#define portUSING_GRANULAR_LOCKS ( 1 ) - -typedef struct xPortSpinlock -{ - volatile uint32_t uxLockCount; - volatile BaseType_t xOwnerCore; -} xPortSpinlock_t; - -#define portSPINLOCK_TYPE xPortSpinlock_t - -void vFakePortGetSpinlock( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock ); -#define portGET_SPINLOCK vFakePortGetSpinlock - -void vFakePortReleaseSpinlock( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock ); -#define portRELEASE_SPINLOCK vFakePortReleaseSpinlock - -void vFakePortInitSpinlock( portSPINLOCK_TYPE *pxSpinlock ); -#define portINIT_SPINLOCK vFakePortInitSpinlock -#define portINIT_SPINLOCK_STATIC { 0 } - -#define portENTER_CRITICAL_DATA_GROUP vFakePortEnterCriticalDataGroup -#define portEXIT_CRITICAL_DATA_GROUP vFakePortExitCriticalDataGroup -void vFakePortEnterCriticalDataGroup( portSPINLOCK_TYPE *pxTaskSpinLock, portSPINLOCK_TYPE *pxISRSpinLock ); -void vFakePortExitCriticalDataGroup( portSPINLOCK_TYPE *pxTaskSpinLock, portSPINLOCK_TYPE *pxISRSpinLock ); - -extern uint32_t xPortCriticalNestingCount[ configNUMBER_OF_CORES ]; -#define portGET_CRITICAL_NESTING_COUNT( xCoreID ) xPortCriticalNestingCount[ ( xCoreID ) ] -#define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) do{ xPortCriticalNestingCount[ ( xCoreID ) ] = ( x ); } while( 0 ) -#define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) do{ xPortCriticalNestingCount[ ( xCoreID ) ]++; } while( 0 ) -#define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) do{ xPortCriticalNestingCount[ ( xCoreID ) ]--; } while( 0 ) - - -/*-----------------------------------------------------------*/ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ -#endif /* PORTMACRO_H */ diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_utest_common.c b/FreeRTOS/Test/CMock/smp/granular_lock_utest_common.c new file mode 100644 index 00000000000..d5f92df110d --- /dev/null +++ b/FreeRTOS/Test/CMock/smp/granular_lock_utest_common.c @@ -0,0 +1,936 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 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. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ +/*! @file granular_lock_utest_common.c */ + +/* C runtime includes. */ +#include +#include +#include +#include + +/* Task includes */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" +#include "event_groups.h" +#include "queue.h" +#include "semphr.h" + +/* Test includes. */ +#include "unity.h" +#include "unity_memory.h" +#include "../global_vars.h" +#include "smp_utest_common.h" + +/* Mock includes. */ +#include "mock_fake_assert.h" +#include "mock_fake_port.h" +#include "mock_portmacro.h" + +/* =========================== EXTERN VARIABLES =========================== */ +extern portSPINLOCK_TYPE xTaskSpinlock; +extern portSPINLOCK_TYPE xISRSpinlock; + +/* =========================== GLOBAL VARIABLES =========================== */ + +static TaskHandle_t xTaskHandles[ configNUMBER_OF_CORES ] = { NULL }; +uint32_t xPortCriticalNestingCount[ configNUMBER_OF_CORES ] = { 0U }; + +static BaseType_t xCoreYields[ configNUMBER_OF_CORES ] = { 0 }; + +static UBaseType_t xInterruptMaskCount[ configNUMBER_OF_CORES ] = { 0U }; +static BaseType_t xInterruptDisableStatus[ configNUMBER_OF_CORES ] = { 0U }; + +static List_t xTasksWaitingToSend; + +static portSPINLOCK_TYPE xPortTaskSpinlock = portINIT_SPINLOCK_STATIC; +static portSPINLOCK_TYPE xPortISRSpinlock = portINIT_SPINLOCK_STATIC; + +BaseType_t xReturnOnSpin = pdFALSE; + +/* ============================ Callback Functions ============================ */ +static void vFakePortEnterCriticalSection_callback( int cmock_num_calls ) +{ + taskDATA_GROUP_ENTER_CRITICAL( &xPortTaskSpinlock, &xPortISRSpinlock ); +} + +static void vFakePortExitCriticalSection_callback( int cmock_num_calls ) +{ + taskDATA_GROUP_EXIT_CRITICAL( &xPortTaskSpinlock, &xPortISRSpinlock ); +} + +static void vFakePortInitSpinlock_callback( portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) +{ + TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); + + pxSpinlock->uxLockCount = 0; + pxSpinlock->xOwnerCore = -1; +} + +static void vYieldCores( void ) +{ + BaseType_t i; + BaseType_t xPreviousCoreId = portGET_CORE_ID(); + + if( ( xTaskSpinlock.uxLockCount == 0U ) && ( xISRSpinlock.uxLockCount == 0U ) ) + { + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + if( ( xCoreYields[ i ] == pdTRUE ) && + ( xInterruptMaskCount[ i ] == 0 ) && + ( xInterruptDisableStatus[ i ] == pdFALSE ) ) + { + vSetCurrentCore( i ); + xCoreYields[ i ] = pdFALSE; + vTaskSwitchContext( i ); + } + } + + vSetCurrentCore( xPreviousCoreId ); + } +} + +static void vFakePortReleaseSpinlock_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) +{ + TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); + TEST_ASSERT_NOT_EQUAL( 0, pxSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); + + pxSpinlock->uxLockCount = pxSpinlock->uxLockCount - 1U; + if( pxSpinlock->uxLockCount == 0U ) + { + pxSpinlock->xOwnerCore = -1; + } + + /* Check if and pending core yield. */ + vYieldCores(); +} + +static void vFakePortReleaseSpinlock_failure_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) +{ + TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); + TEST_ASSERT_NOT_EQUAL( 0, pxSpinlock->uxLockCount ); + /* Catch failure & do not release lock */ + TEST_ASSERT_NOT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); +} + +static void vFakePortGetSpinlock_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) +{ + TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); + + if( pxSpinlock->uxLockCount == 0 ) + { + pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; + pxSpinlock->xOwnerCore = xCoreID; + } + else + { + TEST_ASSERT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); + pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; + } +} + +static void vFakePortGetSpinlock_failure_callback( BaseType_t xCoreID, portSPINLOCK_TYPE *pxSpinlock, int cmock_num_calls ) +{ + TEST_ASSERT_NOT_EQUAL( NULL, pxSpinlock ); + + if( pxSpinlock->uxLockCount == 0 ) + { + pxSpinlock->uxLockCount = pxSpinlock->uxLockCount + 1U; + pxSpinlock->xOwnerCore = xCoreID; + } + else + { + /* Catch failure and do not increment */ + TEST_ASSERT_NOT_EQUAL( xCoreID, pxSpinlock->xOwnerCore ); + xReturnOnSpin = pdTRUE; + } +} + +static void vFakePortYieldCore_callback( int xCoreID, + int cmock_num_calls ) +{ + BaseType_t xCoreInCritical = pdFALSE; + BaseType_t xPreviousCoreId; + + /* Check if the lock is acquired by any core. */ + if( ( xTaskSpinlock.uxLockCount != 0U ) || ( xISRSpinlock.uxLockCount != 0U ) ) + { + xCoreInCritical = pdTRUE; + } + + if( xCoreInCritical == pdTRUE ) + { + /* If a task is in the critical section, pend the core yield until the + * spinlock is released. */ + xCoreYields[ xCoreID ] = pdTRUE; + } + else + { + /* No task is in the critical section. We can yield this core. */ + xPreviousCoreId = portGET_CORE_ID(); + vSetCurrentCore( xCoreID ); + vTaskSwitchContext( xCoreID ); + vSetCurrentCore( xPreviousCoreId ); + } +} + +static UBaseType_t ulFakePortSetInterruptMaskFromISR_callback( int cmock_num_calls ) +{ + ( void )cmock_num_calls; + xInterruptMaskCount[ portGET_CORE_ID() ]++; + return xInterruptMaskCount[ portGET_CORE_ID() ]; +} + +static void vFakePortClearInterruptMaskFromISR_callback( UBaseType_t uxNewMaskValue, int cmock_num_calls ) +{ + ( void )uxNewMaskValue; + ( void )cmock_num_calls; + TEST_ASSERT_EQUAL( uxNewMaskValue, xInterruptMaskCount[ portGET_CORE_ID() ] ); + TEST_ASSERT_NOT_EQUAL( 0, xInterruptMaskCount[ portGET_CORE_ID() ] ); + xInterruptMaskCount[ portGET_CORE_ID() ]--; + + /* Check if and pending core yield. */ + vYieldCores(); +} + +static UBaseType_t ulFakePortSetInterruptMask_callback( int cmock_num_calls ) +{ + ( void )cmock_num_calls; + xInterruptMaskCount[ portGET_CORE_ID() ]++; + return xInterruptMaskCount[ portGET_CORE_ID() ]; +} + +static void vFakePortClearInterruptMask_callback( UBaseType_t uxNewMaskValue, int cmock_num_calls ) +{ + ( void )uxNewMaskValue; + ( void )cmock_num_calls; + TEST_ASSERT_EQUAL( uxNewMaskValue, xInterruptMaskCount[ portGET_CORE_ID() ] ); + TEST_ASSERT_NOT_EQUAL( 0, xInterruptMaskCount[ portGET_CORE_ID() ] ); + xInterruptMaskCount[ portGET_CORE_ID() ]--; + + /* Check if and pending core yield. */ + vYieldCores(); +} + +static uint32_t vFakePortDisableInterrupts_callback( int cmock_num_calls ) +{ + xInterruptDisableStatus[ portGET_CORE_ID() ] = pdTRUE; + return 0; +} + +static void vFakePortEnableInterrupts_callback( int cmock_num_calls ) +{ + xInterruptDisableStatus[ portGET_CORE_ID() ] = pdFALSE; + + /* Check if and pending core yield. */ + vYieldCores(); +} + +/* ============================ Unity Fixtures ============================ */ + +void granularLocksSetUp( void ) +{ + commonSetUp(); + vListInitialise( &xTasksWaitingToSend ); + + xTaskSpinlock.uxLockCount = 0; + xTaskSpinlock.xOwnerCore = -1; + xISRSpinlock.uxLockCount = 0; + xISRSpinlock.xOwnerCore = -1; + + xReturnOnSpin = pdFALSE; + + uint32_t i; + for ( i = 0; i < configNUMBER_OF_CORES; i++ ){ + xPortCriticalNestingCount[ i ] = 0; + xTaskHandles[ i ] = NULL; + } + + /* Specify the granular lock specific implementation. */ + vFakePortInitSpinlock_Stub( vFakePortInitSpinlock_callback ); + vFakePortReleaseSpinlock_Stub( vFakePortReleaseSpinlock_callback ); + vFakePortGetSpinlock_Stub( vFakePortGetSpinlock_callback ); + vFakePortYieldCore_Stub( vFakePortYieldCore_callback ); + + /* User data group use portENTER/EXIT_CRITICAL now. */ + vFakePortEnterCriticalSection_StubWithCallback( vFakePortEnterCriticalSection_callback ); + vFakePortExitCriticalSection_StubWithCallback( vFakePortExitCriticalSection_callback ); + portINIT_SPINLOCK( &xPortTaskSpinlock ); + portINIT_SPINLOCK( &xPortISRSpinlock ); + + /* Interrupt masks. */ + memset( xInterruptMaskCount, 0, sizeof( UBaseType_t ) * configNUMBER_OF_CORES ); + ulFakePortSetInterruptMaskFromISR_StopIgnore(); + ulFakePortSetInterruptMaskFromISR_Stub( ulFakePortSetInterruptMaskFromISR_callback ); + vFakePortClearInterruptMaskFromISR_StopIgnore(); + vFakePortClearInterruptMaskFromISR_Stub( vFakePortClearInterruptMaskFromISR_callback ); + + ulFakePortSetInterruptMask_StopIgnore(); + ulFakePortSetInterruptMask_Stub( ulFakePortSetInterruptMask_callback ); + vFakePortClearInterruptMask_StopIgnore(); + vFakePortClearInterruptMask_Stub( vFakePortClearInterruptMask_callback ); + + memset( xInterruptDisableStatus, 0, sizeof( BaseType_t ) * configNUMBER_OF_CORES ); + vFakePortDisableInterrupts_StopIgnore(); + vFakePortDisableInterrupts_Stub( vFakePortDisableInterrupts_callback ); + vFakePortEnableInterrupts_StopIgnore(); + vFakePortEnableInterrupts_Stub( vFakePortEnableInterrupts_callback ); +} + +void granularLocksTearDown( void ) +{ + commonTearDown(); +} + +/* ============================== Test Cases ============================== */ + +void granular_locks_critical_section_independence( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + TEST_ASSERT_EQUAL( 1, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 1, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->xOwnerCore ); + + /* Core 1 enters user critical section */ + vSetCurrentCore( 1 ); + taskENTER_CRITICAL(); + + TEST_ASSERT_EQUAL( 1, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 1, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->xOwnerCore ); +} + +void granular_locks_mutual_exclusion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + TEST_ASSERT_EQUAL( 1, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 1, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->xOwnerCore ); + + /* Core 1 attempts to enter timer critical section */ + vSetCurrentCore( 1 ); + vFakePortGetSpinlock_Stub( vFakePortGetSpinlock_failure_callback ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Lock state hasn't changed */ + TEST_ASSERT_EQUAL( 1, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 1, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->xOwnerCore ); +} + +void granular_locks_critical_section_nesting( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + /* Core 0 enters user critical section */ + vSetCurrentCore( 0 ); + taskENTER_CRITICAL(); + + /* Core 0 also enters data group critical section */ + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + TEST_ASSERT_EQUAL( 2, xPortCriticalNestingCount[ 0 ] ); + TEST_ASSERT_EQUAL( 1, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 1, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->xOwnerCore ); + + /* Core 1 attempts to acquire the data group spinlocks */ + vSetCurrentCore( 1 ); + vFakePortGetSpinlock_Stub( vFakePortGetSpinlock_failure_callback ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* The failure callback set the return on spin flag to indicate failure. */ + TEST_ASSERT_EQUAL( pdTRUE, xReturnOnSpin ); + /* The data group lock owner is still core 0. */ + TEST_ASSERT_EQUAL( 1, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 1, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->xOwnerCore ); + + vSetCurrentCore( 0 ); + vFakePortGetSpinlock_Stub( vFakePortGetSpinlock_callback ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + taskEXIT_CRITICAL(); + + TEST_ASSERT_EQUAL( 0, pxDataGroupTaskSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( -1, pxDataGroupTaskSpinlock->xOwnerCore ); + TEST_ASSERT_EQUAL( 0, pxDataGroupISRSpinlock->uxLockCount ); + TEST_ASSERT_EQUAL( -1, pxDataGroupISRSpinlock->xOwnerCore ); +} + +void granular_locks_state_protection_deletion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to delete task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + /* Not Yet Deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now Deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_suspension( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + /* Not Yet Suspended */ + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now Suspended */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} + +void granular_locks_state_protection_deletion_suspension( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to delete & then suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + /* Still running */ + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now Deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_suspension_deletion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend & then delete task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + vTaskDelete( xTaskHandles[ 0 ] ); + + /* Still running */ + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now Deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + + +void granular_locks_state_protection_suspension_resumption_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) //=> Currently fails +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend & then resume task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + vTaskResume( xTaskHandles[ 0 ] ); + + /* Still running on Core 0 */ + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Since we had resumed the task on Core 0 is still running */ + verifySmpTask( &xTaskHandles[ 0 ], eRunning, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventList_blocked_deletion_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + vTaskPlaceOnEventList( &xTasksWaitingToSend, 0); + + /* Core 1 attempts to delete task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + /* Still blocked and run state 1 on Core 0, deletion deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventList_blocked_suspension_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + vSetCurrentCore( 0 ); + vTaskPlaceOnEventList( &xTasksWaitingToSend, 0); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + /* Still blocked and run state 1 on Core 0, suspension deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now suspended */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_blocked_deletion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + vTaskPlaceOnUnorderedEventList( &xTasksWaitingToSend, 0,0); + + /* Core 1 attempts to delete task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + /* Still blocked and run state 1 on Core 0, deletion deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_blocked_suspension_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + vTaskPlaceOnUnorderedEventList( &xTasksWaitingToSend, 0, 0); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + /* Still blocked and run state 1 on Core 0, suspension deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now suspended */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_blocked_deletion_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + vTaskPlaceOnEventListRestricted( &xTasksWaitingToSend, 0, pdFALSE); + + /* Core 1 attempts to delete task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + /* Still blocked and run state 1 on Core 0, deletion deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_blocked_suspension_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + vTaskPlaceOnEventListRestricted( &xTasksWaitingToSend, 0, pdFALSE); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + /* Still blocked and run state 1 on Core 0, suspension deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now suspended */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventList_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + vSetCurrentCore( 0 ); + /* Task running on Core 0 enters blocked state */ + vTaskPlaceOnEventList( &xTasksWaitingToSend, 0); + + /* Still blocked and run state 1 on Core 0, deletion deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventList_suspension_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + vSetCurrentCore( 0 ); + /* Task running on Core 0 enters blocked state */ + vTaskPlaceOnEventList( &xTasksWaitingToSend, 0); + + /* Still blocked and run state 1 on Core 0, suspension deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + vSetCurrentCore( 0 ); + /* Task running on Core 0 enters blocked state */ + vTaskPlaceOnUnorderedEventList( &xTasksWaitingToSend, 0, 0); + + /* Still blocked and run state 1 on Core 0, deletion deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_suspension_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + vSetCurrentCore( 0 ); + /* Task running on Core 0 enters blocked state */ + vTaskPlaceOnUnorderedEventList( &xTasksWaitingToSend, 0, 0); + + /* Still blocked and run state 1 on Core 0, suspension deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskDelete( xTaskHandles[ 0 ] ); + + vSetCurrentCore( 0 ); + /* Task running on Core 0 enters blocked state */ + vTaskPlaceOnEventListRestricted( &xTasksWaitingToSend, 0, pdFALSE); + + /* Still blocked and run state 1 on Core 0, deletion deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eDeleted, -1 ); +} + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_suspension_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ) +{ + xTaskCreate( vSmpTestTask, "Granular Lock Task 1", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 0 ] ); + xTaskCreate( vSmpTestTask, "Granular Lock Task 2", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xTaskHandles[ 1 ] ); + + vTaskStartScheduler(); + + verifySmpTask( &xTaskHandles[ 0 ], eRunning, 0 ); + verifySmpTask( &xTaskHandles[ 1 ], eRunning, 1 ); + + /* Core 0 enters timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_ENTER_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Core 1 attempts to suspend task running on Core 0 */ + vSetCurrentCore( 1 ); + vTaskSuspend( xTaskHandles[ 0 ] ); + + vSetCurrentCore( 0 ); + /* Task running on Core 0 enters blocked state */ + vTaskPlaceOnEventListRestricted( &xTasksWaitingToSend, 0, pdFALSE); + + /* Still blocked and run state 1 on Core 0, suspension deferred */ + verifySmpTask( &xTaskHandles[ 0 ], eBlocked, 0 ); + + /* Core 0 exits timer critical section */ + vSetCurrentCore( 0 ); + taskDATA_GROUP_EXIT_CRITICAL( pxDataGroupTaskSpinlock, pxDataGroupISRSpinlock ); + + /* Now deleted */ + verifySmpTask( &xTaskHandles[ 0 ], eSuspended, -1 ); +} \ No newline at end of file diff --git a/FreeRTOS/Test/CMock/smp/granular_lock_utest_common.h b/FreeRTOS/Test/CMock/smp/granular_lock_utest_common.h new file mode 100644 index 00000000000..7f228b5ca51 --- /dev/null +++ b/FreeRTOS/Test/CMock/smp/granular_lock_utest_common.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 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. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ +/*! @file granular_lock_utest_common.h */ + +#ifndef GRANULAR_LOCK_UTEST_COMMON_H +#define GRANULAR_LOCK_UTEST_COMMON_H + +/* C runtime includes. */ +#include +#include +#include + +/* Test includes. */ +#include "unity.h" +#include "unity_memory.h" + +/* FreeRTOS includes */ +#include "FreeRTOS.h" +#include "task.h" +#include "global_vars.h" + +/* ============================ Unity Fixtures ============================ */ + +void granularLocksSetUp( void ); + +void granularLocksTearDown( void ); + +/* ========================== Helper functions =========================== */ + +/** + * The purpose of this test is to verify that data group critical sections are independent of each other. + * When one core enters timer data group critical section, the other core can enter any other data group + * (user data group in this case) critical section. + */ +void granular_locks_critical_section_independence( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +/** + * The purpose of this test case is to verify that data group critical sections are mutually exclusive. + * When one core enters timer data group critical section, the other cannot enter the same data group + * critical section. + */ +void granular_locks_mutual_exclusion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +/** + * The purpose of this test case is to verify that critical section nesting count is maintained + * correctly for nested critical sections within timer operations. + */ +void granular_locks_critical_section_nesting( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +/** + * The purpose of this test case is to verify that the task's run state is protected when + * it holds a timer data group lock. Operations like deletion/suspend are deferred till the + * lock is held + */ +void granular_locks_state_protection_deletion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_suspension( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_deletion_suspension( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_suspension_deletion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_suspension_resumption_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventList_blocked_deletion_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventList_blocked_suspension_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_blocked_deletion( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_blocked_suspension_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_blocked_deletion_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_blocked_suspension_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventList_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventList_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventList_suspension_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnUnorderedEventList_suspension_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_deletion_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +void granular_locks_state_protection_vTaskPlaceOnEventListRestricted_suspension_blocked_test( portSPINLOCK_TYPE * pxDataGroupTaskSpinlock, portSPINLOCK_TYPE * pxDataGroupISRSpinlock ); + +#endif /* GRANULAR_LOCK_UTEST_COMMON_H */ \ No newline at end of file diff --git a/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/covg_multiple_priorities_no_timeslice_utest.c b/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/covg_multiple_priorities_no_timeslice_utest.c index 57351c4e7ac..132d589b2e3 100644 --- a/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/covg_multiple_priorities_no_timeslice_utest.c +++ b/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/covg_multiple_priorities_no_timeslice_utest.c @@ -206,7 +206,7 @@ void vApplicationGetPassiveIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, /** * @brief vTaskPreemptionEnable - Enable preemption of a task when scheduler is not running. * - * The xPreemptionDisable of the task will be set to pdFALSE. + * The uxPreemptionDisable of the task will be set to pdFALSE. * * Coverage * @code{c} @@ -226,7 +226,7 @@ void test_coverage_vTaskPreemptionEnable_scheduler_not_running( void ) TCB_t xTaskTCB = { NULL }; /* Setup variables. */ - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; /* Clear callback in commonSetUp. */ vFakePortEnterCriticalSection_StubWithCallback( NULL ); @@ -240,13 +240,13 @@ void test_coverage_vTaskPreemptionEnable_scheduler_not_running( void ) vTaskPreemptionEnable( &xTaskTCB ); /* Validation. */ - TEST_ASSERT( xTaskTCB.xPreemptionDisable == pdFALSE ); + TEST_ASSERT( xTaskTCB.uxPreemptionDisable == pdFALSE ); } /** * @brief vTaskPreemptionEnable - Enable preemption of a task when scheduler is running. * - * The xPreemptionDisable of the task will be set to pdFALSE. + * The uxPreemptionDisable of the task will be set to pdFALSE. * * Coverage * @code{c} @@ -267,7 +267,7 @@ void test_coverage_vTaskPreemptionEnable_scheduler_running( void ) TCB_t xTaskTCB = { NULL }; /* Setup variable. */ - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; xTaskTCB.xTaskRunState = -1; /* taskTASK_NOT_RUNNING. */ xSchedulerRunning = pdTRUE; @@ -284,13 +284,13 @@ void test_coverage_vTaskPreemptionEnable_scheduler_running( void ) vTaskPreemptionEnable( &xTaskTCB ); /* Validation. */ - TEST_ASSERT( xTaskTCB.xPreemptionDisable == pdFALSE ); + TEST_ASSERT( xTaskTCB.uxPreemptionDisable == pdFALSE ); } /** * @brief vTaskPreemptionEnable - Enable preemption of a task with NULL handle. * - * The xPreemptionDisable of the task on core 0 will be set to pdFALSE. + * The uxPreemptionDisable of the task on core 0 will be set to pdFALSE. * * Coverage * @code{c} @@ -303,7 +303,7 @@ void test_coverage_vTaskPreemptionEnable_null_handle( void ) TCB_t xTaskTCB = { NULL }; UBaseType_t uxInterruptMask = 0x12345678; - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; xTaskTCB.xTaskRunState = -1; /* taskTASK_NOT_RUNNING. */ pxCurrentTCBs[ 0 ] = &xTaskTCB; @@ -325,13 +325,13 @@ void test_coverage_vTaskPreemptionEnable_null_handle( void ) vTaskPreemptionEnable( NULL ); /* Expection. */ - TEST_ASSERT( pxCurrentTCBs[ 0 ]->xPreemptionDisable == pdFALSE ); + TEST_ASSERT( pxCurrentTCBs[ 0 ]->uxPreemptionDisable == pdFALSE ); } /** * @brief vTaskPreemptionEnable - Enable preemption of a task which is not running. * - * The xPreemptionDisable of the task will be set to pdFALSE. The xTaskRunState is + * The uxPreemptionDisable of the task will be set to pdFALSE. The xTaskRunState is * set to greater than ( configNUMBER_OF_CORES - 1 ). * * Coverage @@ -353,7 +353,7 @@ void test_coverage_vTaskPreemptionEnable_task_not_running_gt_cores( void ) TCB_t xTaskTCB = { NULL }; /* Setup variables. */ - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; xTaskTCB.xTaskRunState = configNUMBER_OF_CORES; xSchedulerRunning = pdTRUE; @@ -370,13 +370,13 @@ void test_coverage_vTaskPreemptionEnable_task_not_running_gt_cores( void ) vTaskPreemptionEnable( &xTaskTCB ); /* Validation. */ - TEST_ASSERT( xTaskTCB.xPreemptionDisable == pdFALSE ); + TEST_ASSERT( xTaskTCB.uxPreemptionDisable == pdFALSE ); } /** * @brief vTaskPreemptionEnable - Enable preemption of a task which is running. * - * The xPreemptionDisable of the task will be set to pdFALSE. + * The uxPreemptionDisable of the task will be set to pdFALSE. * * Coverage * @code{c} @@ -397,7 +397,7 @@ void test_coverage_vTaskPreemptionEnable_task_running( void ) TCB_t xTaskTCB = { NULL }; /* Setup variables. */ - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; xTaskTCB.xTaskRunState = 0; xYieldPendings[ 0 ] = pdTRUE; @@ -418,7 +418,7 @@ void test_coverage_vTaskPreemptionEnable_task_running( void ) vTaskPreemptionEnable( &xTaskTCB ); /* Validation. */ - TEST_ASSERT( xTaskTCB.xPreemptionDisable == pdFALSE ); + TEST_ASSERT( xTaskTCB.uxPreemptionDisable == pdFALSE ); } /** @@ -1495,7 +1495,7 @@ void test_coverage_prvYieldForTask_task_yield_pending( void ) * ( xYieldPendings[ uxCore ] == pdFALSE ) ) * { * #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - * if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + * if( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) * #endif * { * xLowestPriority = xTaskPriority; @@ -1503,7 +1503,7 @@ void test_coverage_prvYieldForTask_task_yield_pending( void ) * } * } * @endcode - * ( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) is false. + * ( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) is false. */ void test_coverage_prvSelectHighestPriorityTask_affinity_preemption_disabled( void ) { @@ -1547,7 +1547,7 @@ void test_coverage_prvSelectHighestPriorityTask_affinity_preemption_disabled( vo xTaskTCBs[ configNUMBER_OF_CORES ].xTaskRunState = 0; /* Task 1 has preemption disabled. */ - xTaskTCBs[ 1 ].xPreemptionDisable = pdTRUE; + xTaskTCBs[ 1 ].uxPreemptionDisable = pdTRUE; /* Setup the affinity mask for TN and TN+1. */ xTaskTCBs[ configNUMBER_OF_CORES ].uxCoreAffinityMask = ( 1 << 0 ) | ( 1 << 1 ); @@ -1588,7 +1588,7 @@ void test_coverage_prvSelectHighestPriorityTask_affinity_preemption_disabled( vo * ( xYieldPendings[ uxCore ] == pdFALSE ) ) * { * #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - * if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + * if( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) * #endif * { * xLowestPriority = xTaskPriority; @@ -1596,7 +1596,7 @@ void test_coverage_prvSelectHighestPriorityTask_affinity_preemption_disabled( vo * } * } * @endcode - * ( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) is true. + * ( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) is true. */ void test_coverage_prvSelectHighestPriorityTask_affinity_preemption_enabled( void ) { @@ -1640,7 +1640,7 @@ void test_coverage_prvSelectHighestPriorityTask_affinity_preemption_enabled( voi xTaskTCBs[ configNUMBER_OF_CORES ].xTaskRunState = 0; /* Task 1 has preemption disabled. */ - xTaskTCBs[ 1 ].xPreemptionDisable = pdFALSE; + xTaskTCBs[ 1 ].uxPreemptionDisable = pdFALSE; /* Setup the affinity mask for TN and TN+1. */ xTaskTCBs[ configNUMBER_OF_CORES ].uxCoreAffinityMask = ( 1 << 0 ) | ( 1 << 1 ); diff --git a/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/multiple_priorities_no_timeslice_utest.c b/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/multiple_priorities_no_timeslice_utest.c index 6d53b059937..d5255c4d74e 100644 --- a/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/multiple_priorities_no_timeslice_utest.c +++ b/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice/multiple_priorities_no_timeslice_utest.c @@ -3340,6 +3340,8 @@ void test_task_priority_inherit_disinherit( void ) /* Create 1 low priority task. */ xTaskCreate( vSmpTestTask, "SMP Task", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandles[ i ] ); + TEST_ASSERT_EQUAL( 1, xTaskHandles[16]->uxPriority ); + TEST_ASSERT_EQUAL( 1, xTaskHandles[16]->uxBasePriority ); /* Start the scheduler. */ vTaskStartScheduler(); diff --git a/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice_mock/covg_multiple_priorities_no_timeslice_mock_utest.c b/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice_mock/covg_multiple_priorities_no_timeslice_mock_utest.c index 341335c8eb4..c04e440cd41 100644 --- a/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice_mock/covg_multiple_priorities_no_timeslice_mock_utest.c +++ b/FreeRTOS/Test/CMock/smp/multiple_priorities_no_timeslice_mock/covg_multiple_priorities_no_timeslice_mock_utest.c @@ -367,9 +367,9 @@ void test_coverage_vTaskPrioritySet_non_running_state( void ) * * Coverage * @code{c} - * if( pxTCB->xPreemptionDisable == pdFALSE ) + * if( pxTCB->uxPreemptionDisable == pdFALSE ) * @endcode - * ( pxTCB->xPreemptionDisable == pdFALSE ) is false. + * ( pxTCB->uxPreemptionDisable == pdFALSE ) is false. */ void test_coverage_vTaskPrioritySet_running_state( void ) { @@ -378,7 +378,7 @@ void test_coverage_vTaskPrioritySet_running_state( void ) /* Setup the variables and structure. */ xTaskTCBs[ 0 ].uxPriority = 4; xTaskTCBs[ 0 ].uxBasePriority = 4; - xTaskTCBs[ 0 ].xPreemptionDisable = pdTRUE; + xTaskTCBs[ 0 ].uxPreemptionDisable = pdTRUE; xTaskTCBs[ 0 ].xTaskRunState = 1; BaseType_t xYieldRequired = pdFALSE; @@ -419,13 +419,14 @@ void test_coverage_prvYieldCore_core_id_ne_current_coreid( void ) { TCB_t task; TCB_t task2; - TaskHandle_t xTaskHandle; + TaskHandle_t xTestTaskHandle; task.xTaskRunState = 1; /* running on core 1 */ - task.xPreemptionDisable = 1; + task.uxPreemptionDisable = 1; + task.uxDeferredStateChange = 0; task2.xTaskRunState = -2; /* running on core 2 taskTASK_YIELDING */ xYieldPendings[ 1 ] = pdTRUE; - xTaskHandle = &task; + xTestTaskHandle = &task; pxCurrentTCBs[ 0 ] = &task; pxCurrentTCBs[ 1 ] = &task; pxCurrentTCBs[ 2 ] = &task2; @@ -440,7 +441,7 @@ void test_coverage_prvYieldCore_core_id_ne_current_coreid( void ) vFakePortExitCriticalSection_Expect(); /* API call */ - vTaskPreemptionEnable( xTaskHandle ); + vTaskPreemptionEnable( xTestTaskHandle ); /* Test Assertions */ TEST_ASSERT_EQUAL( pdFALSE, xYieldPendings[ 2 ] ); @@ -467,7 +468,7 @@ void test_coverage_prvYieldCore_runstate_eq_yielding( void ) TaskHandle_t xTaskHandle; task.xTaskRunState = 1; /* running on core 1 */ - task.xPreemptionDisable = 1; + task.uxPreemptionDisable = 1; task2.xTaskRunState = -2; /* running on core 2 taskTASK_YIELDING */ xTaskHandle = &task; pxCurrentTCBs[ 0 ] = &task; @@ -517,6 +518,7 @@ void test_coverage_vTaskDelete_task_not_running( void ) TaskHandle_t xTaskToDelete; task.xTaskRunState = configNUMBER_OF_CORES + 2; /* running on core 1 */ + task.uxPreemptionDisable = 0; xTaskToDelete = &task; pxCurrentTCBs[ 0 ] = &task; @@ -619,7 +621,7 @@ void test_coverage_vTaskPreemptionDisable_null_handle( void ) vTaskPreemptionDisable( NULL ); /* Test Verifications */ - TEST_ASSERT_EQUAL( pdTRUE, pxCurrentTCBs[ 0 ]->xPreemptionDisable ); + TEST_ASSERT_EQUAL( pdTRUE, pxCurrentTCBs[ 0 ]->uxPreemptionDisable ); } /** diff --git a/FreeRTOS/Test/CMock/smp/multiple_priorities_timeslice/covg_multiple_priorities_timeslice_utest.c b/FreeRTOS/Test/CMock/smp/multiple_priorities_timeslice/covg_multiple_priorities_timeslice_utest.c index 5b6d9878ca2..e6a37888911 100644 --- a/FreeRTOS/Test/CMock/smp/multiple_priorities_timeslice/covg_multiple_priorities_timeslice_utest.c +++ b/FreeRTOS/Test/CMock/smp/multiple_priorities_timeslice/covg_multiple_priorities_timeslice_utest.c @@ -256,7 +256,7 @@ void test_coverage_xTaskIncrementTick_no_eq_priority_task_yield_pending( void ) * for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configNUMBER_OF_CORES; x++ ) * { * #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - * if( pxCurrentTCBs[ x ]->xPreemptionDisable == pdFALSE ) + * if( pxCurrentTCBs[ x ]->uxPreemptionDisable == pdFALSE ) * #endif * { * .... @@ -264,7 +264,7 @@ void test_coverage_xTaskIncrementTick_no_eq_priority_task_yield_pending( void ) * ... * } * @endcode - * ( pxCurrentTCBs[ x ]->xPreemptionDisable == pdFALSE ) is false. + * ( pxCurrentTCBs[ x ]->uxPreemptionDisable == pdFALSE ) is false. */ void test_coverage_xTaskIncrementTick_preemption_disabled_task( void ) { @@ -305,7 +305,7 @@ void test_coverage_xTaskIncrementTick_preemption_disabled_task( void ) xTaskTCB.xTaskRunState = 0; xTaskTCB.xStateListItem.pxContainer = &pxReadyTasksLists[ tskIDLE_PRIORITY ]; xTaskTCB.uxTaskAttributes = 0; - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; listINSERT_END( &pxReadyTasksLists[ tskIDLE_PRIORITY ], &xTaskTCB.xStateListItem ); /* API calls. */ @@ -385,7 +385,7 @@ void test_coverage_xTaskIncrementTick_ready_higher_priority_delayed_task( void ) xTaskTCB.xTaskRunState = 0; xTaskTCB.xStateListItem.pxContainer = pxDelayedTaskList; xTaskTCB.uxTaskAttributes = 0; - xTaskTCB.xPreemptionDisable = pdTRUE; + xTaskTCB.uxPreemptionDisable = pdTRUE; listINSERT_END( pxDelayedTaskList, &xTaskTCB.xStateListItem ); xTaskTCB.xEventListItem.pvOwner = &xTaskTCB; xTaskTCB.xEventListItem.pxContainer = &xEventList; diff --git a/FreeRTOS/Test/CMock/smp/single_priority_timeslice/covg_single_priority_timeslice_utest.c b/FreeRTOS/Test/CMock/smp/single_priority_timeslice/covg_single_priority_timeslice_utest.c index eccab5352a4..59527f9a1d8 100644 --- a/FreeRTOS/Test/CMock/smp/single_priority_timeslice/covg_single_priority_timeslice_utest.c +++ b/FreeRTOS/Test/CMock/smp/single_priority_timeslice/covg_single_priority_timeslice_utest.c @@ -411,7 +411,7 @@ void test_coverage_prvSelectHighestPriorityTask_not_schedule_none_idle_task( voi * ( xYieldPendings[ uxCore ] == pdFALSE ) ) * { * #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - * if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + * if( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) * #endif * { * xLowestPriority = xTaskPriority; @@ -503,7 +503,7 @@ void test_coverage_prvSelectHighestPriorityTask_affinity_task_yielding( void ) * ( xYieldPendings[ uxCore ] == pdFALSE ) ) * { * #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - * if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + * if( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) * #endif * { * xLowestPriority = xTaskPriority; @@ -593,7 +593,7 @@ void test_coverage_prvSelectHighestPriorityTask_affinity_task_state_invalid( voi * ( xYieldPendings[ uxCore ] == pdFALSE ) ) * { * #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - * if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + * if( pxCurrentTCBs[ uxCore ]->uxPreemptionDisable == pdFALSE ) * #endif * { * xLowestPriority = xTaskPriority;