Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-rtos by
rt_Mutex.c
00001 /*---------------------------------------------------------------------------- 00002 * RL-ARM - RTX 00003 *---------------------------------------------------------------------------- 00004 * Name: RT_MUTEX.C 00005 * Purpose: Implements mutex synchronization objects 00006 * Rev.: V4.60 00007 *---------------------------------------------------------------------------- 00008 * 00009 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH 00010 * All rights reserved. 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions are met: 00013 * - Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * - Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * - Neither the name of ARM nor the names of its contributors may be used 00019 * to endorse or promote products derived from this software without 00020 * specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00026 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00027 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00028 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00029 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00030 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *---------------------------------------------------------------------------*/ 00034 00035 #include "rt_TypeDef.h" 00036 #include "RTX_Conf.h" 00037 #include "rt_List.h" 00038 #include "rt_Task.h" 00039 #include "rt_Mutex.h" 00040 #include "rt_HAL_CM.h" 00041 00042 00043 /*---------------------------------------------------------------------------- 00044 * Functions 00045 *---------------------------------------------------------------------------*/ 00046 00047 00048 /*--------------------------- rt_mut_init -----------------------------------*/ 00049 00050 void rt_mut_init (OS_ID mutex) { 00051 /* Initialize a mutex object */ 00052 P_MUCB p_MCB = mutex; 00053 00054 p_MCB->cb_type = MUCB; 00055 p_MCB->prio = 0; 00056 p_MCB->level = 0; 00057 p_MCB->p_lnk = NULL; 00058 p_MCB->owner = NULL; 00059 } 00060 00061 00062 /*--------------------------- rt_mut_delete ---------------------------------*/ 00063 00064 #ifdef __CMSIS_RTOS 00065 OS_RESULT rt_mut_delete (OS_ID mutex) { 00066 /* Delete a mutex object */ 00067 P_MUCB p_MCB = mutex; 00068 P_TCB p_TCB; 00069 00070 /* Restore owner task's priority. */ 00071 if (p_MCB->level != 0) { 00072 p_MCB->owner->prio = p_MCB->prio; 00073 if (p_MCB->owner != os_tsk.run) { 00074 rt_resort_prio (p_MCB->owner); 00075 } 00076 } 00077 00078 while (p_MCB->p_lnk != NULL) { 00079 /* A task is waiting for mutex. */ 00080 p_TCB = rt_get_first ((P_XCB)p_MCB); 00081 rt_ret_val(p_TCB, 0/*osOK*/); 00082 rt_rmv_dly(p_TCB); 00083 p_TCB->state = READY; 00084 rt_put_prio (&os_rdy, p_TCB); 00085 } 00086 00087 if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { 00088 /* preempt running task */ 00089 rt_put_prio (&os_rdy, os_tsk.run); 00090 os_tsk.run->state = READY; 00091 rt_dispatch (NULL); 00092 } 00093 00094 p_MCB->cb_type = 0; 00095 00096 return (OS_R_OK); 00097 } 00098 #endif 00099 00100 00101 /*--------------------------- rt_mut_release --------------------------------*/ 00102 00103 OS_RESULT rt_mut_release (OS_ID mutex) { 00104 /* Release a mutex object */ 00105 P_MUCB p_MCB = mutex; 00106 P_TCB p_TCB; 00107 00108 if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { 00109 /* Unbalanced mutex release or task is not the owner */ 00110 return (OS_R_NOK); 00111 } 00112 if (--p_MCB->level != 0) { 00113 return (OS_R_OK); 00114 } 00115 /* Restore owner task's priority. */ 00116 os_tsk.run->prio = p_MCB->prio; 00117 if (p_MCB->p_lnk != NULL) { 00118 /* A task is waiting for mutex. */ 00119 p_TCB = rt_get_first ((P_XCB)p_MCB); 00120 #ifdef __CMSIS_RTOS 00121 rt_ret_val(p_TCB, 0/*osOK*/); 00122 #else 00123 rt_ret_val(p_TCB, OS_R_MUT); 00124 #endif 00125 rt_rmv_dly (p_TCB); 00126 /* A waiting task becomes the owner of this mutex. */ 00127 p_MCB->level = 1; 00128 p_MCB->owner = p_TCB; 00129 p_MCB->prio = p_TCB->prio; 00130 /* Priority inversion, check which task continues. */ 00131 if (os_tsk.run->prio >= rt_rdy_prio()) { 00132 rt_dispatch (p_TCB); 00133 } 00134 else { 00135 /* Ready task has higher priority than running task. */ 00136 rt_put_prio (&os_rdy, os_tsk.run); 00137 rt_put_prio (&os_rdy, p_TCB); 00138 os_tsk.run->state = READY; 00139 p_TCB->state = READY; 00140 rt_dispatch (NULL); 00141 } 00142 } 00143 else { 00144 /* Check if own priority raised by priority inversion. */ 00145 if (rt_rdy_prio() > os_tsk.run->prio) { 00146 rt_put_prio (&os_rdy, os_tsk.run); 00147 os_tsk.run->state = READY; 00148 rt_dispatch (NULL); 00149 } 00150 } 00151 return (OS_R_OK); 00152 } 00153 00154 00155 /*--------------------------- rt_mut_wait -----------------------------------*/ 00156 00157 OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { 00158 /* Wait for a mutex, continue when mutex is free. */ 00159 P_MUCB p_MCB = mutex; 00160 00161 if (p_MCB->level == 0) { 00162 p_MCB->owner = os_tsk.run; 00163 p_MCB->prio = os_tsk.run->prio; 00164 goto inc; 00165 } 00166 if (p_MCB->owner == os_tsk.run) { 00167 /* OK, running task is the owner of this mutex. */ 00168 inc:p_MCB->level++; 00169 return (OS_R_OK); 00170 } 00171 /* Mutex owned by another task, wait until released. */ 00172 if (timeout == 0) { 00173 return (OS_R_TMO); 00174 } 00175 /* Raise the owner task priority if lower than current priority. */ 00176 /* This priority inversion is called priority inheritance. */ 00177 if (p_MCB->prio < os_tsk.run->prio) { 00178 p_MCB->owner->prio = os_tsk.run->prio; 00179 rt_resort_prio (p_MCB->owner); 00180 } 00181 if (p_MCB->p_lnk != NULL) { 00182 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00183 } 00184 else { 00185 p_MCB->p_lnk = os_tsk.run; 00186 os_tsk.run->p_lnk = NULL; 00187 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00188 } 00189 rt_block(timeout, WAIT_MUT); 00190 return (OS_R_TMO); 00191 } 00192 00193 00194 /*---------------------------------------------------------------------------- 00195 * end of file 00196 *---------------------------------------------------------------------------*/ 00197
Generated on Wed Jul 13 2022 18:32:39 by
