fork
Fork of mbed-rtos by
Diff: rtx/TARGET_CORTEX_A/rt_Mutex.c
- Revision:
- 105:94371fac911d
- Parent:
- 104:07314541bd12
--- a/rtx/TARGET_CORTEX_A/rt_Mutex.c Thu Feb 18 10:00:31 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,267 +0,0 @@ -/*---------------------------------------------------------------------------- - * RL-ARM - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.C - * Purpose: Implements mutex synchronization objects - * Rev.: V4.73 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Mutex.h" -#ifdef __CORTEX_A9 -#include "rt_HAL_CA.h" -#else -#include "rt_HAL_CM.h" -#endif - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mut_init -----------------------------------*/ - -void rt_mut_init (OS_ID mutex) { - /* Initialize a mutex object */ - P_MUCB p_MCB = mutex; - - p_MCB->cb_type = MUCB; - p_MCB->level = 0; - p_MCB->p_lnk = NULL; - p_MCB->owner = NULL; - p_MCB->p_mlnk = NULL; -} - - -/*--------------------------- rt_mut_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_mut_delete (OS_ID mutex) { - /* Delete a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - P_MUCB p_mlnk; - U8 prio; - - __DMB(); - /* Restore owner task's priority. */ - if (p_MCB->level != 0) { - - p_TCB = p_MCB->owner; - - /* Remove mutex from task mutex owner list. */ - p_mlnk = p_TCB->p_mlnk; - if (p_mlnk == p_MCB) { - p_TCB->p_mlnk = p_MCB->p_mlnk; - } - else { - while (p_mlnk) { - if (p_mlnk->p_mlnk == p_MCB) { - p_mlnk->p_mlnk = p_MCB->p_mlnk; - break; - } - p_mlnk = p_mlnk->p_mlnk; - } - } - - /* Restore owner task's priority. */ - prio = p_TCB->prio_base; - p_mlnk = p_TCB->p_mlnk; - while (p_mlnk) { - if (p_mlnk->p_lnk && (p_mlnk->p_lnk->prio > prio)) { - /* A task with higher priority is waiting for mutex. */ - prio = p_mlnk->p_lnk->prio; - } - p_mlnk = p_mlnk->p_mlnk; - } - if (p_TCB->prio != prio) { - p_TCB->prio = prio; - if (p_TCB != os_tsk.run) { - rt_resort_prio (p_TCB); - } - } - - } - - while (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); - rt_ret_val(p_TCB, 0/*osOK*/); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_MCB->cb_type = 0; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_mut_release --------------------------------*/ - -OS_RESULT rt_mut_release (OS_ID mutex) { - /* Release a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - P_MUCB p_mlnk; - U8 prio; - - if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { - /* Unbalanced mutex release or task is not the owner */ - return (OS_R_NOK); - } - __DMB(); - if (--p_MCB->level != 0) { - return (OS_R_OK); - } - - /* Remove mutex from task mutex owner list. */ - p_mlnk = os_tsk.run->p_mlnk; - if (p_mlnk == p_MCB) { - os_tsk.run->p_mlnk = p_MCB->p_mlnk; - } - else { - while (p_mlnk) { - if (p_mlnk->p_mlnk == p_MCB) { - p_mlnk->p_mlnk = p_MCB->p_mlnk; - break; - } - p_mlnk = p_mlnk->p_mlnk; - } - } - - /* Restore owner task's priority. */ - prio = os_tsk.run->prio_base; - p_mlnk = os_tsk.run->p_mlnk; - while (p_mlnk) { - if (p_mlnk->p_lnk && (p_mlnk->p_lnk->prio > prio)) { - /* A task with higher priority is waiting for mutex. */ - prio = p_mlnk->p_lnk->prio; - } - p_mlnk = p_mlnk->p_mlnk; - } - os_tsk.run->prio = prio; - - if (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_MUT); -#endif - rt_rmv_dly (p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB->level = 1; - p_MCB->owner = p_TCB; - p_MCB->p_mlnk = p_TCB->p_mlnk; - p_TCB->p_mlnk = p_MCB; - /* Priority inversion, check which task continues. */ - if (os_tsk.run->prio >= rt_rdy_prio()) { - rt_dispatch (p_TCB); - } - else { - /* Ready task has higher priority than running task. */ - rt_put_prio (&os_rdy, os_tsk.run); - rt_put_prio (&os_rdy, p_TCB); - os_tsk.run->state = READY; - p_TCB->state = READY; - rt_dispatch (NULL); - } - } - else { - /* Check if own priority lowered by priority inversion. */ - if (rt_rdy_prio() > os_tsk.run->prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mut_wait -----------------------------------*/ - -OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { - /* Wait for a mutex, continue when mutex is free. */ - P_MUCB p_MCB = mutex; - - if (p_MCB->level == 0) { - p_MCB->owner = os_tsk.run; - p_MCB->p_mlnk = os_tsk.run->p_mlnk; - os_tsk.run->p_mlnk = p_MCB; - goto inc; - } - if (p_MCB->owner == os_tsk.run) { - /* OK, running task is the owner of this mutex. */ -inc:p_MCB->level++; - __DMB(); - return (OS_R_OK); - } - /* Mutex owned by another task, wait until released. */ - if (timeout == 0) { - return (OS_R_TMO); - } - /* Raise the owner task priority if lower than current priority. */ - /* This priority inversion is called priority inheritance. */ - if (p_MCB->owner->prio < os_tsk.run->prio) { - p_MCB->owner->prio = os_tsk.run->prio; - rt_resort_prio (p_MCB->owner); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - } - rt_block(timeout, WAIT_MUT); - return (OS_R_TMO); -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ -