00001 /* $Id: thread.c 22023 2005-09-05 14:23:39Z fm3 $ */ 00002 /*****************************************************************************/ 00003 /** 00004 * \file dsi/lib/src/thread.c 00005 * \brief Thread handling. 00006 * 00007 * \date 07/09/2000 00008 * \author Lars Reuther <reuther@os.inf.tu-dresden.de> 00009 */ 00010 /*****************************************************************************/ 00011 00012 /* L4 includes */ 00013 #include <stdio.h> 00014 #include <l4/sys/types.h> 00015 #include <l4/env/errno.h> 00016 #include <l4/util/macros.h> 00017 #include <l4/thread/thread.h> 00018 00019 /* lib includes */ 00020 #include <l4/dsi/dsi.h> 00021 #include "__socket.h" 00022 #include "__sync.h" 00023 #include "__config.h" 00024 #include "__debug.h" 00025 #include "__thread.h" 00026 00027 static int sync_thread_prio = L4THREAD_DEFAULT_PRIO; 00028 static int select_thread_prio = L4THREAD_DEFAULT_PRIO; 00029 static int event_thread_prio = L4THREAD_DEFAULT_PRIO; 00030 00031 /*****************************************************************************/ 00032 /** 00033 * \brief Set priority of syncronisation threads created in the future. 00034 * \ingroup general 00035 * 00036 * \param new_prio The new L4 priority. Use L4THREAD_DEFAULT_PRIO to 00037 * use the default priority of the l4 thread lib. The 00038 * actual priority depends on the implementation of 00039 * the l4 thread lib. 00040 * 00041 * \return old sync-thread priority. 00042 * 00043 * This function sets the priority used to create the synchronisation threads. 00044 * This function does not effect existing threads. 00045 * 00046 * Prior to the first call, L4THREAD_DEFAULT_PRIO will be used to create 00047 * the synchronisation threads. 00048 */ 00049 /*****************************************************************************/ 00050 int 00051 dsi_set_sync_thread_prio(int new_prio) 00052 { 00053 int old_prio = sync_thread_prio; 00054 00055 sync_thread_prio = new_prio; 00056 00057 return old_prio; 00058 } 00059 00060 /*****************************************************************************/ 00061 /** 00062 * \brief Set priority of the select threads created in the future. 00063 * \ingroup general 00064 * 00065 * \param new_prio The new L4 priority. Use L4THREAD_DEFAULT_PRIO to 00066 * use the default priority of the l4 thread lib. The 00067 * actual priority depends on the implementation of 00068 * the l4 thread lib. 00069 * 00070 * \return old select-thread priority. 00071 * 00072 * This function sets the priority used to create the select threads. 00073 * This function does not effect existing threads. 00074 * 00075 * Prior to the first call, L4THREAD_DEFAULT_PRIO will be used to create 00076 * the select threads. 00077 */ 00078 /*****************************************************************************/ 00079 int 00080 dsi_set_select_thread_prio(int new_prio) 00081 { 00082 int old_prio = select_thread_prio; 00083 00084 select_thread_prio = new_prio; 00085 00086 return old_prio; 00087 } 00088 00089 /*****************************************************************************/ 00090 /** 00091 * \brief Set priority of event thread created in the future. 00092 * \ingroup general 00093 * 00094 * \param new_prio The new L4 priority. Use L4THREAD_DEFAULT_PRIO to 00095 * use the default priority of the l4 thread lib. The 00096 * actual priority depends on the implementation of 00097 * the l4 thread lib. 00098 * 00099 * \return old event-thread priority. 00100 * 00101 * This function sets the priority used to create the event thread. 00102 * It should be called prior to dsi_init(), otherwise it has no effect. 00103 * 00104 * If this function is not called, L4THREAD_DEFAULT_PRIO will be used to 00105 * create the event thread. 00106 */ 00107 /*****************************************************************************/ 00108 int 00109 dsi_set_event_thread_prio(int new_prio) 00110 { 00111 int old_prio = event_thread_prio; 00112 00113 event_thread_prio = new_prio; 00114 00115 return old_prio; 00116 } 00117 00118 00119 /*****************************************************************************/ 00120 /** 00121 * \brief Create new synchronization thread for socket. 00122 * \ingroup internal 00123 * 00124 * \param socket Socket descriptor 00125 * \return 0 on success, error code otherwise (see l4thread_create_long()) 00126 * 00127 * The priority of the newly created thread can be set with 00128 * dsi_set_sync_thread_prio() prior to calling this function. 00129 */ 00130 /*****************************************************************************/ 00131 int 00132 dsi_create_sync_thread(dsi_socket_t * socket) 00133 { 00134 l4thread_t t; 00135 char buf[14]; 00136 00137 /* start synchronization thread */ 00138 if (IS_SEND_SOCKET(socket)) 00139 { 00140 00141 LOGdL(DEBUG_THREAD,"send sync thread..."); 00142 sprintf(buf, "dsi.txsync-%.2d", socket->socket_id); 00143 00144 t = l4thread_create_long(L4THREAD_INVALID_ID,dsi_sync_thread_send, 00145 buf, 00146 L4THREAD_INVALID_SP,L4THREAD_DEFAULT_SIZE, 00147 sync_thread_prio, (void *)socket, 00148 L4THREAD_CREATE_ASYNC); 00149 } 00150 else 00151 { 00152 LOGdL(DEBUG_THREAD,"receive sync thread..."); 00153 sprintf(buf, "dsi.rxsync-%.2d", socket->socket_id); 00154 00155 t = l4thread_create_long(L4THREAD_INVALID_ID,dsi_sync_thread_receive, 00156 buf, 00157 L4THREAD_INVALID_SP,L4THREAD_DEFAULT_SIZE, 00158 sync_thread_prio, (void *)socket, 00159 L4THREAD_CREATE_ASYNC); 00160 } 00161 00162 if (t < 0) 00163 { 00164 LOG_Error("DSI: failed to create sync thread: %s (%d)", 00165 l4env_errstr(t), t); 00166 return t; 00167 } 00168 00169 LOGdL(DEBUG_THREAD,"created sync thread %d",t); 00170 00171 /* setup socket descriptor */ 00172 socket->sync_id = t; 00173 socket->sync_th = l4thread_l4_id(t); 00174 00175 /* done */ 00176 return 0; 00177 } 00178 00179 /*****************************************************************************/ 00180 /** 00181 * \brief Shutdown synchronization thread. 00182 * \ingroup internal 00183 * 00184 * \param socket Socket descriptor. 00185 * \return 0 on success, error code otherwise (see l4thread_shutdown()) 00186 */ 00187 /*****************************************************************************/ 00188 int 00189 dsi_shutdown_sync_thread(dsi_socket_t * socket) 00190 { 00191 LOGdL(DEBUG_THREAD,"shutdown sync thread..."); 00192 00193 /* shutdown synchronization thread */ 00194 return l4thread_shutdown(socket->sync_id); 00195 } 00196 00197 /*****************************************************************************/ 00198 /** 00199 * \brief Start event signalling thread. 00200 * \ingroup internal 00201 * 00202 * \param fn Signalling thread function 00203 * 00204 * \return L4 threadid of signalling thread, \c L4_INVALID_ID if creation 00205 * failed. 00206 * 00207 * The priority of the newly created thread can be set with 00208 * dsi_set_event_thread_prio() prior to calling this function. 00209 */ 00210 /*****************************************************************************/ 00211 l4_threadid_t 00212 dsi_create_event_thread(l4thread_fn_t fn) 00213 { 00214 l4thread_t t; 00215 00216 /* create thread */ 00217 t = l4thread_create_long(L4THREAD_INVALID_ID,fn, ".dsi-evt", 00218 L4THREAD_INVALID_SP,L4THREAD_DEFAULT_SIZE, 00219 event_thread_prio,NULL,L4THREAD_CREATE_ASYNC); 00220 if (t < 0) 00221 { 00222 Panic("DSI: create event signalling thread failed: %s (%d)", 00223 l4env_errstr(t),t); 00224 return L4_INVALID_ID; 00225 } 00226 else 00227 return l4thread_l4_id(t); 00228 } 00229 00230 /*****************************************************************************/ 00231 /** 00232 * \brief Start a select thread. 00233 * 00234 * \param fn Thread function 00235 * \param data Thread data 00236 * 00237 * \return Thread id of select thread, \c L4THREAD_INVALID_ID if creation 00238 * failed. 00239 * 00240 * The priority of the newly created thread can be set with 00241 * dsi_set_select_thread_prio() prior to calling this function. 00242 * 00243 */ 00244 /*****************************************************************************/ 00245 l4thread_t 00246 dsi_create_select_thread(l4thread_fn_t fn, void * data, int tid, int nr) 00247 { 00248 l4thread_t t; 00249 char buf[14]; 00250 00251 sprintf(buf, "dsi.sel-%.2d.%.2d", tid, nr); 00252 /* create thread */ 00253 t = l4thread_create_long(L4THREAD_INVALID_ID,fn, buf, 00254 L4THREAD_INVALID_SP, 00255 L4THREAD_DEFAULT_SIZE, 00256 select_thread_prio, 00257 data,L4THREAD_CREATE_ASYNC); 00258 if (t < 0) 00259 { 00260 LOG_Error("DSI: create select thread failed: %s (%d)", 00261 l4env_errstr(t),t); 00262 return L4THREAD_INVALID_ID; 00263 } 00264 else 00265 return t; 00266 } 00267 00268 /*****************************************************************************/ 00269 /** 00270 * \brief Shutdown select thread. 00271 * 00272 * \param thread Select thread. 00273 */ 00274 /*****************************************************************************/ 00275 void 00276 dsi_shutdown_select_thread(l4thread_t thread) 00277 { 00278 int ret; 00279 00280 /* shutdown thread */ 00281 ret = l4thread_shutdown(thread); 00282 00283 if (ret) 00284 LOG_Error("DSI: shutdown select thread failed: %s (%d)", 00285 l4env_errstr(ret),ret); 00286 }