Ethernetwebsoc

Dependencies:   C12832_lcd LM75B WebSocketClient mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rt_Mutex.c Source File

rt_Mutex.c

00001 /*----------------------------------------------------------------------------
00002  *      RL-ARM - RTX
00003  *----------------------------------------------------------------------------
00004  *      Name:    RT_MUTEX.C
00005  *      Purpose: Implements mutex synchronization objects
00006  *      Rev.:    V4.50
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_Config.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 OS_RESULT rt_mut_delete (OS_ID mutex) {
00064   /* Delete a mutex object */
00065   P_MUCB p_MCB = mutex;
00066   P_TCB  p_TCB;
00067 
00068   /* Restore owner task's priority. */
00069   if (p_MCB->level != 0) {
00070     p_MCB->owner->prio = p_MCB->prio;
00071     if (p_MCB->owner != os_tsk.run) {
00072       rt_resort_prio (p_MCB->owner);
00073     }
00074   }
00075 
00076   while (p_MCB->p_lnk != NULL) {
00077     /* A task is waiting for mutex. */
00078     p_TCB = rt_get_first ((P_XCB)p_MCB);
00079     rt_ret_val(p_TCB, 0/*osOK*/);
00080     rt_rmv_dly(p_TCB);
00081     p_TCB->state = READY;
00082     rt_put_prio (&os_rdy, p_TCB);
00083   }
00084 
00085   if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) {
00086     /* preempt running task */
00087     rt_put_prio (&os_rdy, os_tsk.run);
00088     os_tsk.run->state = READY;
00089     rt_dispatch (NULL);
00090   }
00091 
00092   p_MCB->cb_type = 0;
00093 
00094   return (OS_R_OK);
00095 }
00096 
00097 /*--------------------------- rt_mut_release --------------------------------*/
00098 
00099 OS_RESULT rt_mut_release (OS_ID mutex) {
00100   /* Release a mutex object */
00101   P_MUCB p_MCB = mutex;
00102   P_TCB  p_TCB;
00103 
00104   if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) {
00105     /* Unbalanced mutex release or task is not the owner */
00106     return (OS_R_NOK);
00107   }
00108   if (--p_MCB->level != 0) {
00109     return (OS_R_OK);
00110   }
00111   /* Restore owner task's priority. */
00112   os_tsk.run->prio = p_MCB->prio;
00113   if (p_MCB->p_lnk != NULL) {
00114     /* A task is waiting for mutex. */
00115     p_TCB = rt_get_first ((P_XCB)p_MCB);
00116     rt_ret_val(p_TCB, 0/*osOK*/);
00117     rt_rmv_dly (p_TCB);
00118     /* A waiting task becomes the owner of this mutex. */
00119     p_MCB->level     = 1;
00120     p_MCB->owner     = p_TCB;
00121     p_MCB->prio      = p_TCB->prio;
00122     /* Priority inversion, check which task continues. */
00123     if (os_tsk.run->prio >= rt_rdy_prio()) {
00124       rt_dispatch (p_TCB);
00125     }
00126     else {
00127       /* Ready task has higher priority than running task. */
00128       rt_put_prio (&os_rdy, os_tsk.run);
00129       rt_put_prio (&os_rdy, p_TCB);
00130       os_tsk.run->state = READY;
00131       p_TCB->state      = READY;
00132       rt_dispatch (NULL);
00133     }
00134   }
00135   else {
00136     /* Check if own priority raised by priority inversion. */
00137     if (rt_rdy_prio() > os_tsk.run->prio) {
00138       rt_put_prio (&os_rdy, os_tsk.run);
00139       os_tsk.run->state = READY;
00140       rt_dispatch (NULL);
00141     }
00142   }
00143   return (OS_R_OK);
00144 }
00145 
00146 
00147 /*--------------------------- rt_mut_wait -----------------------------------*/
00148 
00149 OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) {
00150   /* Wait for a mutex, continue when mutex is free. */
00151   P_MUCB p_MCB = mutex;
00152 
00153   if (p_MCB->level == 0) {
00154     p_MCB->owner = os_tsk.run;
00155     p_MCB->prio  = os_tsk.run->prio;
00156     goto inc;
00157   }
00158   if (p_MCB->owner == os_tsk.run) {
00159     /* OK, running task is the owner of this mutex. */
00160 inc:p_MCB->level++;
00161     return (OS_R_OK);
00162   }
00163   /* Mutex owned by another task, wait until released. */
00164   if (timeout == 0) {
00165     return (OS_R_TMO);
00166   }
00167   /* Raise the owner task priority if lower than current priority. */
00168   /* This priority inversion is called priority inheritance.       */
00169   if (p_MCB->prio < os_tsk.run->prio) {
00170     p_MCB->owner->prio = os_tsk.run->prio;
00171     rt_resort_prio (p_MCB->owner);
00172   }
00173   if (p_MCB->p_lnk != NULL) {
00174     rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
00175   }
00176   else {
00177     p_MCB->p_lnk = os_tsk.run;
00178     os_tsk.run->p_lnk  = NULL;
00179     os_tsk.run->p_rlnk = (P_TCB)p_MCB;
00180   }
00181   rt_block(timeout, WAIT_MUT);
00182   return (OS_R_TMO);
00183 }
00184 
00185 
00186 /*----------------------------------------------------------------------------
00187  * end of file
00188  *---------------------------------------------------------------------------*/
00189