Contiki 2.5
mtarch.c
1 /*
2  * Copyright (c) 2007, 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: Oliver Schmidt <ol.sc@web.de>
32  *
33  * $Id: mtarch.c,v 1.2 2007/04/03 18:37:15 oliverschmidt Exp $
34  */
35 
36 #if defined(_WIN32) || defined(__CYGWIN__)
37 
38 #define WIN32_LEAN_AND_MEAN
39 #include <windows.h>
40 
41 static void *main_fiber;
42 
43 #else /* _WIN32 || __CYGWIN__ */
44 
45 #include <stdlib.h>
46 #include <signal.h>
47 #include <ucontext.h>
48 
49 struct mtarch_t {
50  char stack[4096];
51  ucontext_t context;
52 };
53 
54 static ucontext_t main_context;
55 static ucontext_t *running_context;
56 
57 #endif /* _WIN32 || __CYGWIN__ */
58 
59 #include "mtarch.h"
60 
61 /*--------------------------------------------------------------------------*/
62 void
64 {
65 #if defined(_WIN32) || defined(__CYGWIN__)
66 
67  main_fiber = ConvertThreadToFiber(NULL);
68 
69 #endif /* _WIN32 || __CYGWIN__ */
70 }
71 /*--------------------------------------------------------------------------*/
72 void
74 {
75 #if defined(_WIN32) || defined(__CYGWIN__)
76 
77  ConvertFiberToThread();
78 
79 #endif /* _WIN32 || __CYGWIN__ */
80 }
81 /*--------------------------------------------------------------------------*/
82 void
83 mtarch_start(struct mtarch_thread *thread,
84  void (* function)(void *data),
85  void *data)
86 {
87 #if defined(_WIN32) || defined(__CYGWIN__)
88 
89  thread->mt_thread = CreateFiber(0, (LPFIBER_START_ROUTINE)function, data);
90 
91 #else /* _WIN32 || __CYGWIN__ */
92 
93  thread->mt_thread = malloc(sizeof(struct mtarch_t));
94 
95  getcontext(&((struct mtarch_t *)thread->mt_thread)->context);
96 
97  ((struct mtarch_t *)thread->mt_thread)->context.uc_link = NULL;
98  ((struct mtarch_t *)thread->mt_thread)->context.uc_stack.ss_sp =
99  ((struct mtarch_t *)thread->mt_thread)->stack;
100  ((struct mtarch_t *)thread->mt_thread)->context.uc_stack.ss_size =
101  sizeof(((struct mtarch_t *)thread->mt_thread)->stack);
102 
103  /* Some notes:
104  - If a CPU needs stronger alignment for the stack than malloc()
105  guarantees (like i.e. IA64) then makecontext() is supposed to
106  add that alignment internally.
107  - According to POSIX the arguments to function() are of type int
108  and there are in fact 64-bit implementations which support only
109  32 bits per argument meaning that a pointer argument has to be
110  splitted into two arguments.
111  - Most implementations interpret context.uc_stack.ss_sp on entry
112  as the lowest stack address even if the CPU stack actually grows
113  downwards. Although this means that ss_sp does NOT represent the
114  CPU stack pointer this behaviour makes perfectly sense as it is
115  the only way to stay independent from the CPU architecture. But
116  Solaris prior to release 10 interprets ss_sp as highest stack
117  address thus requiring special handling. */
118  makecontext(&((struct mtarch_t *)thread->mt_thread)->context,
119  (void (*)(void))function, 1, data);
120 
121 #endif /* _WIN32 || __CYGWIN__ */
122 }
123 /*--------------------------------------------------------------------------*/
124 void
126 {
127 #if defined(_WIN32) || defined(__CYGWIN__)
128 
129  SwitchToFiber(main_fiber);
130 
131 #else /* _WIN32 || __CYGWIN__ */
132 
133  swapcontext(running_context, &main_context);
134 
135 #endif /* _WIN32 || __CYGWIN__ */
136 }
137 /*--------------------------------------------------------------------------*/
138 void
139 mtarch_exec(struct mtarch_thread *thread)
140 {
141 #if defined(_WIN32) || defined(__CYGWIN__)
142 
143  SwitchToFiber(thread->mt_thread);
144 
145 #else /* _WIN32 || __CYGWIN__ */
146 
147  running_context = &((struct mtarch_t *)thread->mt_thread)->context;
148  swapcontext(&main_context, running_context);
149  running_context = NULL;
150 
151 #endif /* _WIN32 || __CYGWIN__ */
152 }
153 /*--------------------------------------------------------------------------*/
154 void
155 mtarch_stop(struct mtarch_thread *thread)
156 {
157 #if defined(_WIN32) || defined(__CYGWIN__)
158 
159  DeleteFiber(thread->mt_thread);
160 
161 #else /* _WIN32 || __CYGWIN__ */
162 
163  free(thread->mt_thread);
164 
165 #endif /* _WIN32 || __CYGWIN__ */
166 }
167 /*--------------------------------------------------------------------------*/
168 void
169 mtarch_pstart(void)
170 {
171 }
172 /*--------------------------------------------------------------------------*/
173 void
174 mtarch_pstop(void)
175 {
176 }
177 /*--------------------------------------------------------------------------*/