Uncommented beaudio code
[pwlib.git] / src / ptlib / unix / switch.cxx
blob731afeba3148293e2bd82547eaa4ae24add314ef
1 /*
2 * switch.cxx
4 * Cooperative multi-threading stack switch function.
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
29 * $Log$
30 * Revision 1.23 2003/01/06 18:41:08 rogerh
31 * Add NetBSD patches, taken from the NetBSD pkg patches.
32 * Submitted by Andreas Wrede
34 * Revision 1.22 2002/10/10 04:43:44 robertj
35 * VxWorks port, thanks Martijn Roest
37 * Revision 1.21 2001/08/11 15:38:43 rogerh
38 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
40 * Revision 1.20 2000/03/08 12:17:09 rogerh
41 * Add OpenBSD support
43 * Revision 1.19 1999/05/12 02:12:02 robertj
44 * Fixed stack size on alpha
46 * Revision 1.18 1999/05/01 11:29:20 robertj
47 * Alpha linux port changes.
49 * Revision 1.17 1999/03/05 07:03:27 robertj
50 * Some more BeOS port changes.
52 * Revision 1.16 1999/02/22 13:26:54 robertj
53 * BeOS port changes.
55 * Revision 1.15 1998/12/21 06:50:36 robertj
56 * Linux PPC support
58 * Revision 1.14 1998/12/04 12:21:14 robertj
59 * FreeBSD support
61 * Revision 1.13 1998/11/05 09:04:16 craigs
62 * Changed free to runtime_free
64 * Revision 1.12 1998/09/24 04:12:21 robertj
65 * Added open software license.
69 #include <ptlib.h>
71 #if !defined(P_PTHREADS) && !defined(BE_THREADS) && !defined(P_MAC_MPTHREADS) && !defined(VX_TASKS)
73 #ifdef P_LINUX
74 #ifdef PPC
75 #define SET_STACK context[0].__jmpbuf[0].__misc[0] = (long int)stackTop-16;
76 #define STACK_MULT 4
77 #else
78 #ifdef JB_SP
79 #define SET_STACK context[0].__jmpbuf[JB_SP] = (INT)stackTop-16;
80 #else
81 #define SET_STACK context[0].__sp = (__ptr_t)stackTop-16;
82 #endif
83 #ifdef P_64BIT
84 #define STACK_MULT 5
85 #else
86 #include <sys/mman.h>
87 #define USE_MMAP MAP_ANON | MAP_PRIVATE
88 #endif
89 #endif
90 #endif
92 #if defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD)
93 #define SET_STACK context[0]._jb[2] = (int)stackTop-16;
94 #if defined(P_NETBSD)
95 #include <sys/mman.h>
96 #define USE_MMAP MAP_ANON | MAP_PRIVATE
97 #endif
98 #endif
100 #ifdef __BEOS__
101 #define SET_STACK context[0].__jmpbuf[JB_SP] = (int)stackTop-16;
102 #endif
104 #ifdef P_SUN4
105 #define SETJMP_PROLOG __asm__ ("ta 3");
106 #define SET_STACK context[2] = ((int)stackTop-1024) & ~7;
107 #endif
109 #ifdef P_SOLARIS
110 #define SETJMP_PROLOG __asm__ ("ta 3");
111 #define SET_STACK context[1] = ((int)stackTop-1024) & ~7;
112 #define STACK_MULT 4
113 //#define USE_MMAP MAP_PRIVATE | MAP_NORESERVE
114 #include <sys/mman.h>
115 #endif
117 #ifdef P_HPUX
118 #define SET_STACK context[1] = (int)(stackBase+64*2);
119 #endif
121 #ifdef P_ULTRIX
122 #define SET_STACK context[JB_SP] = (int)(stackTop-16);
123 #endif
125 #ifndef SETJMP_PROLOG
126 #define SETJMP_PROLOG
127 #endif
129 #ifndef STACK_MIN
130 #define STACK_MIN 10240
131 #endif
133 #ifndef STACK_MULT
134 #define STACK_MULT 1
135 #endif
137 static PThread * localThis;
139 void PThread::SwitchContext(PThread * from)
142 // no need to switch to ourselves
144 if (this == from)
145 return;
147 #ifdef SET_STACK
149 // save context for old thread
150 SETJMP_PROLOG
151 if (setjmp(from->context) != 0) // Are being reactivated from previous yield
152 return;
154 // if starting the current thread, create a context, give it a new stack
155 // and then switch to it.
156 // if we have just switched into a new thread, execute the BeginThread
157 // function
158 if (status == Starting) {
159 localThis = this;
160 SETJMP_PROLOG
161 if (setjmp(context) != 0) { // Are being reactivated from previous yield
162 localThis->BeginThread();
163 PAssertAlways("Return from BeginThread not allowed");
165 SET_STACK
168 // switch to the new thread
169 longjmp(context, TRUE);
170 PAssertAlways("Return from longjmp not allowed");
172 #else
174 #warning No lightweight thread context switch mechanism defined
175 PAssertAlways("SwitchContext() not implemented");
177 #endif
181 void PThread::AllocateStack(PINDEX stackProtoSize)
183 int stackSize = STACK_MULT*PMAX(STACK_MIN, stackProtoSize);
185 #if defined(USE_MMAP)
186 stackBase = (char *)mmap(0,
187 stackSize,
188 PROT_READ | PROT_WRITE,
189 USE_MMAP,
190 -1, 0);
191 PAssert(stackBase != (char *)-1, "Cannot allocate virtual stack for thread");
192 #else
193 stackBase = (char *)malloc(stackSize);
194 PAssert(stackBase != NULL, "Cannot allocate stack for thread");
195 #endif
196 stackTop = stackBase + stackSize-1;
199 void PThread::FreeStack()
201 if (stackBase != NULL)
202 #if defined(USE_MMAP)
203 munmap(stackBase, stackTop-stackBase+1);
204 #else
205 free(stackBase);
206 #endif
209 #endif // !P_PTHREADS && !BE_THREADS