00001 /* 00002 * Copyright (c) 2004, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * Author: Adam Dunkels <adam@sics.se> 00032 * 00033 * $Id: mt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ 00034 */ 00035 00036 /** \addtogroup sys 00037 * @{ 00038 */ 00039 00040 /** 00041 * \defgroup mt Multi-threading library 00042 * 00043 * The event driven Contiki kernel does not provide multi-threading 00044 * by itself - instead, preemptive multi-threading is implemented 00045 * as a library that optionally can be linked with applications. This 00046 * library constists of two parts: a platform independent part, which is 00047 * the same for all platforms on which Contiki runs, and a platform 00048 * specific part, which must be implemented specifically for the 00049 * platform that the multi-threading library should run. 00050 * 00051 * @{ 00052 */ 00053 00054 /** 00055 * \defgroup mtarch Architecture support for multi-threading 00056 * @{ 00057 * 00058 * The Contiki multi-threading library requires some architecture 00059 * specific support for seting up and switching stacks. This support 00060 * requires three stack manipulation functions to be implemented: 00061 * mtarch_start(), which sets up the stack frame for a new thread, 00062 * mtarch_exec(), which switches in the stack of a thread, and 00063 * mtarch_yield(), which restores the kernel stack from a thread's 00064 * stack. Additionally, two functions for controlling the preemption 00065 * (if any) must be implemented: mtarch_preemption_start() and 00066 * mtarch_preemption_stop(). If no preemption is used, these functions 00067 * can be implemented as empty functions. Finally, the function 00068 * mtarch_init() is called by mt_init(), and can be used for 00069 * initalization of timer interrupts, or any other mechanisms required 00070 * for correct operation of the architecture specific support funcions. 00071 * 00072 */ 00073 00074 /** 00075 * \file 00076 * Header file for the preemptive multitasking library for Contiki. 00077 * \author 00078 * Adam Dunkels <adam@sics.se> 00079 * 00080 */ 00081 #ifndef __MT_H__ 00082 #define __MT_H__ 00083 00084 #include "contiki.h" 00085 00086 00087 /** 00088 * An opaque structure that is used for holding the state of a thread. 00089 * 00090 * The structure should be defined in the "mtarch.h" file. This 00091 * structure typically holds the entire stack for the thread. 00092 */ 00093 struct mtarch_thread; 00094 00095 /** 00096 * Initialize the architecture specific support functions for the 00097 * multi-thread library. 00098 * 00099 * This function is implemented by the architecture specific functions 00100 * for the multi-thread library and is called by the mt_init() 00101 * function as part of the initialization of the library. The 00102 * mtarch_init() function can be used for, e.g., starting preemtion 00103 * timers or other architecture specific mechanisms required for the 00104 * operation of the library. 00105 */ 00106 void mtarch_init(void); 00107 00108 /** 00109 * Uninstall library and clean up. 00110 * 00111 */ 00112 void mtarch_remove(void); 00113 00114 /** 00115 * Setup the stack frame for a thread that is being started. 00116 * 00117 * This function is called by the mt_start() function in order to set 00118 * up the architecture specific stack of the thread to be started. 00119 * 00120 * \param thread A pointer to a struct mtarch_thread for the thread to 00121 * be started. 00122 * 00123 * \param function A pointer to the function that the thread will 00124 * start executing the first time it is scheduled to run. 00125 * 00126 * \param data A pointer to the argument that the function should be 00127 * passed. 00128 */ 00129 void mtarch_start(struct mtarch_thread *thread, 00130 void (* function)(void *data), 00131 void *data); 00132 00133 /** 00134 * Yield the processor. 00135 * 00136 * This function is called by the mt_yield() function, which is called 00137 * from the running thread in order to give up the processor. 00138 * 00139 */ 00140 void mtarch_yield(void); 00141 00142 /** 00143 * Start executing a thread. 00144 * 00145 * This function is called from mt_exec() and the purpose of the 00146 * function is to start execution of the thread. The function should 00147 * switch in the stack of the thread, and does not return until the 00148 * thread has explicitly yielded (using mt_yield()) or until it is 00149 * preempted. 00150 * 00151 */ 00152 void mtarch_exec(struct mtarch_thread *thread); 00153 00154 00155 void mtarch_pstart(void); 00156 void mtarch_pstop(void); 00157 00158 /** @} */ 00159 00160 00161 #include "mtarch.h" 00162 00163 struct mt_thread { 00164 int state; 00165 process_event_t *evptr; 00166 process_data_t *dataptr; 00167 struct mtarch_thread thread; 00168 }; 00169 00170 /** 00171 * No error. 00172 * 00173 * \hideinitializer 00174 */ 00175 #define MT_OK 1 00176 00177 /** 00178 * Initializes the multithreading library. 00179 * 00180 */ 00181 void mt_init(void); 00182 00183 /** 00184 * Uninstalls library and cleans up. 00185 * 00186 */ 00187 void mt_remove(void); 00188 00189 00190 /** 00191 * Starts a multithreading thread. 00192 * 00193 * \param thread Pointer to an mt_thread struct that must have been 00194 * previously allocated by the caller. 00195 * 00196 * \param function A pointer to the entry function of the thread that is 00197 * to be set up. 00198 * 00199 * \param data A pointer that will be passed to the entry function. 00200 * 00201 */ 00202 void mt_start(struct mt_thread *thread, void (* function)(void *), void *data); 00203 00204 /** 00205 * Execute parts of a thread. 00206 * 00207 * This function is called by a Contiki process and runs a 00208 * thread. The function does not return until the thread has yielded, 00209 * or is preempted. 00210 * 00211 * \note The thread must first be initialized with the mt_init() function. 00212 * 00213 * \param thread A pointer to a struct mt_thread block that must be 00214 * allocated by the caller. 00215 * 00216 */ 00217 void mt_exec(struct mt_thread *thread); 00218 00219 /** 00220 * Post an event to a thread. 00221 * 00222 * This function posts an event to a thread. The thread will be 00223 * scheduled if the thread currently is waiting for the posted event 00224 * number. If the thread is not waiting for the event, this function 00225 * does nothing. 00226 * 00227 * \note The thread must first be initialized with the mt_init() function. 00228 * 00229 * \param thread A pointer to a struct mt_thread block that must be 00230 * allocated by the caller. 00231 * 00232 * \param s The event that is posted to the thread. 00233 * 00234 * \param data An opaque pointer to a user specified structure 00235 * containing additonal information, or NULL if no additional 00236 * information is needed. 00237 */ 00238 void mt_exec_event(struct mt_thread *thread, process_event_t s, 00239 process_data_t data); 00240 00241 /** 00242 * Voluntarily give up the processor. 00243 * 00244 * This function is called by a running thread in order to give up 00245 * control of the CPU. 00246 * 00247 */ 00248 void mt_yield(void); 00249 00250 /** 00251 * Post an event to another process. 00252 * 00253 * This function is called by a running thread and will emit a signal 00254 * to another Contiki process. This will cause the currently executing 00255 * thread to yield. 00256 * 00257 * \param p The process receiving the signal, or PROCESS_BROADCAST 00258 * for a broadcast event. 00259 * 00260 * \param ev The event to be posted. 00261 * 00262 * \param data A pointer to a message that is to be delivered together 00263 * with the signal. 00264 * 00265 */ 00266 void mt_post(struct process *p, process_event_t ev, process_data_t data); 00267 00268 /** 00269 * Block and wait for an event to occur. 00270 * 00271 * This function can be called by a running thread in order to block 00272 * and wait for an event. The function returns when an event has 00273 * occured. The event number and the associated data are placed in the 00274 * variables pointed to by the function arguments. 00275 * 00276 * \param ev A pointer to a process_event_t variable. The variable 00277 * will be filled with the number event that woke the thread. 00278 * 00279 * \param data A pointer to a process_data_t variable. The variable 00280 * will be filled with the data associated with the event that woke 00281 * the thread. 00282 * 00283 */ 00284 void mt_wait(process_event_t *ev, process_data_t *data); 00285 00286 /** 00287 * Exit a thread. 00288 * 00289 * This function is called from within an executing thread in order to 00290 * exit the thread. The function never returns. 00291 * 00292 */ 00293 void mt_exit(void); 00294 00295 /** 00296 * \defgroup mtp Multi-threading library convenience functions 00297 * @{ 00298 * 00299 * The Contiki multi-threading library has an interface that might be 00300 * hard to use. Therefore, the mtp module provides a simpler 00301 * interface. 00302 * 00303 * Example: 00304 \code 00305 static void 00306 example_thread_code(void *data) 00307 { 00308 while(1) { 00309 printf("Test\n"); 00310 mt_yield(); 00311 } 00312 } 00313 MTP(example_thread, "Example thread", p1, t1, t1_idle); 00314 00315 int 00316 main(int argc, char *argv[]) 00317 { 00318 mtp_start(&example_thread, example_thread_code, NULL); 00319 } 00320 \endcode 00321 * 00322 */ 00323 00324 00325 /** 00326 * Declare a multithreaded process. 00327 * 00328 * This macro is used to declare a multithreaded process. 00329 * 00330 * \hideinitializer 00331 */ 00332 #define MT_PROCESS(name, strname) \ 00333 extern struct mt_process name##mt_process; \ 00334 struct process name = { NULL, strname, mt_process_thread }; \ 00335 static struct mt_process thread = {&name} 00336 00337 struct mt_process { 00338 struct process *p; 00339 struct mt_thread t; 00340 }; 00341 00342 /** 00343 * Start a thread. 00344 * 00345 * This function starts the process in which the thread is to run, and 00346 * also sets up the thread to run within the process. The function 00347 * should be passed variable names declared with the MTP() macro. 00348 * 00349 * \param t A pointer to a thread structure previously declared with MTP(). 00350 * 00351 * \param function A pointer to the function that the thread should 00352 * start executing. 00353 * 00354 * \param data A pointer that the function should be passed when first 00355 * invocated. 00356 */ 00357 void mtp_start(struct mt_process *p, 00358 void (* function)(void *), void *data); 00359 00360 void mtp_exit(void); 00361 void mtp_eventhandler(process_event_t ev, process_data_t data); 00362 00363 /** @} */ 00364 /** @} */ 00365 /** @} */ 00366 #endif /* __MT_H__ */