SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/ksynch.c (Article 6.5) and /sos/ksynch.c (Article 9.5)


001 /* Copyright (C) 2004 David Decotigny             001 /* Copyright (C) 2004 David Decotigny
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007    
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012    
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA. 
017 */                                                017 */
018                                                   018 
019                                                   019 
020 #include <hwcore/irq.h>                           020 #include <hwcore/irq.h>
                                                   >> 021 #include <sos/assert.h>
021                                                   022 
022                                                   023 
023 #include "ksynch.h"                               024 #include "ksynch.h"
024                                                   025 
025                                                   026 
026 sos_ret_t sos_ksema_init(struct sos_ksema *sem    027 sos_ret_t sos_ksema_init(struct sos_ksema *sema, const char *name,
027                          int initial_value)    !! 028                          int initial_value,
                                                   >> 029                          sos_kwaitq_ordering_t ordering)
028 {                                                 030 {
029   sema->value = initial_value;                    031   sema->value = initial_value;
030   return sos_kwaitq_init(& sema->kwaitq, name) !! 032   return sos_kwaitq_init(& sema->kwaitq, name, ordering);
031 }                                                 033 }
032                                                   034 
033                                                   035 
034 sos_ret_t sos_ksema_dispose(struct sos_ksema *    036 sos_ret_t sos_ksema_dispose(struct sos_ksema *sema)
035 {                                                 037 {
036   return sos_kwaitq_dispose(& sema->kwaitq);      038   return sos_kwaitq_dispose(& sema->kwaitq);
037 }                                                 039 }
038                                                   040 
039                                                   041 
040 sos_ret_t sos_ksema_down(struct sos_ksema *sem    042 sos_ret_t sos_ksema_down(struct sos_ksema *sema,
041                          struct sos_time *time    043                          struct sos_time *timeout)
042 {                                                 044 {
043   sos_ui32_t flags;                               045   sos_ui32_t flags;
044   sos_ret_t retval;                               046   sos_ret_t retval;
045                                                   047 
046   sos_disable_IRQs(flags);                        048   sos_disable_IRQs(flags);
047   retval = SOS_OK;                                049   retval = SOS_OK;
048                                                   050 
049   sema->value --;                                 051   sema->value --;
050   if (sema->value < 0)                            052   if (sema->value < 0)
051     {                                             053     {
052       /* Wait for somebody to wake us */          054       /* Wait for somebody to wake us */
053       retval = sos_kwaitq_wait(& sema->kwaitq,    055       retval = sos_kwaitq_wait(& sema->kwaitq, timeout);
054                                                   056 
055       /* Something wrong happened (timeout, ex    057       /* Something wrong happened (timeout, external wakeup, ...) ? */
056       if (SOS_OK != retval)                       058       if (SOS_OK != retval)
057         {                                         059         {
058           /* Yes: pretend we did not ask for t    060           /* Yes: pretend we did not ask for the semaphore */
059           sema->value ++;                         061           sema->value ++;
060         }                                         062         }
061     }                                             063     }
062                                                   064 
063   sos_restore_IRQs(flags);                        065   sos_restore_IRQs(flags);
064   return retval;                                  066   return retval;
065 }                                                 067 }
066                                                   068 
067                                                   069 
068 sos_ret_t sos_ksema_trydown(struct sos_ksema *    070 sos_ret_t sos_ksema_trydown(struct sos_ksema *sema)
069 {                                                 071 {
070   sos_ui32_t flags;                               072   sos_ui32_t flags;
071   sos_ret_t retval;                               073   sos_ret_t retval;
072                                                   074 
073   sos_disable_IRQs(flags);                        075   sos_disable_IRQs(flags);
074                                                   076 
075   /* Can we take the semaphore without blockin    077   /* Can we take the semaphore without blocking ? */
076   if (sema->value >= 1)                           078   if (sema->value >= 1)
077     {                                             079     {
078       /* Yes: we take it now */                   080       /* Yes: we take it now */
079       sema->value --;                             081       sema->value --;      
080       retval = SOS_OK;                            082       retval = SOS_OK;
081     }                                             083     }
082   else                                            084   else
083     {                                             085     {
084       /* No: we signal it */                      086       /* No: we signal it */
085       retval = -SOS_EBUSY;                        087       retval = -SOS_EBUSY;
086     }                                             088     }
087                                                   089 
088   sos_restore_IRQs(flags);                        090   sos_restore_IRQs(flags);
089   return retval;                                  091   return retval;
090 }                                                 092 }
091                                                   093 
092                                                   094 
093 sos_ret_t sos_ksema_up(struct sos_ksema *sema)    095 sos_ret_t sos_ksema_up(struct sos_ksema *sema)
094 {                                                 096 {
095   sos_ui32_t flags;                               097   sos_ui32_t flags;
096   sos_ret_t retval;                               098   sos_ret_t retval;
097                                                   099 
098   sos_disable_IRQs(flags);                        100   sos_disable_IRQs(flags);
099                                                   101 
100   sema->value ++;                                 102   sema->value ++;
101   retval = sos_kwaitq_wakeup(& sema->kwaitq, 1    103   retval = sos_kwaitq_wakeup(& sema->kwaitq, 1, SOS_OK);
102                                                   104 
103   sos_restore_IRQs(flags);                        105   sos_restore_IRQs(flags);
104   return retval;                                  106   return retval;
105 }                                                 107 }
106                                                   108 
107                                                   109 
108 sos_ret_t sos_kmutex_init(struct sos_kmutex *m !! 110 sos_ret_t sos_kmutex_init(struct sos_kmutex *mutex, const char *name,
                                                   >> 111                           sos_kwaitq_ordering_t ordering)
109 {                                                 112 {
110   mutex->owner = NULL;                            113   mutex->owner = NULL;
111   return sos_kwaitq_init(& mutex->kwaitq, name !! 114   return sos_kwaitq_init(& mutex->kwaitq, name, ordering);
112 }                                                 115 }
113                                                   116 
114                                                   117 
115 sos_ret_t sos_kmutex_dispose(struct sos_kmutex    118 sos_ret_t sos_kmutex_dispose(struct sos_kmutex *mutex)
116 {                                                 119 {
117   return sos_kwaitq_dispose(& mutex->kwaitq);     120   return sos_kwaitq_dispose(& mutex->kwaitq);
118 }                                                 121 }
119                                                   122 
120                                                   123 
121 /*                                                124 /*
122  * Implementation based on ownership transfer     125  * Implementation based on ownership transfer (ie no while()
123  * loop). The only assumption is that the thre    126  * loop). The only assumption is that the thread awoken by
124  * kmutex_unlock is not suppressed before effe    127  * kmutex_unlock is not suppressed before effectively waking up: in
125  * that case the mutex will be forever locked     128  * that case the mutex will be forever locked AND unlockable (by
126  * nobody other than the owner, but this is no    129  * nobody other than the owner, but this is not natural since this
127  * owner already issued an unlock()...). The s    130  * owner already issued an unlock()...). The same problem happens with
128  * the semaphores, but in a less obvious manne    131  * the semaphores, but in a less obvious manner.
129  */                                               132  */
130 sos_ret_t sos_kmutex_lock(struct sos_kmutex *m    133 sos_ret_t sos_kmutex_lock(struct sos_kmutex *mutex,
131                           struct sos_time *tim    134                           struct sos_time *timeout)
132 {                                                 135 {
133   __label__ exit_kmutex_lock;                     136   __label__ exit_kmutex_lock;
134   sos_ui32_t flags;                               137   sos_ui32_t flags;
135   sos_ret_t retval;                               138   sos_ret_t retval;
136                                                   139 
137   sos_disable_IRQs(flags);                        140   sos_disable_IRQs(flags);
138   retval = SOS_OK;                                141   retval = SOS_OK;
139                                                   142 
140   /* Mutex already owned ? */                     143   /* Mutex already owned ? */
141   if (NULL != mutex->owner)                       144   if (NULL != mutex->owner)
142     {                                             145     {
143       /* Owned by us or by someone else ? */      146       /* Owned by us or by someone else ? */
144       if (sos_thread_get_current() == mutex->o    147       if (sos_thread_get_current() == mutex->owner)
145         {                                         148         {
146           /* Owned by us: do nothing */           149           /* Owned by us: do nothing */
147           retval = -SOS_EBUSY;                    150           retval = -SOS_EBUSY;
148           goto exit_kmutex_lock;                  151           goto exit_kmutex_lock;
149         }                                         152         }
150                                                   153 
151       /* Wait for somebody to wake us */          154       /* Wait for somebody to wake us */
152       retval = sos_kwaitq_wait(& mutex->kwaitq    155       retval = sos_kwaitq_wait(& mutex->kwaitq, timeout);
153                                                   156 
154       /* Something wrong happened ? */            157       /* Something wrong happened ? */
155       if (SOS_OK != retval)                       158       if (SOS_OK != retval)
156         {                                         159         {
157           goto exit_kmutex_lock;                  160           goto exit_kmutex_lock;
158         }                                         161         }
159     }                                             162     }
160                                                   163 
161   /* Ok, the mutex is available to us: take it    164   /* Ok, the mutex is available to us: take it */
162   mutex->owner = sos_thread_get_current();        165   mutex->owner = sos_thread_get_current();
163                                                   166 
164  exit_kmutex_lock:                                167  exit_kmutex_lock:
165   sos_restore_IRQs(flags);                        168   sos_restore_IRQs(flags);
166   return retval;                                  169   return retval;
167 }                                                 170 }
168                                                   171 
169                                                   172 
                                                   >> 173 sos_bool_t sos_kmutex_owned_by_me(struct sos_kmutex const* mutex)
                                                   >> 174 {
                                                   >> 175   sos_ui32_t flags;
                                                   >> 176   sos_bool_t retval;
                                                   >> 177 
                                                   >> 178   sos_disable_IRQs(flags);
                                                   >> 179   retval = (sos_thread_get_current() == mutex->owner);
                                                   >> 180   sos_restore_IRQs(flags);
                                                   >> 181 
                                                   >> 182   return retval;
                                                   >> 183 }
                                                   >> 184 
                                                   >> 185 
170 sos_ret_t sos_kmutex_trylock(struct sos_kmutex    186 sos_ret_t sos_kmutex_trylock(struct sos_kmutex *mutex)
171 {                                                 187 {
172   sos_ui32_t flags;                               188   sos_ui32_t flags;
173   sos_ret_t retval;                               189   sos_ret_t retval;
174                                                   190 
175   sos_disable_IRQs(flags);                        191   sos_disable_IRQs(flags);
176                                                   192 
177   /* Mutex available to us ? */                   193   /* Mutex available to us ? */
178   if (NULL == mutex->owner)                       194   if (NULL == mutex->owner)
179     {                                             195     {
180       /* Great ! Take it now */                   196       /* Great ! Take it now */
181       mutex->owner = sos_thread_get_current();    197       mutex->owner = sos_thread_get_current();
182                                                   198 
183       retval = SOS_OK;                            199       retval = SOS_OK;
184     }                                             200     }
185   else                                            201   else
186     {                                             202     {
187       /* No: signal it */                         203       /* No: signal it */
188       retval = -SOS_EBUSY;                        204       retval = -SOS_EBUSY;
189     }                                             205     }
190                                                   206 
191   sos_restore_IRQs(flags);                        207   sos_restore_IRQs(flags);
192   return retval;                                  208   return retval;
193 }                                                 209 }
194                                                   210 
195                                                   211 
196 sos_ret_t sos_kmutex_unlock(struct sos_kmutex     212 sos_ret_t sos_kmutex_unlock(struct sos_kmutex *mutex)
197 {                                                 213 {
198   sos_ui32_t flags;                               214   sos_ui32_t flags;
199   sos_ret_t  retval;                              215   sos_ret_t  retval;
200                                                   216 
201   sos_disable_IRQs(flags);                        217   sos_disable_IRQs(flags);
202                                                   218 
203   if (sos_thread_get_current() != mutex->owner    219   if (sos_thread_get_current() != mutex->owner)
204     retval = -SOS_EPERM;                          220     retval = -SOS_EPERM;
205                                                   221 
206   else if (sos_kwaitq_is_empty(& mutex->kwaitq    222   else if (sos_kwaitq_is_empty(& mutex->kwaitq))
207     {                                             223     {
208       /*                                          224       /*
209        * There is NOT ANY thread waiting => we    225        * There is NOT ANY thread waiting => we really mark the mutex
210        * as FREE                                  226        * as FREE
211        */                                         227        */
212       mutex->owner = NULL;                        228       mutex->owner = NULL;
213       retval = SOS_OK;                            229       retval = SOS_OK;
214     }                                             230     }
215   else                                            231   else
216     {                                             232     {
217       /*                                          233       /*
218        * There is at least 1 thread waiting =>    234        * There is at least 1 thread waiting => we DO NOT mark the
219        * mutex as free !                          235        * mutex as free !
220        * Actually, we should have written:        236        * Actually, we should have written:
221        *   mutex->owner = thread_that_is_woken    237        *   mutex->owner = thread_that_is_woken_up;
222        * But the real Id of the next thread ow    238        * But the real Id of the next thread owning the mutex is not
223        * that important. What is important her    239        * that important. What is important here is that mutex->owner
224        * IS NOT NULL. Otherwise there will be  !! 240        * IS NOT NULL and does not correspond to any existing thread
                                                   >> 241        * (address 0x43 is a good candidate because, in SOS, addresses
                                                   >> 242        * below 4kB are never mapped in order to catch invalid
                                                   >> 243        * pointers). Otherwise there will be a possibility for the
225        * thread woken up here to have the mute    244        * thread woken up here to have the mutex stolen by a thread
226        * locking the mutex in the meantime.       245        * locking the mutex in the meantime.
227        */                                         246        */
                                                   >> 247 #define MUTEX_STILL_LOCKED ((struct sos_thread*) 0x43)
                                                   >> 248       mutex->owner = MUTEX_STILL_LOCKED;
                                                   >> 249 
                                                   >> 250       /* We wake up ONE thread ONLY */
228       retval = sos_kwaitq_wakeup(& mutex->kwai    251       retval = sos_kwaitq_wakeup(& mutex->kwaitq, 1, SOS_OK);
229     }                                             252     } 
230                                                   253  
231   sos_restore_IRQs(flags);                        254   sos_restore_IRQs(flags);
232   return retval;                                  255   return retval;
233 }                                                 256 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]