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

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