source: trunk/source/lisp-kernel/Threads.h @ 10068

Last change on this file since 10068 was 10068, checked in by gb, 12 years ago

Use SIGUSR1 for interrupt, SIGUSR2 for suspend on Solaris.

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