Merge threads directory into libguile.
[bpt/guile.git] / libguile / mit-pthreads.h
1 /* classes: h_files */
2
3 #ifndef MIT_PTHREADSH
4 #define MIT_PTHREADSH
5
6 /* Copyright (C) 1996 Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this software; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * As a special exception, the Free Software Foundation gives permission
23 * for additional uses of the text contained in its release of GUILE.
24 *
25 * The exception is that, if you link the GUILE library with other files
26 * to produce an executable, this does not by itself cause the
27 * resulting executable to be covered by the GNU General Public License.
28 * Your use of that executable is in no way restricted on account of
29 * linking the GUILE library code into it.
30 *
31 * This exception does not however invalidate any other reasons why
32 * the executable file might be covered by the GNU General Public License.
33 *
34 * This exception applies only to the code released by the
35 * Free Software Foundation under the name GUILE. If you copy
36 * code from other Free Software Foundation releases into a copy of
37 * GUILE, as the General Public License permits, the exception does
38 * not apply to the code that you add in this way. To avoid misleading
39 * anyone as to the status of such modified files, you must delete
40 * this exception notice from them.
41 *
42 * If you write modifications of your own for GUILE, it is your choice
43 * whether to permit this exception to apply to your modifications.
44 * If you do not wish that, delete this exception notice.
45 */
46 \f
47
48 #include "libguile/__scm.h"
49
50 #define PTHREAD_KERNEL
51 #include <pthread.h>
52
53 /* Identify where the stack pointer can be found in a jmpbuf.
54 */
55
56 /* Solaris 2.4 */
57 #if defined(__sparc_setjmp_h)
58 # define THREAD_SP machdep_data.machdep_state[2]
59 #endif
60
61 /* Solaris 2.5 */
62 #if defined(__sparc)
63 #ifndef THREAD_SP
64 # define THREAD_SP machdep_data.machdep_state[2]
65 #endif
66 #endif
67
68 #if defined(linux)
69 # define THREAD_SP machdep_data.machdep_state[0].__sp
70 #endif
71
72 #if defined(sgi)
73 # define THREAD_SP machdep_data.machdep_state[JB_SP]
74 #endif
75
76 /* ...define THREAD_SP for your architecture here...
77 */
78
79 #if !defined(THREAD_SP)
80 --> where is your stack pointer?
81 #endif
82
83 \f
84
85 /* Boost the priority of this thread so that it is the only
86 one running. PTHREAD_MAX_PRIORITY is reserved for this
87 purpose */
88
89 #define SCM_THREAD_CRITICAL_SECTION_START \
90 struct sched_param param; \
91 int previous_prio; \
92 int policy; \
93 pthread_getschedparam(pthread_self(), &policy, &param); \
94 previous_prio = param.prio; \
95 param.prio = PTHREAD_MAX_PRIORITY; \
96 pthread_setschedparam(pthread_self(), policy, &param)
97
98 #define SCM_THREAD_CRITICAL_SECTION_END \
99 param.prio = previous_prio; \
100 pthread_setschedparam(pthread_self(), policy, &param)
101
102 \f
103
104 #if 1
105
106 #define SCM_NO_CRITICAL_SECTION_OWNER 0
107
108 #define SCM_THREAD_DEFER pthread_kernel_lock++
109 #define SCM_THREAD_ALLOW pthread_kernel_lock--
110
111 #define SCM_THREAD_REDEFER pthread_kernel_lock++
112 #define SCM_THREAD_REALLOW_1 pthread_kernel_lock--
113 #define SCM_THREAD_REALLOW_2 \
114 { \
115 scm_critical_section_owner = SCM_NO_CRITICAL_SECTION_OWNER; \
116 pthread_mutex_unlock(&scm_critical_section_mutex); \
117 }
118
119 #else
120
121 #define SCM_NO_CRITICAL_SECTION_OWNER 0
122
123 #define SCM_THREAD_DEFER \
124 { \
125 pthread_mutex_lock (&scm_critical_section_mutex); \
126 scm_critical_section_owner = pthread_self(); \
127 }
128
129 #define SCM_THREAD_ALLOW \
130 { \
131 scm_critical_section_owner = SCM_NO_CRITICAL_SECTION_OWNER; \
132 pthread_mutex_unlock (&scm_critical_section_mutex); \
133 }
134
135 #define SCM_THREAD_REDEFER \
136 { \
137 if ((scm_critical_section_owner != pthread_self()) || \
138 (scm_critical_section_owner == SCM_NO_CRITICAL_SECTION_OWNER)) \
139 { \
140 pthread_mutex_lock(&scm_critical_section_mutex); \
141 scm_critical_section_owner = pthread_self(); \
142 } \
143 }
144
145 #define SCM_THREAD_REALLOW_1
146 #define SCM_THREAD_REALLOW_2 \
147 { \
148 scm_critical_section_owner = SCM_NO_CRITICAL_SECTION_OWNER; \
149 pthread_mutex_unlock (&scm_critical_section_mutex); \
150 }
151
152 #endif
153
154 #define SCM_THREAD_SWITCHING_CODE
155
156 #define SCM_THREAD_LOCAL_DATA (pthread_self () -> attr.arg_attr)
157 #define SCM_SET_THREAD_LOCAL_DATA(new_root) \
158 { \
159 pthread_t t = pthread_self (); \
160 void *r = (new_root); \
161 pthread_attr_setcleanup (&t -> attr, NULL, r); \
162 pthreads_find_info (t) -> root = r; \
163 }
164
165
166 \f
167
168 void scm_threads_init_mit_pthreads ();
169
170 typedef struct QUEUE {
171 struct QUEUE *flink, *blink;
172 } queue;
173
174 extern pthread_mutex_t scm_critical_section_mutex;
175 extern pthread_t scm_critical_section_owner;
176
177 /* Key to thread specific data */
178 extern pthread_key_t info_key;
179
180 struct scm_pthread_create_info_type
181 {
182 SCM thunk;
183 SCM error;
184 SCM *prots;
185 } scm_pthread_create_info;
186
187 #endif /* MIT_PTHREADSH */