Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 1 | /* |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 2 | * FreeRTOS Kernel V10.2.1 |
| 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 4 | * |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 6 | * this software and associated documentation files (the "Software"), to deal in |
| 7 | * the Software without restriction, including without limitation the rights to |
| 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| 9 | * the Software, and to permit persons to whom the Software is furnished to do so, |
| 10 | * subject to the following conditions: |
| 11 | * |
| 12 | * The above copyright notice and this permission notice shall be included in all |
| 13 | * copies or substantial portions of the Software. |
| 14 | * |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 21 | * |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 22 | * http://www.FreeRTOS.org |
| 23 | * http://aws.amazon.com/freertos |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 24 | * |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 25 | * 1 tab == 4 spaces! |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 26 | */ |
| 27 | |
| 28 | #include "FreeRTOS.h" |
| 29 | #include "task.h" |
| 30 | #include "croutine.h" |
| 31 | |
| 32 | /* Remove the whole file is co-routines are not being used. */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 33 | #if( configUSE_CO_ROUTINES != 0 ) |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 34 | |
| 35 | /* |
| 36 | * Some kernel aware debuggers require data to be viewed to be global, rather |
| 37 | * than file scope. |
| 38 | */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 39 | #ifdef portREMOVE_STATIC_QUALIFIER |
| 40 | #define static |
| 41 | #endif |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 42 | |
| 43 | |
| 44 | /* Lists for ready and blocked co-routines. --------------------*/ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 45 | static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ |
| 46 | static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ |
| 47 | static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ |
| 48 | static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ |
| 49 | static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ |
| 50 | static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 51 | |
| 52 | /* Other file private variables. --------------------------------*/ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 53 | CRCB_t * pxCurrentCoRoutine = NULL; |
| 54 | static UBaseType_t uxTopCoRoutineReadyPriority = 0; |
| 55 | static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 56 | |
| 57 | /* The initial state of the co-routine when it is created. */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 58 | #define corINITIAL_STATE ( 0 ) |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 59 | |
| 60 | /* |
| 61 | * Place the co-routine represented by pxCRCB into the appropriate ready queue |
| 62 | * for the priority. It is inserted at the end of the list. |
| 63 | * |
| 64 | * This macro accesses the co-routine ready lists and therefore must not be |
| 65 | * used from within an ISR. |
| 66 | */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 67 | #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ |
| 68 | { \ |
| 69 | if ( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ |
| 70 | { \ |
| 71 | uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ |
| 72 | } \ |
| 73 | vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ |
| 74 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 75 | |
| 76 | /* |
| 77 | * Utility to ready all the lists used by the scheduler. This is called |
| 78 | * automatically upon the creation of the first co-routine. |
| 79 | */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 80 | static void prvInitialiseCoRoutineLists( void ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 81 | |
| 82 | /* |
| 83 | * Co-routines that are readied by an interrupt cannot be placed directly into |
| 84 | * the ready lists (there is no mutual exclusion). Instead they are placed in |
| 85 | * in the pending ready list in order that they can later be moved to the ready |
| 86 | * list by the co-routine scheduler. |
| 87 | */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 88 | static void prvCheckPendingReadyList( void ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 89 | |
| 90 | /* |
| 91 | * Macro that looks at the list of co-routines that are currently delayed to |
| 92 | * see if any require waking. |
| 93 | * |
| 94 | * Co-routines are stored in the queue in the order of their wake time - |
| 95 | * meaning once one co-routine has been found whose timer has not expired |
| 96 | * we need not look any further down the list. |
| 97 | */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 98 | static void prvCheckDelayedList( void ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 99 | |
| 100 | /*-----------------------------------------------------------*/ |
| 101 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 102 | BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) |
| 103 | { |
| 104 | BaseType_t xReturn; |
| 105 | CRCB_t *pxCoRoutine; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 106 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 107 | /* Allocate the memory that will store the co-routine control block. */ |
| 108 | pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); |
| 109 | if ( pxCoRoutine ) |
| 110 | { |
| 111 | /* If pxCurrentCoRoutine is NULL then this is the first co-routine to |
| 112 | be created and the co-routine data structures need initialising. */ |
| 113 | if ( pxCurrentCoRoutine == NULL ) |
| 114 | { |
| 115 | pxCurrentCoRoutine = pxCoRoutine; |
| 116 | prvInitialiseCoRoutineLists(); |
| 117 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 118 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 119 | /* Check the priority is within limits. */ |
| 120 | if ( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) |
| 121 | { |
| 122 | uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; |
| 123 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 124 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 125 | /* Fill out the co-routine control block from the function parameters. */ |
| 126 | pxCoRoutine->uxState = corINITIAL_STATE; |
| 127 | pxCoRoutine->uxPriority = uxPriority; |
| 128 | pxCoRoutine->uxIndex = uxIndex; |
| 129 | pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 130 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 131 | /* Initialise all the other co-routine control block parameters. */ |
| 132 | vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); |
| 133 | vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 134 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 135 | /* Set the co-routine control block as a link back from the ListItem_t. |
| 136 | This is so we can get back to the containing CRCB from a generic item |
| 137 | in a list. */ |
| 138 | listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); |
| 139 | listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 140 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 141 | /* Event lists are always in priority order. */ |
| 142 | listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 143 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 144 | /* Now the co-routine has been initialised it can be added to the ready |
| 145 | list at the correct priority. */ |
| 146 | prvAddCoRoutineToReadyQueue( pxCoRoutine ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 147 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 148 | xReturn = pdPASS; |
| 149 | } |
| 150 | else |
| 151 | { |
| 152 | xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; |
| 153 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 154 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 155 | return xReturn; |
| 156 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 157 | /*-----------------------------------------------------------*/ |
| 158 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 159 | void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) |
| 160 | { |
| 161 | TickType_t xTimeToWake; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 162 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 163 | /* Calculate the time to wake - this may overflow but this is |
| 164 | not a problem. */ |
| 165 | xTimeToWake = xCoRoutineTickCount + xTicksToDelay; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 166 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 167 | /* We must remove ourselves from the ready list before adding |
| 168 | ourselves to the blocked list as the same list item is used for |
| 169 | both lists. */ |
| 170 | ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 171 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 172 | /* The list item will be inserted in wake time order. */ |
| 173 | listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 174 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 175 | if ( xTimeToWake < xCoRoutineTickCount ) |
| 176 | { |
| 177 | /* Wake time has overflowed. Place this item in the |
| 178 | overflow list. */ |
| 179 | vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); |
| 180 | } |
| 181 | else |
| 182 | { |
| 183 | /* The wake time has not overflowed, so we can use the |
| 184 | current block list. */ |
| 185 | vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); |
| 186 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 187 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 188 | if ( pxEventList ) |
| 189 | { |
| 190 | /* Also add the co-routine to an event list. If this is done then the |
| 191 | function must be called with interrupts disabled. */ |
| 192 | vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); |
| 193 | } |
| 194 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 195 | /*-----------------------------------------------------------*/ |
| 196 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 197 | static void prvCheckPendingReadyList( void ) |
| 198 | { |
| 199 | /* Are there any co-routines waiting to get moved to the ready list? These |
| 200 | are co-routines that have been readied by an ISR. The ISR cannot access |
| 201 | the ready lists itself. */ |
| 202 | while ( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) |
| 203 | { |
| 204 | CRCB_t *pxUnblockedCRCB; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 205 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 206 | /* The pending ready list can be accessed by an ISR. */ |
| 207 | portDISABLE_INTERRUPTS(); |
| 208 | { |
| 209 | pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); |
| 210 | ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); |
| 211 | } |
| 212 | portENABLE_INTERRUPTS(); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 213 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 214 | ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); |
| 215 | prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); |
| 216 | } |
| 217 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 218 | /*-----------------------------------------------------------*/ |
| 219 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 220 | static void prvCheckDelayedList( void ) |
| 221 | { |
| 222 | CRCB_t *pxCRCB; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 223 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 224 | xPassedTicks = xTaskGetTickCount() - xLastTickCount; |
| 225 | while ( xPassedTicks ) |
| 226 | { |
| 227 | xCoRoutineTickCount++; |
| 228 | xPassedTicks--; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 229 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 230 | /* If the tick count has overflowed we need to swap the ready lists. */ |
| 231 | if ( xCoRoutineTickCount == 0 ) |
| 232 | { |
| 233 | List_t * pxTemp; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 234 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 235 | /* Tick count has overflowed so we need to swap the delay lists. If there are |
| 236 | any items in pxDelayedCoRoutineList here then there is an error! */ |
| 237 | pxTemp = pxDelayedCoRoutineList; |
| 238 | pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; |
| 239 | pxOverflowDelayedCoRoutineList = pxTemp; |
| 240 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 241 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 242 | /* See if this tick has made a timeout expire. */ |
| 243 | while ( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) |
| 244 | { |
| 245 | pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 246 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 247 | if ( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) |
| 248 | { |
| 249 | /* Timeout not yet expired. */ |
| 250 | break; |
| 251 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 252 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 253 | portDISABLE_INTERRUPTS(); |
| 254 | { |
| 255 | /* The event could have occurred just before this critical |
| 256 | section. If this is the case then the generic list item will |
| 257 | have been moved to the pending ready list and the following |
| 258 | line is still valid. Also the pvContainer parameter will have |
| 259 | been set to NULL so the following lines are also valid. */ |
| 260 | ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 261 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 262 | /* Is the co-routine waiting on an event also? */ |
| 263 | if ( pxCRCB->xEventListItem.pxContainer ) |
| 264 | { |
| 265 | ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); |
| 266 | } |
| 267 | } |
| 268 | portENABLE_INTERRUPTS(); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 269 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 270 | prvAddCoRoutineToReadyQueue( pxCRCB ); |
| 271 | } |
| 272 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 273 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 274 | xLastTickCount = xCoRoutineTickCount; |
| 275 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 276 | /*-----------------------------------------------------------*/ |
| 277 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 278 | void vCoRoutineSchedule( void ) |
| 279 | { |
| 280 | /* See if any co-routines readied by events need moving to the ready lists. */ |
| 281 | prvCheckPendingReadyList(); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 282 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 283 | /* See if any delayed co-routines have timed out. */ |
| 284 | prvCheckDelayedList(); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 285 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 286 | /* Find the highest priority queue that contains ready co-routines. */ |
| 287 | while ( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) |
| 288 | { |
| 289 | if ( uxTopCoRoutineReadyPriority == 0 ) |
| 290 | { |
| 291 | /* No more co-routines to check. */ |
| 292 | return; |
| 293 | } |
| 294 | --uxTopCoRoutineReadyPriority; |
| 295 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 296 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 297 | /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines |
| 298 | of the same priority get an equal share of the processor time. */ |
| 299 | listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 300 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 301 | /* Call the co-routine. */ |
| 302 | ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 303 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 304 | return; |
| 305 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 306 | /*-----------------------------------------------------------*/ |
| 307 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 308 | static void prvInitialiseCoRoutineLists( void ) |
| 309 | { |
| 310 | UBaseType_t uxPriority; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 311 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 312 | for ( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) |
| 313 | { |
| 314 | vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); |
| 315 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 316 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 317 | vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); |
| 318 | vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); |
| 319 | vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 320 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 321 | /* Start with pxDelayedCoRoutineList using list1 and the |
| 322 | pxOverflowDelayedCoRoutineList using list2. */ |
| 323 | pxDelayedCoRoutineList = &xDelayedCoRoutineList1; |
| 324 | pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; |
| 325 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 326 | /*-----------------------------------------------------------*/ |
| 327 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 328 | BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) |
| 329 | { |
| 330 | CRCB_t *pxUnblockedCRCB; |
| 331 | BaseType_t xReturn; |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 332 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 333 | /* This function is called from within an interrupt. It can only access |
| 334 | event lists and the pending ready list. This function assumes that a |
| 335 | check has already been made to ensure pxEventList is not empty. */ |
| 336 | pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); |
| 337 | ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); |
| 338 | vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 339 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 340 | if ( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) |
| 341 | { |
| 342 | xReturn = pdTRUE; |
| 343 | } |
| 344 | else |
| 345 | { |
| 346 | xReturn = pdFALSE; |
| 347 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 348 | |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 349 | return xReturn; |
| 350 | } |
Xiaohu.Huang | 2c96ef4 | 2021-10-15 16:12:27 +0800 | [diff] [blame] | 351 | |
| 352 | #endif /* configUSE_CO_ROUTINES == 0 */ |
xiaohu.huang | 4f321fb | 2024-03-22 14:50:29 +0800 | [diff] [blame] | 353 | |