Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Examples

mt.c

Go to the documentation of this file.
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.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $
00034  */
00035 
00036 /**
00037  * \file
00038  * Implementation of the archtecture agnostic parts of the preemptive
00039  * multithreading library for Contiki.
00040  *
00041  * \author
00042  * Adam Dunkels <adam@sics.se>
00043  *
00044  */
00045 
00046 #include "contiki.h"
00047 #include "sys/mt.h"
00048 #include "sys/cc.h"
00049 
00050 #define MT_STATE_READY   1
00051 #define MT_STATE_RUNNING 2
00052 #define MT_STATE_WAITING 3
00053 #define MT_STATE_PEEK    4
00054 #define MT_STATE_EXITED  5
00055 
00056 static struct mt_thread *current;
00057 
00058 /*--------------------------------------------------------------------------*/
00059 void
00060 mt_init(void)
00061 {
00062   mtarch_init();
00063 }
00064 /*--------------------------------------------------------------------------*/
00065 void
00066 mt_remove(void)
00067 {
00068   mtarch_remove();
00069 }
00070 /*--------------------------------------------------------------------------*/
00071 void
00072 mt_start(struct mt_thread *thread, void (* function)(void *), void *data)
00073 {
00074   /* Call the architecture dependant function to set up the processor
00075      stack with the correct parameters. */
00076   mtarch_start(&thread->thread, function, data);
00077 
00078   thread->state = MT_STATE_READY;
00079 }
00080 /*--------------------------------------------------------------------------*/
00081 void
00082 mt_exec(struct mt_thread *thread)
00083 {
00084   if(thread->state == MT_STATE_READY ||
00085      thread->state == MT_STATE_PEEK) {
00086     thread->state = MT_STATE_RUNNING;
00087     current = thread;
00088     /* Switch context to the thread. The function call will not return
00089        until the the thread has yielded, or is preempted. */
00090     /*printf("swtis\n");*/
00091     mtarch_exec(&thread->thread);
00092   }
00093 }
00094 /*--------------------------------------------------------------------------*/
00095 void
00096 mt_exit(void)
00097 {
00098   current->state = MT_STATE_EXITED;
00099   current = NULL;
00100   mtarch_yield();
00101 }
00102 /*--------------------------------------------------------------------------*/
00103 void
00104 mt_exec_event(struct mt_thread *thread, process_event_t ev,
00105               process_data_t data)
00106 {
00107   if(thread->state == MT_STATE_WAITING ||
00108      thread->state == MT_STATE_PEEK) {
00109     *(thread->evptr) = ev;
00110     *(thread->dataptr) = data;
00111     thread->state = MT_STATE_RUNNING;
00112     current = thread;
00113     /* Switch context to the thread. The function call will not return
00114        until the the thread has yielded, or is preempted. */
00115     mtarch_exec(&thread->thread);
00116   }
00117 }
00118 /*--------------------------------------------------------------------------*/
00119 void
00120 mt_yield(void)
00121 {
00122   mtarch_pstop();
00123   current->state = MT_STATE_READY;
00124   current = NULL;
00125   /* This function is called from the running thread, and we call the
00126      switch function in order to switch the thread to the main Contiki
00127      program instead. For us, the switch function will not return
00128      until the next time we are scheduled to run. */
00129   mtarch_yield();
00130   
00131 }
00132 /*--------------------------------------------------------------------------*/
00133 void
00134 mt_post(struct process *p, process_event_t ev,
00135         process_data_t data)
00136 {
00137   /* Turn off preemption to ensure mutual exclusion of kernel. */
00138   mtarch_pstop();
00139 
00140   process_post(p, ev, data);
00141   
00142   /* Turn preemption on again. */
00143   mtarch_pstart();
00144 }
00145 /*--------------------------------------------------------------------------*/
00146 void
00147 mt_wait(process_event_t *ev, process_data_t *data)
00148 {
00149   mtarch_pstop();
00150   current->evptr = ev;
00151   current->dataptr = data;
00152   current->state = MT_STATE_WAITING;
00153   current = NULL;
00154   mtarch_yield();
00155 }
00156 /*--------------------------------------------------------------------------*/
00157 void
00158 mt_peek(process_event_t *ev, process_data_t *data)
00159 {
00160   mtarch_pstop();
00161   *ev = PROCESS_EVENT_NONE;
00162   current->evptr = ev;
00163   current->dataptr = data;
00164   current->state = MT_STATE_PEEK;
00165   current = NULL;
00166   mtarch_yield();
00167 }
00168 /*--------------------------------------------------------------------------*/
00169 void
00170 mtp_start(struct mt_process *t,
00171           void (* function)(void *), void *data)
00172 {
00173   mt_start(&t->t, function, data);
00174   process_start(t->p, function);
00175 }
00176 /*--------------------------------------------------------------------------*/
00177 void
00178 mtp_exit(void)
00179 {
00180   mtarch_pstop();
00181   mt_exit();
00182   mt_remove();
00183 }
00184 /*--------------------------------------------------------------------------*/
00185 /*void
00186 mtp_eventhandler(ek_event_t ev, ek_data_t data)
00187 {
00188   struct mtp_thread *thread = (struct mtp_thread *)EK_PROC_STATE(EK_CURRENT());
00189 
00190   if(ev == EK_EVENT_REQUEST_EXIT) {
00191     ek_exit();
00192     LOADER_UNLOAD();
00193     
00194   } else if(ev == EK_EVENT_INIT) {
00195     
00196     ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL);
00197     
00198   } else if(ev == EK_EVENT_CONTINUE) {
00199 
00200     if(thread->t.state == MT_STATE_READY ||
00201        thread->t.state == MT_STATE_PEEK) {
00202       mt_exec(&thread->t);
00203       if(thread->t.state == MT_STATE_EXITED) {
00204         ek_exit();
00205         LOADER_UNLOAD();
00206       } else {
00207         ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL);
00208       }
00209     }
00210   } else {
00211     mt_exec_event(&thread->t, ev, data);
00212     if(thread->t.state == MT_STATE_EXITED) {
00213       ek_exit();
00214       LOADER_UNLOAD();
00215     } else if(thread->t.state == MT_STATE_READY ||
00216               thread->t.state == MT_STATE_PEEK) {
00217       ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL);
00218     }
00219   }
00220 }*/
00221 /*--------------------------------------------------------------------------*/

Generated on Thu Jun 22 17:45:43 2006 for Contiki 2.x by  doxygen 1.4.4