|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2004 David Decotigny 002 003 This program is free software; you can redistribute it and/or 004 modify it under the terms of the GNU General Public License 005 as published by the Free Software Foundation; either version 2 006 of the License, or (at your option) any later version. 007 008 This program is distributed in the hope that it will be useful, 009 but WITHOUT ANY WARRANTY; without even the implied warranty of 010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 011 GNU General Public License for more details. 012 013 You should have received a copy of the GNU General Public License 014 along with this program; if not, write to the Free Software 015 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 016 USA. 017 */ 018 #ifndef _SOS_KWAITQ_H_ 019 #define _SOS_KWAITQ_H_ 020 021 #include <sos/errno.h> 022 #include <sos/thread.h> 023 #include <sos/time.h> 024 #include <sos/sched.h> 025 026 027 /** 028 * @kwaitq.h 029 * 030 * Low-level functions to manage queues of threads waiting for a 031 * resource. These functions are public. For higher-level 032 * synchronization primitives such as mutex, semaphores, conditions, 033 * ... prefer looking at the corresponding libraries. 034 */ 035 036 037 /** 038 * Define this if you want to know the names of the kwaitq 039 */ 040 // #define SOS_KWQ_DEBUG 041 042 043 /* Forward declaration */ 044 struct sos_kwaitq_entry; 045 046 047 /** 048 * Definition of a waitqueue. In a kwaitq, the threads are ordererd in 049 * FIFO order. 050 */ 051 struct sos_kwaitq 052 { 053 #ifdef SOS_KWQ_DEBUG 054 # define SOS_KWQ_DEBUG_MAX_NAMELEN 32 055 char name[SOS_KWQ_DEBUG_MAX_NAMELEN]; 056 #endif 057 struct sos_kwaitq_entry *waiting_list; 058 }; 059 060 061 /** 062 * Definition of an entry for a thread waiting in the waitqueue 063 */ 064 struct sos_kwaitq_entry 065 { 066 /** The thread associted with this entry */ 067 struct sos_thread *thread; 068 069 /** The kwaitqueue this entry belongs to */ 070 struct sos_kwaitq *kwaitq; 071 072 /** TRUE when somebody woke up this entry */ 073 sos_bool_t wakeup_triggered; 074 075 /** The status of wakeup for this entry. @see wakeup_status argument 076 of sos_kwaitq_wakeup() */ 077 sos_ret_t wakeup_status; 078 079 /** Other entries in this kwaitqueue */ 080 struct sos_kwaitq_entry *prev_entry_in_kwaitq, *next_entry_in_kwaitq; 081 082 /** Other entries for the thread */ 083 struct sos_kwaitq_entry *prev_entry_for_thread, *next_entry_for_thread; 084 }; 085 086 087 /** 088 * Initialize an empty waitqueue. 089 * 090 * @param name Used only if SOS_KWQ_DEBUG is defined (safe [deep 091 * copied]) 092 */ 093 sos_ret_t sos_kwaitq_init(struct sos_kwaitq *kwq, 094 const char *name); 095 096 097 /** 098 * Release a waitqueue, making sure that no thread is in it. 099 * 100 * @return -SOS_EBUSY in case a thread is still in the waitqueue. 101 */ 102 sos_ret_t sos_kwaitq_dispose(struct sos_kwaitq *kwq); 103 104 105 /** 106 * Return whether there are no threads in the waitq 107 */ 108 sos_bool_t sos_kwaitq_is_empty(const struct sos_kwaitq *kwq); 109 110 111 /** 112 * Initialize a waitqueue entry. Mainly consists in updating the 113 * "thread" field of the entry (set to current running thread), and 114 * initializing the remaining of the entry as to indicate it does not 115 * belong to any waitq. 116 */ 117 sos_ret_t sos_kwaitq_init_entry(struct sos_kwaitq_entry *kwq_entry); 118 119 120 /** 121 * Add an entry (previously initialized with sos_kwaitq_init_entry()) 122 * in the given waitqueue. 123 * 124 * @note: No state change/context switch can occur here ! Among other 125 * things: the current executing thread is not preempted. 126 */ 127 sos_ret_t sos_kwaitq_add_entry(struct sos_kwaitq *kwq, 128 struct sos_kwaitq_entry *kwq_entry); 129 130 131 /** 132 * Remove the given kwaitq_entry from the kwaitq. 133 * 134 * @note: No state change/context switch can occur here ! Among other 135 * things: the thread associated with the entry is not necessarilly 136 * the same as the one currently running, and does not preempt the 137 * current running thread if they are different. 138 */ 139 sos_ret_t sos_kwaitq_remove_entry(struct sos_kwaitq *kwq, 140 struct sos_kwaitq_entry *kwq_entry); 141 142 143 /** 144 * Helper function to make the current running thread block in the 145 * given kwaitq, waiting to be woken up by somedy else or by the given 146 * timeout. It calls the sos_kwaitq_add_entry() and 147 * sos_kwaitq_remove_entry(). 148 * 149 * @param timeout The desired timeout (can be NULL => wait for 150 * ever). It is updated by the function to reflect the remaining 151 * timeout in case the thread has been woken-up prior to its 152 * expiration. 153 * 154 * @return -SOS_EINTR when the thread is resumed while it has not be 155 * explicitely woken up by someone calling sos_kwaitq_wakeup() upon 156 * the same waitqueue... This can only happen 1/ if the timeout 157 * expired, or 2/ if the current thread is also in another kwaitq 158 * different to "kwq". Otherwise return the value set by 159 * sos_kwaitq_wakeup(). The timeout remaining is updated in timeout. 160 * 161 * @note This is a BLOCKING FUNCTION 162 */ 163 sos_ret_t sos_kwaitq_wait(struct sos_kwaitq *kwq, 164 struct sos_time *timeout); 165 166 167 /** 168 * Wake up as much as nb_thread threads (SOS_KWQ_WAKEUP_ALL to wake 169 * up all threads) in the kwaitq kwq, in FIFO order. 170 * 171 * @param wakeup_status The value returned by sos_kwaitq_wait() when 172 * the thread will effectively woken up due to this wakeup. 173 */ 174 sos_ret_t sos_kwaitq_wakeup(struct sos_kwaitq *kwq, 175 unsigned int nb_threads, 176 sos_ret_t wakeup_status); 177 #define SOS_KWQ_WAKEUP_ALL (~((unsigned int)0)) 178 179 180 #endif /* _SOS_KWAITQ_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |