]>
Commit | Line | Data |
---|---|---|
e9ce8d39 A |
1 | /* |
2 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 | |
3 | * All Rights Reserved | |
4 | * | |
5 | * Permission to use, copy, modify, and distribute this software and | |
6 | * its documentation for any purpose and without fee is hereby granted, | |
7 | * provided that the above copyright notice appears in all copies and | |
8 | * that both the copyright notice and this permission notice appear in | |
9 | * supporting documentation. | |
10 | * | |
11 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE | |
12 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
13 | * FOR A PARTICULAR PURPOSE. | |
14 | * | |
15 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR | |
16 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | |
17 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, | |
18 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | |
19 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
20 | * | |
21 | */ | |
22 | /* | |
23 | * MkLinux | |
24 | */ | |
25 | ||
26 | /* | |
27 | * POSIX Threads - IEEE 1003.1c | |
28 | */ | |
29 | ||
30 | #ifndef _POSIX_PTHREAD_INTERNALS_H | |
31 | #define _POSIX_PTHREAD_INTERNALS_H | |
32 | ||
33 | ||
34 | #include <assert.h> | |
35 | #include <mach/port.h> | |
36 | #include <mach/mach_error.h> | |
37 | #include <mach/message.h> | |
38 | #include <mach/machine/vm_types.h> | |
39 | #include <mach/std_types.h> | |
40 | #include <mach/policy.h> | |
41 | #include <mach/sync.h> | |
42 | #include <mach/sync_policy.h> | |
43 | #include <mach/mach_traps.h> | |
44 | #include <mach/thread_switch.h> | |
45 | #include <mach/mach_host.h> | |
46 | #include <mach/mach.h> /* For generic MACH support */ | |
47 | ||
48 | ||
49 | #ifndef __POSIX_LIB__ | |
50 | #define __POSIX_LIB__ | |
51 | #endif | |
52 | ||
53 | #include "posix_sched.h" /* For POSIX scheduling policy & parameter */ | |
54 | #include "pthread_machdep.h" /* Machine-dependent definitions. */ | |
55 | ||
56 | extern kern_return_t syscall_thread_switch(mach_port_name_t, int, mach_msg_timeout_t); | |
57 | ||
58 | /* | |
59 | * Compiled-in limits | |
60 | */ | |
61 | #undef _POSIX_THREAD_KEYS_MAX | |
62 | #define _POSIX_THREAD_KEYS_MAX 128 | |
63 | ||
64 | /* | |
65 | * Threads | |
66 | */ | |
67 | typedef struct _pthread | |
68 | { | |
69 | long sig; /* Unique signature for this structure */ | |
70 | struct _pthread_handler_rec *cleanup_stack; | |
71 | pthread_lock_t lock; /* Used for internal mutex on structure */ | |
72 | int detached; | |
73 | int inherit; | |
74 | int policy; | |
75 | struct sched_param param; | |
76 | struct _pthread_mutex *mutexes; | |
77 | mach_port_t joiners; /* pthread_join() uses this to wait for death's call */ | |
78 | int num_joiners; | |
79 | void *exit_value; | |
80 | mach_port_t death; /* pthread_exit() uses this to wait for the hearse */ | |
81 | mach_port_t kernel_thread; /* kernel thread this thread is bound to */ | |
82 | void *(*fun)(void*);/* Thread start routine */ | |
83 | void *arg; /* Argment for thread start routine */ | |
84 | int cancel_state; /* Whether thread can be cancelled */ | |
85 | int err_no; /* thread-local errno */ | |
86 | void *tsd[_POSIX_THREAD_KEYS_MAX]; /* Thread specific data */ | |
87 | void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ | |
88 | size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ | |
89 | mach_port_t reply_port; /* Cached MiG reply port */ | |
90 | void *cthread_self; /* cthread_self() if somebody calls cthread_set_self() */ | |
91 | boolean_t freeStackOnExit;/* Should we free the stack when we're done? */ | |
92 | } *pthread_t; | |
93 | ||
94 | ||
95 | /* | |
96 | * Thread attributes | |
97 | */ | |
98 | typedef struct | |
99 | { | |
100 | long sig; /* Unique signature for this structure */ | |
101 | pthread_lock_t lock; /* Used for internal mutex on structure */ | |
102 | int detached; | |
103 | int inherit; | |
104 | int policy; | |
105 | struct sched_param param; | |
106 | void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ | |
107 | size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ | |
108 | boolean_t freeStackOnExit;/* Should we free the stack when we exit? */ | |
109 | } pthread_attr_t; | |
110 | ||
111 | /* | |
112 | * Mutex attributes | |
113 | */ | |
114 | typedef struct | |
115 | { | |
116 | long sig; /* Unique signature for this structure */ | |
117 | int prioceiling; | |
118 | int protocol; | |
119 | } pthread_mutexattr_t; | |
120 | ||
121 | /* | |
122 | * Mutex variables | |
123 | */ | |
124 | typedef struct _pthread_mutex | |
125 | { | |
126 | long sig; /* Unique signature for this structure */ | |
127 | pthread_lock_t lock; /* Used for internal mutex on structure */ | |
128 | int prioceiling; | |
129 | int priority; /* Priority to restore when mutex unlocked */ | |
130 | int protocol; | |
131 | pthread_t owner; /* Which thread has this mutex locked */ | |
132 | struct _pthread_mutex *next, *prev; /* List of other mutexes he owns */ | |
133 | struct _pthread_cond *busy; /* List of condition variables using this mutex */ | |
134 | int waiters:31, /* Count of threads waiting for this mutex */ | |
135 | cond_lock:1; /* Is there a condition locking me? */ | |
136 | mach_port_t sem; /* Semaphore used for waiting */ | |
137 | } pthread_mutex_t; | |
138 | ||
139 | /* | |
140 | * Condition variable attributes | |
141 | */ | |
142 | typedef struct | |
143 | { | |
144 | long sig; /* Unique signature for this structure */ | |
145 | int unsupported; | |
146 | } pthread_condattr_t; | |
147 | ||
148 | /* | |
149 | * Condition variables | |
150 | */ | |
151 | typedef struct _pthread_cond | |
152 | { | |
153 | long sig; /* Unique signature for this structure */ | |
154 | pthread_lock_t lock; /* Used for internal mutex on structure */ | |
155 | mach_port_t sem; /* Kernel semaphore */ | |
156 | struct _pthread_cond *next, *prev; /* List of condition variables using mutex */ | |
157 | struct _pthread_mutex *busy; /* mutex associated with variable */ | |
158 | int waiters:16, /* Number of threads waiting */ | |
159 | sigspending:16; /* Number of outstanding signals */ | |
160 | } pthread_cond_t; | |
161 | ||
162 | /* | |
163 | * Initialization control (once) variables | |
164 | */ | |
165 | typedef struct | |
166 | { | |
167 | long sig; /* Unique signature for this structure */ | |
168 | pthread_lock_t lock; /* Used for internal mutex on structure */ | |
169 | } pthread_once_t; | |
170 | ||
171 | #include "pthread.h" | |
172 | ||
173 | #define _PTHREAD_DEFAULT_INHERITSCHED PTHREAD_INHERIT_SCHED | |
174 | #define _PTHREAD_DEFAULT_PROTOCOL PTHREAD_PRIO_NONE | |
175 | #define _PTHREAD_DEFAULT_PRIOCEILING 0 | |
176 | #define _PTHREAD_DEFAULT_POLICY SCHED_OTHER | |
177 | #define _PTHREAD_DEFAULT_STACKSIZE 0x80000 /* 512K */ | |
178 | ||
179 | #define _PTHREAD_NO_SIG 0x00000000 | |
180 | #define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */ | |
181 | #define _PTHREAD_MUTEX_SIG 0x4D555458 /* 'MUTX' */ | |
182 | #define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 /* [almost] ~'MUTX' */ | |
183 | #define _PTHREAD_COND_SIG 0x434F4E44 /* 'COND' */ | |
184 | #define _PTHREAD_COND_SIG_init 0x3CB0B1BB /* [almost] ~'COND' */ | |
185 | #define _PTHREAD_ATTR_SIG 0x54484441 /* 'THDA' */ | |
186 | #define _PTHREAD_ONCE_SIG 0x4F4E4345 /* 'ONCE' */ | |
187 | #define _PTHREAD_ONCE_SIG_init 0x30B1BCBA /* [almost] ~'ONCE' */ | |
188 | #define _PTHREAD_SIG 0x54485244 /* 'THRD' */ | |
189 | ||
190 | #define _PTHREAD_EXITED 3 | |
191 | #define _PTHREAD_CREATE_PARENT 4 | |
192 | ||
193 | #define _PTHREAD_CANCEL_STATE_MASK 0xFE | |
194 | #define _PTHREAD_CANCEL_TYPE_MASK 0xFD | |
195 | #define _PTHREAD_CANCEL_PENDING 0x10 /* pthread_cancel() has been called for this thread */ | |
196 | ||
197 | extern boolean_t swtch_pri(int); | |
198 | ||
199 | /* Number of times to spin when the lock is unavailable and we are on a | |
200 | multiprocessor. On a uniprocessor we yield the processor immediately. */ | |
201 | #define SPIN_TRIES 10 | |
202 | extern int _spin_tries; | |
203 | extern int __is_threaded; | |
204 | extern int _cpu_has_altivec; | |
205 | ||
206 | /* Internal mutex locks for data structures */ | |
207 | #define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&v)) | |
208 | #if 0 | |
209 | #define LOCK(v) if (__is_threaded) _spin_lock((pthread_lock_t)&v) | |
210 | #else | |
211 | #define LOCK(v) \ | |
212 | if (__is_threaded) { \ | |
213 | while (!_spin_lock_try((pthread_lock_t *)&v)) { \ | |
214 | syscall_thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, 1); \ | |
215 | } \ | |
216 | } | |
217 | #endif | |
218 | #define UNLOCK(v) if (__is_threaded) _spin_unlock((pthread_lock_t *)&v) | |
219 | #ifndef ESUCCESS | |
220 | #define ESUCCESS 0 | |
221 | #endif | |
222 | ||
223 | #ifndef PTHREAD_MACH_CALL | |
224 | #define PTHREAD_MACH_CALL(expr, ret) (ret) = (expr) | |
225 | #endif | |
226 | ||
227 | /* Prototypes. */ | |
228 | ||
229 | /* Functions defined in machine-dependent files. */ | |
230 | extern vm_address_t _sp(void); | |
231 | extern vm_address_t _adjust_sp(vm_address_t sp); | |
232 | extern void _spin_lock(pthread_lock_t *lockp); | |
233 | extern int _spin_lock_try(pthread_lock_t *lockp); | |
234 | extern void _spin_unlock(pthread_lock_t *lockp); | |
235 | extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), vm_address_t sp); | |
236 | ||
237 | extern void _pthread_tsd_cleanup(pthread_t self); | |
238 | ||
239 | __private_extern__ semaphore_t new_sem_from_pool(void); | |
240 | __private_extern__ void restore_sem_to_pool(semaphore_t); | |
241 | #endif /* _POSIX_PTHREAD_INTERNALS_H */ |