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/kwaitq.c (Article 9) and /sos/kwaitq.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 #include <sos/klibc.h>                            019 #include <sos/klibc.h>
020 #include <sos/list.h>                             020 #include <sos/list.h>
021 #include <sos/assert.h>                           021 #include <sos/assert.h>
022 #include <hwcore/irq.h>                           022 #include <hwcore/irq.h>
023                                                   023 
024 #include "kwaitq.h"                               024 #include "kwaitq.h"
025                                                   025 
026                                                   026 
027 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *k    027 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *kwq,
028                           const char *name,    !! 028                           const char *name)
029                           sos_kwaitq_ordering_ << 
030 {                                                 029 {
031   memset(kwq, 0x0, sizeof(struct sos_kwaitq));    030   memset(kwq, 0x0, sizeof(struct sos_kwaitq));
032                                                   031 
033 #ifdef SOS_KWQ_DEBUG                              032 #ifdef SOS_KWQ_DEBUG
034   if (! name)                                     033   if (! name)
035     name = "<unknown>";                           034     name = "<unknown>";
036   strzcpy(kwq->name, name, SOS_KWQ_DEBUG_MAX_N    035   strzcpy(kwq->name, name, SOS_KWQ_DEBUG_MAX_NAMELEN);
037 #endif                                            036 #endif
038   kwq->ordering = ordering;                    << 
039   list_init_named(kwq->waiting_list,              037   list_init_named(kwq->waiting_list,
040                   prev_entry_in_kwaitq, next_e    038                   prev_entry_in_kwaitq, next_entry_in_kwaitq);
041                                                   039 
042   return SOS_OK;                                  040   return SOS_OK;
043 }                                                 041 }
044                                                   042 
045                                                   043 
046 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq    044 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq *kwq)
047 {                                                 045 {
048   sos_ui32_t flags;                               046   sos_ui32_t flags;
049   sos_ret_t retval;                               047   sos_ret_t retval;
050                                                   048 
051   sos_disable_IRQs(flags);                        049   sos_disable_IRQs(flags);
052   if (list_is_empty_named(kwq->waiting_list,      050   if (list_is_empty_named(kwq->waiting_list,
053                           prev_entry_in_kwaitq    051                           prev_entry_in_kwaitq, next_entry_in_kwaitq))
054     retval = SOS_OK;                              052     retval = SOS_OK;
055   else                                            053   else
056     retval = -SOS_EBUSY;                          054     retval = -SOS_EBUSY;
057                                                   055 
058   sos_restore_IRQs(flags);                        056   sos_restore_IRQs(flags);
059   return retval;                                  057   return retval;
060 }                                                 058 }
061                                                   059 
062                                                   060 
063 sos_bool_t sos_kwaitq_is_empty(const struct so    061 sos_bool_t sos_kwaitq_is_empty(const struct sos_kwaitq *kwq)
064 {                                                 062 {
065   sos_ui32_t flags;                               063   sos_ui32_t flags;
066   sos_ret_t retval;                               064   sos_ret_t retval;
067                                                   065 
068   sos_disable_IRQs(flags);                        066   sos_disable_IRQs(flags);
069   retval = list_is_empty_named(kwq->waiting_li    067   retval = list_is_empty_named(kwq->waiting_list,
070                                prev_entry_in_k    068                                prev_entry_in_kwaitq, next_entry_in_kwaitq);
071                                                   069 
072   sos_restore_IRQs(flags);                        070   sos_restore_IRQs(flags);
073   return retval;                                  071   return retval;  
074 }                                                 072 }
075                                                   073 
076                                                   074 
077 sos_ret_t sos_kwaitq_init_entry(struct sos_kwa    075 sos_ret_t sos_kwaitq_init_entry(struct sos_kwaitq_entry *kwq_entry)
078 {                                                 076 {
079   memset(kwq_entry, 0x0, sizeof(struct sos_kwa    077   memset(kwq_entry, 0x0, sizeof(struct sos_kwaitq_entry));
080   kwq_entry->thread = sos_thread_get_current()    078   kwq_entry->thread = sos_thread_get_current();
081   return SOS_OK;                                  079   return SOS_OK;
082 }                                                 080 }
083                                                   081 
084                                                   082 
085 /** Internal helper function equivalent to sos    083 /** Internal helper function equivalent to sos_kwaitq_add_entry(), but
086     without interrupt protection scheme */     !! 084     without interrupt protection scheme, and explicit priority
087 inline static sos_ret_t                        !! 085     ordering */
088 _kwaitq_add_entry(struct sos_kwaitq *kwq,      !! 086 inline static sos_ret_t _kwaitq_add_entry(struct sos_kwaitq *kwq,
089                   struct sos_kwaitq_entry *kwq !! 087                                           struct sos_kwaitq_entry *kwq_entry)
090                   sos_sched_priority_t prio)   << 
091 {                                                 088 {
092   struct sos_kwaitq_entry *next_entry = NULL,  << 
093   int nb_entries;                              << 
094                                                << 
095   /* This entry is already added in the kwaitq    089   /* This entry is already added in the kwaitq ! */
096   SOS_ASSERT_FATAL(NULL == kwq_entry->kwaitq);    090   SOS_ASSERT_FATAL(NULL == kwq_entry->kwaitq);
097                                                   091 
098   /* sos_kwaitq_init_entry() has not been call    092   /* sos_kwaitq_init_entry() has not been called ?! */
099   SOS_ASSERT_FATAL(NULL != kwq_entry->thread);    093   SOS_ASSERT_FATAL(NULL != kwq_entry->thread);
100                                                   094 
101   /* (Re-)Initialize wakeup status of the entr    095   /* (Re-)Initialize wakeup status of the entry */
102   kwq_entry->wakeup_triggered = FALSE;            096   kwq_entry->wakeup_triggered = FALSE;
103   kwq_entry->wakeup_status    = SOS_OK;           097   kwq_entry->wakeup_status    = SOS_OK;
104                                                   098 
105   /* Insert this entry in the kwaitq waiting l !! 099   /* Add the thread in the list */
106   switch (kwq->ordering)                       !! 100   list_add_tail_named(kwq->waiting_list, kwq_entry,
107     {                                          !! 101                       prev_entry_in_kwaitq, next_entry_in_kwaitq);
108     case SOS_KWQ_ORDER_FIFO:                   << 
109       /* Insertion in the list in FIFO order * << 
110       {                                        << 
111         /* Add the thread in the list */       << 
112         list_add_tail_named(kwq->waiting_list, << 
113                             prev_entry_in_kwai << 
114       }                                        << 
115       break;                                   << 
116                                                << 
117     case SOS_KWQ_ORDER_PRIO:                   << 
118       /* Priority-driven insertion in the list << 
119       {                                        << 
120         /* Look for the place where to insert  << 
121            want to order them in order of incr << 
122         list_foreach_forward_named(kwq->waitin << 
123                                    prev_entry_ << 
124           {                                    << 
125             /* Does the thread we want to inse << 
126                the given thread in the queue ? << 
127             if (SOS_SCHED_PRIO_CMP(prio,       << 
128                                    sos_thread_ << 
129                 > 0)                           << 
130               {                                << 
131                 /* Yes: we insert before this  << 
132                 next_entry = entry;            << 
133                 break;                         << 
134               }                                << 
135           }                                    << 
136                                                << 
137         /* Actually insert the entry in the li << 
138         if (next_entry != NULL)                << 
139           {                                    << 
140             list_insert_before_named(kwq->wait << 
141                                      prev_entr << 
142                                      next_entr << 
143           }                                    << 
144         else                                   << 
145           {                                    << 
146             /* The thread we want to insert ha << 
147                other in the list */            << 
148             list_add_tail_named(kwq->waiting_l << 
149                                 prev_entry_in_ << 
150           }                                    << 
151       }                                        << 
152       break;                                   << 
153                                                << 
154     default:                                   << 
155       SOS_FATAL_ERROR("Invalid kwq ordering %d << 
156       break;                                   << 
157     }                                          << 
158                                                   102 
159   /* Update the list of waitqueues for the thr    103   /* Update the list of waitqueues for the thread */
160   list_add_tail_named(kwq_entry->thread->kwait    104   list_add_tail_named(kwq_entry->thread->kwaitq_list, kwq_entry,
161                       prev_entry_for_thread, n    105                       prev_entry_for_thread, next_entry_for_thread);
162                                                   106 
163   kwq_entry->kwaitq = kwq;                        107   kwq_entry->kwaitq = kwq;
164                                                !! 108 
165   return SOS_OK;                                  109   return SOS_OK;
166 }                                                 110 }
167                                                   111 
168                                                   112 
169 sos_ret_t sos_kwaitq_add_entry(struct sos_kwai    113 sos_ret_t sos_kwaitq_add_entry(struct sos_kwaitq *kwq,
170                                struct sos_kwai    114                                struct sos_kwaitq_entry *kwq_entry)
171 {                                                 115 {
172   sos_ui32_t flags;                               116   sos_ui32_t flags;
173   sos_ret_t retval;                               117   sos_ret_t retval;
174                                                   118 
175   sos_disable_IRQs(flags);                        119   sos_disable_IRQs(flags);
176   retval = _kwaitq_add_entry(kwq, kwq_entry,   !! 120   retval = _kwaitq_add_entry(kwq, kwq_entry);
177                              sos_thread_get_pr << 
178   sos_restore_IRQs(flags);                        121   sos_restore_IRQs(flags);
179                                                   122 
180   return retval;                                  123   return retval;
181 }                                                 124 }
182                                                   125 
183                                                   126 
184 /** Internal helper function equivalent to sos    127 /** Internal helper function equivalent to sos_kwaitq_remove_entry(),
185     but without interrupt protection scheme */    128     but without interrupt protection scheme */
186 inline static sos_ret_t                           129 inline static sos_ret_t
187 _kwaitq_remove_entry(struct sos_kwaitq *kwq,      130 _kwaitq_remove_entry(struct sos_kwaitq *kwq,
188                      struct sos_kwaitq_entry *    131                      struct sos_kwaitq_entry *kwq_entry)
189 {                                                 132 {
190   SOS_ASSERT_FATAL(kwq_entry->kwaitq == kwq);     133   SOS_ASSERT_FATAL(kwq_entry->kwaitq == kwq);
191                                                   134 
192   list_delete_named(kwq->waiting_list, kwq_ent    135   list_delete_named(kwq->waiting_list, kwq_entry,
193                     prev_entry_in_kwaitq, next    136                     prev_entry_in_kwaitq, next_entry_in_kwaitq);
194                                                   137 
195   list_delete_named(kwq_entry->thread->kwaitq_    138   list_delete_named(kwq_entry->thread->kwaitq_list, kwq_entry,
196                     prev_entry_for_thread, nex    139                     prev_entry_for_thread, next_entry_for_thread);
197                                                   140 
198   kwq_entry->kwaitq = NULL;                       141   kwq_entry->kwaitq = NULL;
199   return SOS_OK;                                  142   return SOS_OK;
200 }                                                 143 }
201                                                   144 
202                                                   145 
203 sos_ret_t sos_kwaitq_remove_entry(struct sos_k    146 sos_ret_t sos_kwaitq_remove_entry(struct sos_kwaitq *kwq,
204                                   struct sos_k    147                                   struct sos_kwaitq_entry *kwq_entry)
205 {                                                 148 {
206   sos_ui32_t flags;                               149   sos_ui32_t flags;
207   sos_ret_t retval;                               150   sos_ret_t retval;
208                                                   151 
209   sos_disable_IRQs(flags);                        152   sos_disable_IRQs(flags);
210   retval = _kwaitq_remove_entry(kwq, kwq_entry    153   retval = _kwaitq_remove_entry(kwq, kwq_entry);
211   sos_restore_IRQs(flags);                        154   sos_restore_IRQs(flags);
212                                                   155 
213   return retval;                                  156   return retval;
214 }                                                 157 }
215                                                   158 
216                                                   159 
217 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *k    160 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *kwq,
218                           struct sos_time *tim    161                           struct sos_time *timeout)
219 {                                                 162 {
220   sos_ui32_t flags;                               163   sos_ui32_t flags;
221   sos_ret_t retval;                               164   sos_ret_t retval;
222   struct sos_kwaitq_entry kwq_entry;              165   struct sos_kwaitq_entry kwq_entry;
223                                                   166 
224   sos_kwaitq_init_entry(& kwq_entry);             167   sos_kwaitq_init_entry(& kwq_entry);
225                                                   168 
226   sos_disable_IRQs(flags);                        169   sos_disable_IRQs(flags);
227                                                   170 
228   retval = _kwaitq_add_entry(kwq, & kwq_entry, !! 171   retval = _kwaitq_add_entry(kwq, & kwq_entry);
229                              sos_thread_get_pr << 
230                                                   172 
231   /* Wait for wakeup or timeout */                173   /* Wait for wakeup or timeout */
232   sos_thread_sleep(timeout);                      174   sos_thread_sleep(timeout);
233   /* Woken up ! */                                175   /* Woken up ! */
234                                                   176 
235   /* Sleep delay elapsed ? */                     177   /* Sleep delay elapsed ? */
236   if (! kwq_entry.wakeup_triggered)               178   if (! kwq_entry.wakeup_triggered)
237     {                                             179     {
238       /* Yes (timeout occured, or wakeup on an    180       /* Yes (timeout occured, or wakeup on another waitqueue): remove
239          the waitq entry by ourselves */          181          the waitq entry by ourselves */
240       _kwaitq_remove_entry(kwq, & kwq_entry);     182       _kwaitq_remove_entry(kwq, & kwq_entry);
241       retval = -SOS_EINTR;                        183       retval = -SOS_EINTR;
242     }                                             184     }
243   else                                            185   else
244     {                                             186     {
245       retval = kwq_entry.wakeup_status;           187       retval = kwq_entry.wakeup_status;
246     }                                             188     }
247                                                   189   
248   sos_restore_IRQs(flags);                        190   sos_restore_IRQs(flags);
249                                                   191 
250   /* We were correctly awoken: position return    192   /* We were correctly awoken: position return status */
251   return retval;                                  193   return retval;
252 }                                                 194 }
253                                                   195 
254                                                   196 
255 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq     197 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq *kwq,
256                             unsigned int nb_th    198                             unsigned int nb_threads,
257                             sos_ret_t wakeup_s    199                             sos_ret_t wakeup_status)
258 {                                                 200 {
259   sos_ui32_t flags;                               201   sos_ui32_t flags;
260                                                   202 
261   sos_disable_IRQs(flags);                        203   sos_disable_IRQs(flags);
262                                                   204 
263   /* Wake up as much threads waiting in waitqu    205   /* Wake up as much threads waiting in waitqueue as possible (up to
264      nb_threads), scanning the list in FIFO/de !! 206      nb_threads), scanning the list in FIFO order */
265      (depends on the kwaitq ordering) */       << 
266   while (! list_is_empty_named(kwq->waiting_li    207   while (! list_is_empty_named(kwq->waiting_list,
267                                prev_entry_in_k    208                                prev_entry_in_kwaitq, next_entry_in_kwaitq))
268     {                                             209     {
269       struct sos_kwaitq_entry *kwq_entry          210       struct sos_kwaitq_entry *kwq_entry
270         = list_get_head_named(kwq->waiting_lis    211         = list_get_head_named(kwq->waiting_list,
271                               prev_entry_in_kw    212                               prev_entry_in_kwaitq, next_entry_in_kwaitq);
272                                                   213 
273       /* Enough threads woken up ? */             214       /* Enough threads woken up ? */
274       if (nb_threads <= 0)                        215       if (nb_threads <= 0)
275         break;                                    216         break;
276                                                   217 
277       /*                                          218       /*
278        * Ok: wake up the thread for this entry    219        * Ok: wake up the thread for this entry
279        */                                         220        */
280                                                   221 
281       /* Thread already woken up ? */             222       /* Thread already woken up ? */
282       if (SOS_THR_RUNNING == sos_thread_get_st    223       if (SOS_THR_RUNNING == sos_thread_get_state(kwq_entry->thread))
283         {                                         224         {
284           /* Yes => Do nothing because WE are     225           /* Yes => Do nothing because WE are that woken-up thread. In
285              particular: don't call set_ready(    226              particular: don't call set_ready() here because this
286              would result in an inconsistent c    227              would result in an inconsistent configuration (currently
287              running thread marked as "waiting    228              running thread marked as "waiting for CPU"...). */
288           continue;                               229           continue;
289         }                                         230         }
290       else                                        231       else
291         {                                         232         {
292           /* No => wake it up now. */             233           /* No => wake it up now. */
293           sos_sched_set_ready(kwq_entry->threa    234           sos_sched_set_ready(kwq_entry->thread);
294         }                                         235         }
295                                                   236 
296       /* Remove this waitq entry */               237       /* Remove this waitq entry */
297       _kwaitq_remove_entry(kwq, kwq_entry);       238       _kwaitq_remove_entry(kwq, kwq_entry);
298       kwq_entry->wakeup_triggered = TRUE;         239       kwq_entry->wakeup_triggered = TRUE;
299       kwq_entry->wakeup_status    = wakeup_sta    240       kwq_entry->wakeup_status    = wakeup_status;
300                                                   241 
301       /* Next iteration... */                     242       /* Next iteration... */
302       nb_threads --;                              243       nb_threads --;
303     }                                             244     }
304                                                   245 
305   sos_restore_IRQs(flags);                        246   sos_restore_IRQs(flags);
306                                                << 
307   return SOS_OK;                               << 
308 }                                              << 
309                                                << 
310                                                << 
311 /* Internal function (callback for thread subs << 
312 sos_ret_t sos_kwaitq_change_priority(struct so << 
313                                      struct so << 
314                                      sos_sched << 
315 {                                              << 
316   /* Reorder the waiting list */               << 
317   _kwaitq_remove_entry(kwq, kwq_entry);        << 
318   _kwaitq_add_entry(kwq, kwq_entry, priority); << 
319                                                   247 
320   return SOS_OK;                                  248   return SOS_OK;
321 }                                                 249 }
                                                      

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