source: release/1.9/source/lisp-kernel/threads.h @ 16083

Last change on this file since 16083 was 15739, checked in by gb, 6 years ago

merge recent changes from trunk

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