OpenRTX/rtos/uC-OS3/Source/os_prio.c

184 wiersze
6.7 KiB
C

/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
*
* SPDX-License-Identifier: APACHE-2.0
*
* This software is subject to an open source license and is distributed by
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* PRIORITY MANAGEMENT
*
* File : os_prio.c
* Version : V3.08.00
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#include "os.h"
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_prio__c = "$Id: $";
#endif
/*
************************************************************************************************************************
* INITIALIZE THE PRIORITY LIST
*
* Description: This function is called by uC/OS-III to initialize the list of ready priorities.
*
* Arguments : none
*
* Returns : none
*
* Note : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_PrioInit (void)
{
CPU_DATA i;
/* Clear the bitmap table ... no task is ready */
for (i = 0u; i < OS_PRIO_TBL_SIZE; i++) {
OSPrioTbl[i] = 0u;
}
#if (OS_CFG_TASK_IDLE_EN == 0u)
OS_PrioInsert ((OS_PRIO)(OS_CFG_PRIO_MAX - 1u)); /* Insert what would be the idle task */
#endif
}
/*
************************************************************************************************************************
* GET HIGHEST PRIORITY TASK WAITING
*
* Description: This function is called by other uC/OS-III services to determine the highest priority task
* waiting on the event.
*
* Arguments : none
*
* Returns : The priority of the Highest Priority Task (HPT) waiting for the event
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
OS_PRIO OS_PrioGetHighest (void)
{
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* Optimize for less than word size nbr of priorities */
return ((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[0]));
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* Optimize for 2x the word size nbr of priorities */
if (OSPrioTbl[0] == 0u) {
return ((OS_PRIO)((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[1]) + (CPU_CFG_DATA_SIZE * 8u)));
} else {
return ((OS_PRIO)((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[0])));
}
#else
CPU_DATA *p_tbl;
OS_PRIO prio;
prio = 0u;
p_tbl = &OSPrioTbl[0];
while (*p_tbl == 0u) { /* Search the bitmap table for the highest priority */
prio = (OS_PRIO)(prio + (CPU_CFG_DATA_SIZE * 8u)); /* Compute the step of each CPU_DATA entry */
p_tbl++;
}
prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); /* Find the position of the first bit set at the entry */
return (prio);
#endif
}
/*
************************************************************************************************************************
* INSERT PRIORITY
*
* Description: This function is called to insert a priority in the priority table.
*
* Arguments : prio is the priority to insert
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_PrioInsert (OS_PRIO prio)
{
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* Optimize for less than word size nbr of priorities */
OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* Optimize for 2x the word size nbr of priorities */
if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
} else {
OSPrioTbl[1] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u)));
}
#else
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = (OS_PRIO)(prio / (CPU_CFG_DATA_SIZE * 8u));
bit_nbr = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
OSPrioTbl[ix] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr);
#endif
}
/*
************************************************************************************************************************
* REMOVE PRIORITY
*
* Description: This function is called to remove a priority in the priority table.
*
* Arguments : prio is the priority to remove
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_PrioRemove (OS_PRIO prio)
{
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* Optimize for less than word size nbr of priorities */
OSPrioTbl[0] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio));
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* Optimize for 2x the word size nbr of priorities */
if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
OSPrioTbl[0] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio));
} else {
OSPrioTbl[1] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u))));
}
#else
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = (OS_PRIO)(prio / (CPU_CFG_DATA_SIZE * 8u));
bit_nbr = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
OSPrioTbl[ix] &= ~((CPU_DATA) 1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr));
#endif
}