source: trunk/source/lisp-kernel/threads.h @ 15473

Last change on this file since 15473 was 15473, checked in by gb, 8 years ago

Ensure that darwin_sigreturn() is prototyped on platforms where it's
used.

Remove some remaining Mach-isms (notably the paging info stuff used
by GC-VERBOSE; just use getrusage()).

Make sure that the right headers are included in threads.h, to support
the remaining Mach-ism (use of Mach semaphores. Apple still doesn't
implement POSIX semaphores, though the functions have been prototyped
for several years now.)

This builds without warnings or errors on 10.8.1 with Xcode 4.4's
toolchain. It -may- address the problems described in ticket:1019.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/*
2   Copyright (C) 2009 Clozure Associates
3   Copyright (C) 1994-2001 Digitool, Inc
4   This file is part of Clozure CL. 
5
6   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
7   License , known as the LLGPL and distributed with Clozure CL as the
8   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
9   which is distributed with Clozure CL as the file "LGPL".  Where these
10   conflict, the preamble takes precedence. 
11
12   Clozure CL is referenced in the preamble as the "LIBRARY."
13
14   The LLGPL is also available online at
15   http://opensource.franz.com/preamble.html
16*/
17
18#include <stdlib.h>
19#ifndef WINDOWS
20#include <unistd.h>
21#include <sys/mman.h>
22#endif
23#undef __argv
24#include <stdio.h>
25#ifndef WINDOWS
26#include <pthread.h>
27#endif
28#ifdef WINDOWS
29#include <process.h>
30#endif
31#include <errno.h>
32#include <limits.h>
33
34#ifdef SOLARIS
35#include <sys/syscall.h>
36#include <sys/lwp.h>
37#endif
38
39#ifdef LINUX
40#include <sys/syscall.h>
41#endif
42
43#undef USE_MACH_SEMAPHORES
44#define USE_POSIX_SEMAPHORES
45#undef USE_WINDOWS_SEMAPHORES
46
47#ifdef DARWIN
48#define USE_MACH_SEMAPHORES 1
49#undef  USE_POSIX_SEMAPHORES
50#endif
51#ifdef WINDOWS
52#define USE_WINDOWS_SEMAPHORES 1
53#undef USE_POSIX_SEMAPHORES
54#ifdef NEED_TIMESPEC
55struct timespec {
56  int tv_sec;
57  int tv_nsec;
58};
59#endif
60#endif
61
62#ifdef USE_POSIX_SEMAPHORES
63#include <semaphore.h>
64#endif
65
66
67#ifdef USE_MACH_SEMAPHORES
68/* We have to use Mach semaphores, even if we're otherwise
69   using POSIX signals, etc. */
70#include <mach/mach_init.h>
71#include <mach/task.h>
72#include <mach/semaphore.h>
73#endif
74
75#include <limits.h>
76
77#ifdef FREEBSD
78#include <pthread_np.h>
79#endif
80
81#ifndef WINDOWS
82#ifndef ANDROID
83#include <sched.h>
84#endif
85#endif
86
87#include "lisp.h"
88#include "lisp_globals.h"
89#include "gc.h"
90
91#ifdef USE_FUTEX
92#ifndef FUTEX_WAIT
93#define FUTEX_WAIT (0)
94#endif
95#ifndef FUTEX_WAKE
96#define FUTEX_WAKE (1)
97#endif
98#include <sys/syscall.h>
99#endif
100
101#ifndef WINDOWS
102#include <syslog.h>
103#endif
104
105Boolean extern threads_initialized;
106Boolean extern log_tcr_info;
107
108#define LOCK_SPINLOCK(x,tcr) get_spin_lock(&(x),tcr)
109#define RELEASE_SPINLOCK(x) (x)=0
110
111#ifdef WIN_32
112#define TCR_TO_TSD(tcr) ((void *)((natural)(tcr)))
113#define TCR_FROM_TSD(tsd) ((TCR *)((natural)(tsd)))
114#else
115#define TCR_TO_TSD(tcr) ((void *)((natural)(tcr)+TCR_BIAS))
116#define TCR_FROM_TSD(tsd) ((TCR *)((natural)(tsd)-TCR_BIAS))
117#endif
118
119#ifdef USE_WINDOWS_SEMAPHORES
120
121typedef void * SEMAPHORE;
122#define SEM_WAIT(s) WaitForSingleObject(s,INFINITE)
123#define SEM_RAISE(s) ReleaseSemaphore(s, 1L, NULL)
124#define SEM_BROADCAST(s, count) do {while(count) {SEM_RAISE(s);(count)--;}}while(0)
125#define SEM_TIMEDWAIT(s,t) WaitOnSingleObject(s,t)
126
127#endif
128#ifdef USE_POSIX_SEMAPHORES
129typedef sem_t * SEMAPHORE;
130#define SEM_WAIT(s) sem_wait((SEMAPHORE)s)
131#define SEM_RAISE(s) sem_post((SEMAPHORE)s)
132#define SEM_BROADCAST(s, count) do {while(count) {SEM_RAISE(s);(count)--;}}while(0)
133#define SEM_TIMEDWAIT(s,t) sem_timedwait((SEMAPHORE)s,(struct timespec *)t)
134#endif
135
136#ifdef USE_MACH_SEMAPHORES
137typedef semaphore_t SEMAPHORE;
138#define SEM_WAIT(s) semaphore_wait((SEMAPHORE)(natural)s)
139#define SEM_RAISE(s) semaphore_signal((SEMAPHORE)(natural)s)
140#define SEM_BROADCAST(s,count)semaphore_signal_all((SEMAPHORE)(natural)s)
141#define SEM_TIMEDWAIT(s,t) semaphore_timedwait((SEMAPHORE)(natural)s,t)
142#endif
143
144void signal_semaphore(SEMAPHORE s);
145int wait_on_semaphore(void *s, int seconds, int millis);
146void sem_wait_forever(SEMAPHORE s);
147
148#ifdef USE_POSIX_SEMAPHORES
149#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)s)
150#endif
151
152#ifdef USE_MACH_SEMAPHORES
153#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)(natural)s)
154#endif
155
156#ifdef USE_WINDOWS_SEMAPHORES
157#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)s)
158#endif
159
160typedef struct
161{
162  signed_natural avail;
163  TCR* owner;
164  signed_natural  count;
165  void* signal;
166  signed_natural waiting;
167  void *malloced_ptr;
168  signed_natural spinlock;
169} _recursive_lock, *RECURSIVE_LOCK;
170
171
172int lock_recursive_lock(RECURSIVE_LOCK, TCR *);
173int unlock_recursive_lock(RECURSIVE_LOCK, TCR *);
174RECURSIVE_LOCK new_recursive_lock(void);
175void destroy_recursive_lock(RECURSIVE_LOCK);
176int recursive_lock_trylock(RECURSIVE_LOCK, TCR *, int *);
177
178#define LOCK(m, t) lock_recursive_lock((RECURSIVE_LOCK)ptr_from_lispobj(m), (TCR *)t)
179#define UNLOCK(m, t) unlock_recursive_lock((RECURSIVE_LOCK)ptr_from_lispobj(m), (TCR *)t)
180
181/* Hmm.  This doesn't look like the MacOS Thread Manager ... */
182LispObj current_thread_osid(void);
183void *current_native_thread_id(void);
184void *new_semaphore(int);
185void destroy_semaphore(void**);
186void tsd_set(LispObj, void *);
187void *tsd_get(LispObj);
188TCR *new_tcr(natural, natural);
189void thread_init_tcr(TCR *tcr, void *stack_base, natural stack_size);
190TCR *initial_thread_tcr;
191
192#define DEFAULT_THREAD_STACK_SIZE ((size_t) -1)
193#define MINIMAL_THREAD_STACK_SIZE ((size_t) 0)
194
195
196Boolean create_system_thread(size_t stack_size, 
197                             void* stackaddr,
198#ifdef WINDOWS
199                             unsigned CALLBACK (*start_routine)(void *)
200#else
201                             void* (*start_routine)(void *)
202#endif
203                             ,
204                             void* param);
205
206TCR *get_tcr(Boolean);
207TCR *get_interrupt_tcr(Boolean);
208
209Boolean suspend_tcr(TCR *);
210Boolean resume_tcr(TCR *);
211Boolean kill_tcr(TCR *);
212
213int raise_thread_interrupt(TCR *target);
214
215Boolean lisp_suspend_tcr(TCR *);
216Boolean lisp_resume_tcr(TCR *);
217void lisp_suspend_other_threads(void);
218void lisp_resume_other_threads(void);
219
220typedef struct
221{
222  signed_natural spin; /* need spin lock to change fields */
223  signed_natural state; /* 0 = free, positive if writer, negative if readers; */
224  natural blocked_writers;
225  natural blocked_readers;
226  TCR  *writer;
227#ifdef USE_FUTEX
228  natural reader_signal;
229  natural writer_signal;
230#else
231  void * reader_signal;
232  void * writer_signal;
233#endif
234  void *malloced_ptr;
235} rwlock;
236
237
238rwlock * rwlock_new(void);
239void rwlock_destroy(rwlock *);
240int rwlock_rlock(rwlock *, TCR *, struct timespec *);
241int rwlock_wlock(rwlock *, TCR *, struct timespec *);
242int rwlock_try_wlock(rwlock *, TCR *);
243int rwlock_try_rlock(rwlock *, TCR *);
244int rwlock_unlock(rwlock *, TCR *);
245
246
247natural
248atomic_and(natural*, natural);
249
250natural
251atomic_ior(natural*, natural);
252
253#define SET_TCR_FLAG(t,bit) atomic_ior(&(t->flags),(1L<<bit))
254#define CLR_TCR_FLAG(t,bit) atomic_and(&(t->flags),~(1L<<bit))
255
256
257
258extern int thread_suspend_signal, thread_kill_signal;
259
260void *
261allocate_stack(natural);
262
263void
264suspend_resume_handler(int, siginfo_t *, ExceptionInformation *);
265
266/* Maybe later
267Boolean
268rwlock_try_rlock(rwlock *);
269
270Boolean
271rwlock_try_wlock(rwlock *);
272*/
Note: See TracBrowser for help on using the repository browser.