source: branches/arm/lisp-kernel/Threads.h @ 13923

Last change on this file since 13923 was 13643, checked in by gb, 10 years ago

Changed files from trunk.

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