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.h (Article 7.5) and /sos/kwaitq.h (Article 7)


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 #ifndef _SOS_KWAITQ_H_                            018 #ifndef _SOS_KWAITQ_H_
019 #define _SOS_KWAITQ_H_                            019 #define _SOS_KWAITQ_H_
020                                                   020 
021 #include <sos/errno.h>                            021 #include <sos/errno.h>
022 #include <sos/thread.h>                           022 #include <sos/thread.h>
023 #include <sos/time.h>                             023 #include <sos/time.h>
024                                                   024 
025                                                   025 
026 /**                                               026 /**
027  * @kwaitq.h                                      027  * @kwaitq.h
028  *                                                028  *
029  * Low-level functions to manage queues of thr    029  * Low-level functions to manage queues of threads waiting for a
030  * resource. These functions are public, excep    030  * resource. These functions are public, except
031  * sos_kwaitq_change_priority() that is a call    031  * sos_kwaitq_change_priority() that is a callback for the thread
032  * subsystem. However, for higher-level synchr    032  * subsystem. However, for higher-level synchronization primitives
033  * such as mutex, semaphores, conditions, ...     033  * such as mutex, semaphores, conditions, ... prefer to look at the
034  * corresponding libraries.                       034  * corresponding libraries.
035  */                                               035  */
036                                                   036 
037                                                   037 
038 /**                                               038 /**
039  * Define this if you want to know the names o    039  * Define this if you want to know the names of the kwaitq
040  */                                               040  */
041 // #define SOS_KWQ_DEBUG                          041 // #define SOS_KWQ_DEBUG
042                                                   042 
043                                                   043 
044 /* Forward declaration */                         044 /* Forward declaration */
045 struct sos_kwaitq_entry;                          045 struct sos_kwaitq_entry;
046                                                   046 
047                                                   047 
048 /**                                               048 /**
049  * The threads in the kwaitqs can be ordered i    049  * The threads in the kwaitqs can be ordered in FIFO or in decreasing
050  * priority order.                                050  * priority order.
051  */                                               051  */
052 typedef enum { SOS_KWQ_ORDER_FIFO, SOS_KWQ_ORD    052 typedef enum { SOS_KWQ_ORDER_FIFO, SOS_KWQ_ORDER_PRIO } sos_kwaitq_ordering_t;
053                                                   053 
054                                                   054 
055 #include <sos/sched.h>                            055 #include <sos/sched.h>
056                                                   056 
057                                                   057 
058 /**                                               058 /**
059  * Definition of a waitqueue. In a kwaitq, the    059  * Definition of a waitqueue. In a kwaitq, the threads can be ordererd
060  * either in FIFO order (SOS_KWQ_ORDER_FIFO) o    060  * either in FIFO order (SOS_KWQ_ORDER_FIFO) or in decreasing priority
061  * order (SOS_KWQ_ORDER_PRIO ; with FIFO order    061  * order (SOS_KWQ_ORDER_PRIO ; with FIFO ordering for same-prio
062  * threads).                                      062  * threads).
063  *                                                063  * 
064  * A more efficient method to store the thread    064  * A more efficient method to store the threads ordered by their
065  * priority would have been to use 1 list for     065  * priority would have been to use 1 list for each priority level. But
066  * we have to be careful to the size of a kwai    066  * we have to be careful to the size of a kwaitq structure here:
067  * potentially there are thousands of kwaitq i    067  * potentially there are thousands of kwaitq in a running system
068  * (basically: 1 per opened file !). The algor    068  * (basically: 1 per opened file !). The algorithm we use to order the
069  * threads in the kwaitq in this case is highl    069  * threads in the kwaitq in this case is highly under-optimal (naive
070  * linear insertion): as an exercise, one can     070  * linear insertion): as an exercise, one can implement a more
071  * efficient algorithm (think of a heap).         071  * efficient algorithm (think of a heap).
072  */                                               072  */
073 struct sos_kwaitq                                 073 struct sos_kwaitq
074 {                                                 074 {
075 #ifdef SOS_KWQ_DEBUG                              075 #ifdef SOS_KWQ_DEBUG
076 # define SOS_KWQ_DEBUG_MAX_NAMELEN 32             076 # define SOS_KWQ_DEBUG_MAX_NAMELEN 32
077   char name[SOS_KWQ_DEBUG_MAX_NAMELEN];           077   char name[SOS_KWQ_DEBUG_MAX_NAMELEN];
078 #endif                                            078 #endif
079   sos_kwaitq_ordering_t ordering;                 079   sos_kwaitq_ordering_t ordering;
080   struct sos_kwaitq_entry *waiting_list;          080   struct sos_kwaitq_entry *waiting_list;
081 };                                                081 };
082                                                   082 
083                                                   083 
084 /**                                               084 /**
085  * Definition of an entry for a thread waiting    085  * Definition of an entry for a thread waiting in the waitqueue
086  */                                               086  */
087 struct sos_kwaitq_entry                           087 struct sos_kwaitq_entry
088 {                                                 088 {
089   /** The thread associted with this entry */     089   /** The thread associted with this entry */
090   struct sos_thread *thread;                      090   struct sos_thread *thread;
091                                                   091 
092   /** The kwaitqueue this entry belongs to */     092   /** The kwaitqueue this entry belongs to */
093   struct sos_kwaitq *kwaitq;                      093   struct sos_kwaitq *kwaitq;
094                                                   094 
095   /** TRUE when somebody woke up this entry */    095   /** TRUE when somebody woke up this entry */
096   sos_bool_t wakeup_triggered;                    096   sos_bool_t wakeup_triggered;
097                                                   097 
098   /** The status of wakeup for this entry. @se    098   /** The status of wakeup for this entry. @see wakeup_status argument
099       of sos_kwaitq_wakeup() */                   099       of sos_kwaitq_wakeup() */
100   sos_ret_t wakeup_status;                        100   sos_ret_t wakeup_status;
101                                                   101 
102   /** Other entries in this kwaitqueue */         102   /** Other entries in this kwaitqueue */
103   struct sos_kwaitq_entry *prev_entry_in_kwait    103   struct sos_kwaitq_entry *prev_entry_in_kwaitq, *next_entry_in_kwaitq;
104                                                   104 
105   /** Other entries for the thread */             105   /** Other entries for the thread */
106   struct sos_kwaitq_entry *prev_entry_for_thre    106   struct sos_kwaitq_entry *prev_entry_for_thread, *next_entry_for_thread;  
107 };                                                107 };
108                                                   108 
109                                                   109 
110 /**                                               110 /**
111  * Initialize an empty waitqueue.                 111  * Initialize an empty waitqueue.
112  *                                                112  *
113  * @param name Used only if SOS_KWQ_DEBUG is d    113  * @param name Used only if SOS_KWQ_DEBUG is defined (safe [deep
114  * copied])                                       114  * copied])
115  */                                               115  */
116 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *k    116 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *kwq,
117                           const char *name,       117                           const char *name,
118                           sos_kwaitq_ordering_    118                           sos_kwaitq_ordering_t ordering);
119                                                   119 
120                                                   120 
121 /**                                               121 /**
122  * Release a waitqueue, making sure that no th    122  * Release a waitqueue, making sure that no thread is in it.
123  *                                                123  *
124  * @return -SOS_EBUSY in case a thread is stil    124  * @return -SOS_EBUSY in case a thread is still in the waitqueue.
125  */                                               125  */
126 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq    126 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq *kwq);
127                                                   127 
128                                                   128 
129 /**                                               129 /**
130  * Return whether there are no threads in the     130  * Return whether there are no threads in the waitq
131  */                                               131  */
132 sos_bool_t sos_kwaitq_is_empty(const struct so    132 sos_bool_t sos_kwaitq_is_empty(const struct sos_kwaitq *kwq);
133                                                   133 
134                                                   134 
135 /**                                               135 /**
136  * Initialize a waitqueue entry. Mainly consis    136  * Initialize a waitqueue entry. Mainly consists in updating the
137  * "thread" field of the entry (set to current    137  * "thread" field of the entry (set to current running thread), and
138  * initializing the remaining of the entry as     138  * initializing the remaining of the entry as to indicate it does not
139  * belong to any waitq.                           139  * belong to any waitq.
140  */                                               140  */
141 sos_ret_t sos_kwaitq_init_entry(struct sos_kwa    141 sos_ret_t sos_kwaitq_init_entry(struct sos_kwaitq_entry *kwq_entry);
142                                                   142 
143                                                   143 
144 /**                                               144 /**
145  * Add an entry (previously initialized with s    145  * Add an entry (previously initialized with sos_kwaitq_init_entry())
146  * in the given waitqueue.                        146  * in the given waitqueue.
147  *                                                147  *
148  * @note: No state change/context switch can o    148  * @note: No state change/context switch can occur here ! Among other
149  * things: the current executing thread is not    149  * things: the current executing thread is not preempted.
150  */                                               150  */
151 sos_ret_t sos_kwaitq_add_entry(struct sos_kwai    151 sos_ret_t sos_kwaitq_add_entry(struct sos_kwaitq *kwq,
152                                struct sos_kwai    152                                struct sos_kwaitq_entry *kwq_entry);
153                                                   153 
154                                                   154 
155 /**                                               155 /**
156  * Remove the given kwaitq_entry from the kwai    156  * Remove the given kwaitq_entry from the kwaitq.
157  *                                                157  *
158  * @note: No state change/context switch can o    158  * @note: No state change/context switch can occur here ! Among other
159  * things: the thread associated with the entr    159  * things: the thread associated with the entry is not necessarilly
160  * the same as the one currently running, and     160  * the same as the one currently running, and does not preempt the
161  * current running thread if they are differen    161  * current running thread if they are different.
162  */                                               162  */
163 sos_ret_t sos_kwaitq_remove_entry(struct sos_k    163 sos_ret_t sos_kwaitq_remove_entry(struct sos_kwaitq *kwq,
164                                   struct sos_k    164                                   struct sos_kwaitq_entry *kwq_entry);
165                                                   165 
166                                                   166 
167 /**                                               167 /**
168  * Helper function to make the current running    168  * Helper function to make the current running thread block in the
169  * given kwaitq, waiting to be woken up by som    169  * given kwaitq, waiting to be woken up by somedy else or by the given
170  * timeout. It calls the sos_kwaitq_add_entry(    170  * timeout. It calls the sos_kwaitq_add_entry() and
171  * sos_kwaitq_remove_entry().                     171  * sos_kwaitq_remove_entry().
172  *                                                172  *
173  * @param timeout The desired timeout (can be     173  * @param timeout The desired timeout (can be NULL => wait for
174  * ever). It is updated by the function to ref    174  * ever). It is updated by the function to reflect the remaining
175  * timeout in case the thread has been woken-u    175  * timeout in case the thread has been woken-up prior to its
176  * expiration.                                    176  * expiration.
177  *                                                177  *
178  * @return -SOS_EINTR when the thread is resum    178  * @return -SOS_EINTR when the thread is resumed while it has not be
179  * explicitely woken up by someone calling sos    179  * explicitely woken up by someone calling sos_kwaitq_wakeup() upon
180  * the same waitqueue... This can only happen     180  * the same waitqueue... This can only happen 1/ if the timeout
181  * expired, or 2/ if the current thread is als    181  * expired, or 2/ if the current thread is also in another kwaitq
182  * different to "kwq". Otherwise return the va    182  * different to "kwq". Otherwise return the value set by
183  * sos_kwaitq_wakeup(). The timeout remaining     183  * sos_kwaitq_wakeup(). The timeout remaining is updated in timeout.
184  *                                                184  *
185  * @note This is a BLOCKING FUNCTION              185  * @note This is a BLOCKING FUNCTION
186  */                                               186  */
187 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *k    187 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *kwq,
188                           struct sos_time *tim    188                           struct sos_time *timeout);
189                                                   189 
190                                                   190 
191 /**                                               191 /**
192  * Wake up as much as nb_thread threads (SOS_K    192  * Wake up as much as nb_thread threads (SOS_KWQ_WAKEUP_ALL to wake
193  * up all threads) in the kwaitq kwq, in FIFO     193  * up all threads) in the kwaitq kwq, in FIFO or decreasing priority
194  * order (depends on the ordering scheme selec    194  * order (depends on the ordering scheme selected at kwaitq
195  * initialization time).                          195  * initialization time).
196  *                                                196  *
197  * @param wakeup_status The value returned by     197  * @param wakeup_status The value returned by sos_kwaitq_wait() when
198  * the thread will effectively woken up due to    198  * the thread will effectively woken up due to this wakeup.
199  */                                               199  */
200 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq     200 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq *kwq,
201                             unsigned int nb_th    201                             unsigned int nb_threads,
202                             sos_ret_t wakeup_s    202                             sos_ret_t wakeup_status);
203 #define SOS_KWQ_WAKEUP_ALL (~((unsigned int)0)    203 #define SOS_KWQ_WAKEUP_ALL (~((unsigned int)0))
204                                                   204 
205                                                   205 
206 /**                                               206 /**
207  * @note INTERNAL function (in particular: int    207  * @note INTERNAL function (in particular: interrupts not disabled) !
208  *                                                208  *
209  * @note: The use of this function is RESERVED    209  * @note: The use of this function is RESERVED (to thread.c). Do not
210  * call it directly: use sos_thread_set_priori    210  * call it directly: use sos_thread_set_priority() for that !
211  */                                               211  */
212 sos_ret_t sos_kwaitq_change_priority(struct so    212 sos_ret_t sos_kwaitq_change_priority(struct sos_kwaitq *kwq,
213                                      struct so    213                                      struct sos_kwaitq_entry *kwq_entry,
214                                      sos_sched    214                                      sos_sched_priority_t priority);
215                                                   215 
216 #endif /* _SOS_KWAITQ_H_ */                       216 #endif /* _SOS_KWAITQ_H_ */
                                                      

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