source: release/1.2/source/lisp-kernel/Threads.h @ 9852

Last change on this file since 9852 was 9852, checked in by gb, 11 years ago

From trunk: treat stack sizes as "natural" integers.

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