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

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

Because of mingw32/w32api lossage, it's necessary to ensure that "argv"
isn't #defined before #including <stdio.h>.

Thread startup functions need the CALLBACK attribute (because they
follow Windows calling conventions.)

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