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.
rt_Mutex.c
00001 /** 00002 * @file rt_Mutex.c 00003 * @brief 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "rt_TypeDef.h" 00023 #include "RTX_Config.h" 00024 #include "rt_List.h" 00025 #include "rt_Task.h" 00026 #include "rt_Mutex.h" 00027 00028 00029 /*---------------------------------------------------------------------------- 00030 * Functions 00031 *---------------------------------------------------------------------------*/ 00032 00033 00034 /*--------------------------- rt_mut_init -----------------------------------*/ 00035 00036 void rt_mut_init (OS_ID mutex) { 00037 /* Initialize a mutex object */ 00038 P_MUCB p_MCB = mutex; 00039 00040 p_MCB->cb_type = MUCB; 00041 p_MCB->prio = 0; 00042 p_MCB->level = 0; 00043 p_MCB->p_lnk = NULL; 00044 p_MCB->owner = NULL; 00045 } 00046 00047 00048 /*--------------------------- rt_mut_release --------------------------------*/ 00049 00050 OS_RESULT rt_mut_release (OS_ID mutex) { 00051 /* Release a mutex object */ 00052 P_MUCB p_MCB = mutex; 00053 P_TCB p_TCB; 00054 00055 if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { 00056 /* Unbalanced mutex release or task is not the owner */ 00057 return (OS_R_NOK); 00058 } 00059 if (--p_MCB->level != 0) { 00060 return (OS_R_OK); 00061 } 00062 /* Restore owner task's priority. */ 00063 os_tsk.run->prio = p_MCB->prio; 00064 if (p_MCB->p_lnk != NULL) { 00065 /* A task is waiting for mutex. */ 00066 p_TCB = rt_get_first ((P_XCB)p_MCB); 00067 p_TCB->ret_val = OS_R_MUT; 00068 rt_rmv_dly (p_TCB); 00069 /* A waiting task becomes the owner of this mutex. */ 00070 p_MCB->level = 1; 00071 p_MCB->owner = p_TCB; 00072 p_MCB->prio = p_TCB->prio; 00073 /* Priority inversion, check which task continues. */ 00074 if (os_tsk.run->prio >= rt_rdy_prio()) { 00075 rt_dispatch (p_TCB); 00076 } 00077 else { 00078 /* Ready task has higher priority than running task. */ 00079 rt_put_prio (&os_rdy, os_tsk.run); 00080 rt_put_prio (&os_rdy, p_TCB); 00081 os_tsk.run->state = READY; 00082 p_TCB->state = READY; 00083 rt_dispatch (NULL); 00084 } 00085 os_tsk.run->ret_val = OS_R_OK; 00086 } 00087 else { 00088 /* Check if own priority raised by priority inversion. */ 00089 if (rt_rdy_prio() > os_tsk.run->prio) { 00090 rt_put_prio (&os_rdy, os_tsk.run); 00091 os_tsk.run->state = READY; 00092 rt_dispatch (NULL); 00093 os_tsk.run->ret_val = OS_R_OK; 00094 } 00095 } 00096 return (OS_R_OK); 00097 } 00098 00099 00100 /*--------------------------- rt_mut_wait -----------------------------------*/ 00101 00102 OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { 00103 /* Wait for a mutex, continue when mutex is free. */ 00104 P_MUCB p_MCB = mutex; 00105 00106 if (p_MCB->level == 0) { 00107 p_MCB->owner = os_tsk.run; 00108 p_MCB->prio = os_tsk.run->prio; 00109 goto inc; 00110 } 00111 if (p_MCB->owner == os_tsk.run) { 00112 /* OK, running task is the owner of this mutex. */ 00113 inc:p_MCB->level++; 00114 return (OS_R_OK); 00115 } 00116 /* Mutex owned by another task, wait until released. */ 00117 if (timeout == 0) { 00118 return (OS_R_TMO); 00119 } 00120 /* Raise the owner task priority if lower than current priority. */ 00121 /* This priority inversion is called priority inheritance. */ 00122 if (p_MCB->prio < os_tsk.run->prio) { 00123 p_MCB->owner->prio = os_tsk.run->prio; 00124 rt_resort_prio (p_MCB->owner); 00125 } 00126 if (p_MCB->p_lnk != NULL) { 00127 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00128 } 00129 else { 00130 p_MCB->p_lnk = os_tsk.run; 00131 os_tsk.run->p_lnk = NULL; 00132 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00133 } 00134 rt_block(timeout, WAIT_MUT); 00135 return (OS_R_TMO); 00136 } 00137 00138 00139 /*---------------------------------------------------------------------------- 00140 * end of file 00141 *---------------------------------------------------------------------------*/ 00142
Generated on Tue Jul 12 2022 15:37:22 by
1.7.2