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 7.5) and /sos/ksynch.c (Article 8)


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

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