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

Last change on this file since 14347 was 14295, checked in by rme, 9 years ago

Eliminate some (but not all) warnings produced when building with
"-Wall -Wno-format". Also a couple of minor changes that enable
clang to build the lisp kernel (at least on x8632 and x8664).

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