2 * Copyright (c) 2007, Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
29 * This file is part of the Contiki operating system.
31 * Author: Oliver Schmidt <ol.sc@web.de>
33 * $Id: mtarch.c,v 1.2 2007/04/03 18:37:15 oliverschmidt Exp $
38 #define WIN32_LEAN_AND_MEAN
41 static void *main_fiber
;
43 #else /* __CYGWIN__ */
54 static ucontext_t main_context
;
55 static ucontext_t
*running_context
;
57 #endif /* __CYGWIN__ */
61 /*--------------------------------------------------------------------------*/
67 main_fiber
= ConvertThreadToFiber(NULL
);
69 #endif /* __CYGWIN__ */
71 /*--------------------------------------------------------------------------*/
77 ConvertFiberToThread();
79 #endif /* __CYGWIN__ */
81 /*--------------------------------------------------------------------------*/
83 mtarch_start(struct mtarch_thread
*thread
,
84 void (* function
)(void *data
),
89 thread
->mt_thread
= CreateFiber(0, (LPFIBER_START_ROUTINE
)function
, data
);
91 #else /* __CYGWIN__ */
93 thread
->mt_thread
= malloc(sizeof(struct mtarch_t
));
95 getcontext(&((struct mtarch_t
*)thread
->mt_thread
)->context
);
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
);
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
);
121 #endif /* __CYGWIN__ */
123 /*--------------------------------------------------------------------------*/
129 SwitchToFiber(main_fiber
);
131 #else /* __CYGWIN__ */
133 swapcontext(running_context
, &main_context
);
135 #endif /* __CYGWIN__ */
137 /*--------------------------------------------------------------------------*/
139 mtarch_exec(struct mtarch_thread
*thread
)
143 SwitchToFiber(thread
->mt_thread
);
145 #else /* __CYGWIN__ */
147 running_context
= &((struct mtarch_t
*)thread
->mt_thread
)->context
;
148 swapcontext(&main_context
, running_context
);
149 running_context
= NULL
;
151 #endif /* __CYGWIN__ */
153 /*--------------------------------------------------------------------------*/
155 mtarch_stop(struct mtarch_thread
*thread
)
159 DeleteFiber(thread
->mt_thread
);
161 #else /* __CYGWIN__ */
163 free(thread
->mt_thread
);
165 #endif /* __CYGWIN__ */
167 /*--------------------------------------------------------------------------*/
172 /*--------------------------------------------------------------------------*/
177 /*--------------------------------------------------------------------------*/