blob: bbfbc34d43f709f9e550edd8abd158bbf7d50695 [file] [log] [blame]
adamdunkelsa2f3c422004-09-12 20:24:53 +00001/*
2 * Copyright (c) 2004, Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 * Author: Adam Dunkels <adam@sics.se>
32 *
adamdunkels442bdc82005-02-22 22:46:33 +000033 * $Id: mt.h,v 1.4 2005/02/22 22:46:33 adamdunkels Exp $
adamdunkelsa2f3c422004-09-12 20:24:53 +000034 */
35
adamdunkels50b3feb2004-07-04 15:04:56 +000036/**
adamdunkels442bdc82005-02-22 22:46:33 +000037 * \defgroup mt Multi-threading library
adamdunkels50b3feb2004-07-04 15:04:56 +000038 * @{
39 *
40 * The event driven Contiki kernel does not provide multi-threading
41 * by itself - instead, preemptive multi-threading is implemented
42 * as a library that optionally can be linked with applications. This
43 * library constists of two parts: a platform independent part, which is
44 * the same for all platforms on which Contiki runs, and a platform
45 * specific part, which must be implemented specifically for the
46 * platform that the multi-threading library should run.
47 */
48
adamdunkels50b3feb2004-07-04 15:04:56 +000049/**
50 * \defgroup mtarch Architecture support for multi-threading
51 * @{
52 *
53 * The Contiki multi-threading library requires some architecture
54 * specific support for seting up and switching stacks. This support
55 * requires three stack manipulation functions to be implemented:
56 * mtarch_start(), which sets up the stack frame for a new thread,
57 * mtarch_exec(), which switches in the stack of a thread, and
58 * mtarch_yield(), which restores the kernel stack from a thread's
59 * stack. Additionally, two functions for controlling the preemption
60 * (if any) must be implemented: mtarch_preemption_start() and
61 * mtarch_preemption_stop(). If no preemption is used, these functions
62 * can be implemented as empty functions. Finally, the function
63 * mtarch_init() is called by mt_init(), and can be used for
64 * initalization of timer interrupts, or any other mechanisms required
65 * for correct operation of the architecture specific support funcions.
66 *
67 */
68
69/**
adamdunkels12860b02004-08-20 21:27:42 +000070 * \file
71 * Header file for the preemptive multitasking library for Contiki.
72 * \author
73 * Adam Dunkels <adam@sics.se>
74 *
75 */
76#ifndef __MT_H__
77#define __MT_H__
78
79#include "ek.h"
80
81
82/**
adamdunkels50b3feb2004-07-04 15:04:56 +000083 * An opaque structure that is used for holding the state of a thread.
84 *
85 * The structure should be defined in the "mtarch.h" file. This
86 * structure typically holds the entire stack for the thread.
87 */
88struct mtarch_thread;
89
90/**
91 * Initialize the architecture specific support functions for the
92 * multi-thread library.
93 *
94 * This function is implemented by the architecture specific functions
95 * for the multi-thread library and is called by the mt_init()
96 * function as part of the initialization of the library. The
97 * mtarch_init() function can be used for, e.g., starting preemtion
98 * timers or other architecture specific mechanisms required for the
99 * operation of the library.
100 */
101void mtarch_init(void);
102
103/**
104 * Uninstall library and clean up.
105 *
106 */
107void mtarch_remove(void);
108
109/**
110 * Setup the stack frame for a thread that is being started.
111 *
112 * This function is called by the mt_start() function in order to set
113 * up the architecture specific stack of the thread to be started.
114 *
115 * \param thread A pointer to a struct mtarch_thread for the thread to
116 * be started.
117 *
118 * \param function A pointer to the function that the thread will
119 * start executing the first time it is scheduled to run.
120 *
121 * \param data A pointer to the argument that the function should be
122 * passed.
123 */
124void mtarch_start(struct mtarch_thread *thread,
125 void (* function)(void *data),
126 void *data);
127
128/**
129 * Yield the processor.
130 *
131 * This function is called by the mt_yield() function, which is called
132 * from the running thread in order to give up the processor.
133 *
134 */
135void mtarch_yield(void);
136
137/**
138 * Start executing a thread.
139 *
140 * This function is called from mt_exec() and the purpose of the
141 * function is to start execution of the thread. The function should
142 * switch in the stack of the thread, and does not return until the
143 * thread has explicitly yielded (using mt_yield()) or until it is
144 * preempted.
145 *
146 */
147void mtarch_exec(struct mtarch_thread *thread);
148
149
150void mtarch_pstart(void);
151void mtarch_pstop(void);
152
153/** @} */
154
155
156#include "mtarch.h"
157#include "ek.h"
158
159struct mt_thread {
160 int state;
161 ek_event_t *evptr;
162 ek_data_t *dataptr;
163 struct mtarch_thread thread;
164};
165
166/**
167 * No error.
168 *
169 * \hideinitializer
170 */
171#define MT_OK 1
172
173/**
174 * Initializes the multithreading library.
175 *
176 */
177void mt_init(void);
178
179/**
180 * Uninstalls library and cleans up.
181 *
182 */
183void mt_remove(void);
184
185
186/**
187 * Starts a multithreading thread.
188 *
189 * \param thread Pointer to an mt_thread struct that must have been
190 * previously allocated by the caller.
191 *
192 * \param function A pointer to the entry function of the thread that is
193 * to be set up.
194 *
195 * \param data A pointer that will be passed to the entry function.
196 *
197 */
198void mt_start(struct mt_thread *thread, void (* function)(void *), void *data);
199
200/**
201 * Start executing a thread.
202 *
203 * This function is called by a Contiki process and starts running a
204 * thread. The function does not return until the thread has yielded,
205 * or is preempted.
206 *
207 * \note The thread must first be initialized with the mt_init() function.
208 *
209 * \param thread A pointer to a struct mt_thread block that must be
210 * allocated by the caller.
211 *
212 */
213void mt_exec(struct mt_thread *thread);
214
215/**
216 * Post an event to a thread.
217 *
218 * This function posts an event to a thread. The thread will be
219 * scheduled if the thread currently is waiting for the posted event
220 * number. If the thread is not waiting for the event, this function
221 * does nothing.
222 *
223 * \note The thread must first be initialized with the mt_init() function.
224 *
225 * \param thread A pointer to a struct mt_thread block that must be
226 * allocated by the caller.
227 *
228 * \param s The event that is posted to the thread.
adamdunkels442bdc82005-02-22 22:46:33 +0000229 *
230 * \param data An opaque pointer to a user specified structure
231 * containing additonal information, or NULL if no additional
232 * information is needed.
adamdunkels50b3feb2004-07-04 15:04:56 +0000233 */
234void mt_exec_event(struct mt_thread *thread, ek_event_t s, ek_data_t data);
235
236/**
237 * Voluntarily give up the processor.
238 *
239 * This function is called by a running thread in order to give up
240 * control of the CPU.
241 *
242 */
243void mt_yield(void);
244
245/**
246 * Emit a signal to another process.
247 *
248 * This function is called by a running thread and will emit a signal
249 * to another Contiki process. This will cause the currently executing
250 * thread to yield.
251 *
252 * \param s The signal to be emitted.
253 * \param data A pointer to a message that is to be delivered together with the signal.
254 * \param id The process ID of the receiver of the signal, or EK_ID_ALL for a broadcast signal.
255 */
256void mt_post(ek_id_t id, ek_event_t s, ek_data_t data);
257
258/**
259 * Block and wait for an event to occur.
260 *
261 * This function can be called by a running thread in order to block
262 * and wait for an event. The function returns when an event has
263 * occured. The event number and the associated data are placed in the
264 * variables pointed to by the function arguments.
265 *
266 */
267void mt_wait(ek_event_t *s, ek_data_t *data);
268
269/**
270 * Exit a thread.
271 *
272 * This function is called from within an executing thread in order to
273 * exit the thread. The function never returns.
274 *
275 */
276void mt_exit(void);
277
278/**
279 * \defgroup mtp Multi-threading library convenience functions
280 * @{
281 *
282 * The Contiki multi-threading library has an interface that might be
283 * hard to use. Therefore, the mtp module provides a simpler
284 * interface.
285 *
286 * Example:
287\code
288static void
289example_thread_code(void *data)
290{
291 while(1) {
292 printf("Test\n");
293 mt_yield();
294 }
295}
296MTP(example_thread, "Example thread", p1, t1, t1_idle);
297
298int
299main(int argc, char *argv[])
300{
301 mtp_start(&example_thread, example_thread_code, NULL);
302}
303\endcode
304*
305*/
306
307#include "mt.h"
308
309/**
310 * Declare a thread.
311 *
312 * This macro is used to covneniently declare a thread, and the
313 * process in which the thread should execute. The names of the
314 * variables provided to the macro should be chosen to be unique
315 * within the file that the thread is used.
316 *
317 * Example:
318\code
adamdunkels442bdc82005-02-22 22:46:33 +0000319MTP(example_thread, example_proc, "Example thread");
adamdunkels50b3feb2004-07-04 15:04:56 +0000320\endcode
321 *
adamdunkels442bdc82005-02-22 22:46:33 +0000322 * \param thread The variable name of the thread.
323 *
324 * \param proc The variable name of the process containing the thread.
adamdunkels50b3feb2004-07-04 15:04:56 +0000325 *
326 * \param name A string that specifies the user-visible name of the
327 * process in which the thread will run.
328 *
adamdunkels50b3feb2004-07-04 15:04:56 +0000329 * \hideinitializer
330 */
331#define MTP(thread, proc, name) \
332extern struct mtp_thread thread; \
333EK_PROCESS(proc, name, EK_PRIO_NORMAL, mtp_eventhandler, \
334 NULL, (void *)&thread); \
335static struct mtp_thread thread = {&proc}
336
337struct mtp_thread {
338 struct ek_proc *p;
339 struct mt_thread t;
340};
341
342/**
343 * Start a thread.
344 *
345 * This function starts the process in which the thread is to run, and
346 * also sets up the thread to run within the process. The function
347 * should be passed variable names declared with the MTP() macro.
348 *
349 * Example:
350\code
351mtp_start(&t, example_thread_code, NULL);
352\endcode
353 * \param t A pointer to a thread structure previously declared with MTP().
354 *
355 * \param function A pointer to the function that the thread should
356 * start executing.
357 *
358 * \param data A pointer that the function should be passed when first
359 * invocated.
360 */
361void mtp_start(struct mtp_thread *t,
362 void (* function)(void *), void *data);
363
364void mtp_exit(void);
365
adamdunkels50b3feb2004-07-04 15:04:56 +0000366
367void mtp_eventhandler(ek_event_t ev, ek_data_t data);
368
adamdunkels12860b02004-08-20 21:27:42 +0000369/** @} */
adamdunkels50b3feb2004-07-04 15:04:56 +0000370/** @} */
371#endif /* __MT_H__ */
372