source: branches/working-0710/ccl/lisp-kernel/Threads.h @ 7418

Last change on this file since 7418 was 7418, checked in by gb, 13 years ago

Lots of changes to support new rwlocks, heap freeze, deferred GC.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 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#include <unistd.h>
19#include <sys/mman.h>
20#include <stdio.h>
21#include <pthread.h>
22#include <errno.h>
23#include <limits.h>
24#undef USE_MACH_SEMAPHORES
25#undef USE_POSIX_SEMAPHORES
26#ifdef DARWIN
27#define USE_MACH_SEMAPHORES 1
28#endif
29#ifndef USE_MACH_SEMAPHORES
30#define USE_POSIX_SEMAPHORES
31#include <semaphore.h>
32#endif
33#ifdef USE_MACH_SEMAPHORES
34/* We have to use Mach semaphores, even if we're otherwise
35   using POSIX signals, etc. */
36#include <mach/task.h>
37#include <mach/semaphore.h>
38#endif
39#include <limits.h>
40#ifdef FREEBSD
41#include <pthread_np.h>
42#endif
43#include <sched.h>
44
45#include "lisp.h"
46#include "lisp_globals.h"
47#include "gc.h"
48
49Boolean extern threads_initialized;
50
51#define LOCK_SPINLOCK(x,tcr) get_spin_lock(&(x),tcr)
52#define RELEASE_SPINLOCK(x) (x)=0
53
54#define TCR_TO_TSD(tcr) ((void *)((natural)(tcr)+TCR_BIAS))
55#define TCR_FROM_TSD(tsd) ((TCR *)((natural)(tsd)-TCR_BIAS))
56
57#ifdef USE_POSIX_SEMAPHORES
58typedef sem_t * SEMAPHORE;
59#define SEM_WAIT(s) sem_wait((SEMAPHORE)s)
60#define SEM_RAISE(s) sem_post((SEMAPHORE)s)
61#define SEM_BROADCAST(s, count) do {while(count) {SEM_RAISE(s);(count)--;}}while(0)
62#define SEM_TIMEDWAIT(s,t) sem_timedwait((SEMAPHORE)s,(struct timespec *)t)
63#endif
64
65#ifdef USE_MACH_SEMAPHORES
66typedef semaphore_t SEMAPHORE;
67#define SEM_WAIT(s) semaphore_wait((SEMAPHORE)(natural)s)
68#define SEM_RAISE(s) semaphore_signal((SEMAPHORE)(natural)s)
69#define SEM_BROADCAST(s,count)semaphore_signal_all((SEMAPHORE)(natural)s)
70#define SEM_TIMEDWAIT(s,t) semaphore_timedwait((SEMAPHORE)(natural)s,t)
71#endif
72
73void sem_wait_forever(SEMAPHORE s);
74
75#ifdef USE_POSIX_SEMAPHORES
76#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)s)
77#endif
78
79#ifdef USE_MACH_SEMAPHORES
80#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)(natural)s)
81#endif
82
83typedef struct
84{
85  signed_natural avail;
86  TCR* owner;
87  signed_natural  count;
88  void* signal;
89  signed_natural waiting;
90  void *malloced_ptr;
91  signed_natural spinlock;
92} _recursive_lock, *RECURSIVE_LOCK;
93
94
95int lock_recursive_lock(RECURSIVE_LOCK, TCR *);
96int unlock_recursive_lock(RECURSIVE_LOCK, TCR *);
97RECURSIVE_LOCK new_recursive_lock(void);
98void destroy_recursive_lock(RECURSIVE_LOCK);
99int recursive_lock_trylock(RECURSIVE_LOCK, TCR *, int *);
100
101#define LOCK(m, t) lock_recursive_lock((RECURSIVE_LOCK)ptr_from_lispobj(m), (TCR *)t)
102#define UNLOCK(m, t) unlock_recursive_lock((RECURSIVE_LOCK)ptr_from_lispobj(m), (TCR *)t)
103
104/* Hmm.  This doesn't look like the MacOS Thread Manager ... */
105LispObj current_thread_osid(void);
106void *current_native_thread_id(void);
107void *new_semaphore(int);
108void destroy_semaphore(void**);
109void tsd_set(LispObj, void *);
110void *tsd_get(LispObj);
111TCR *new_tcr(natural, natural);
112TCR *initial_thread_tcr;
113
114#define DEFAULT_THREAD_STACK_SIZE ((size_t) -1)
115#define MINIMAL_THREAD_STACK_SIZE ((size_t) 0)
116
117
118LispObj create_system_thread(size_t stack_size, 
119                             void* stackaddr,
120                             void* (*start_routine)(void *),
121                             void* param);
122
123TCR *get_tcr(Boolean);
124TCR *get_interrupt_tcr(Boolean);
125Boolean suspend_tcr(TCR *);
126Boolean resume_tcr(TCR *);
127
128typedef struct
129{
130  signed_natural spin; /* need spin lock to change fields */
131  signed_natural state; /* 0 = free, positive if writer, negative if readers; */
132  natural blocked_writers;
133  natural blocked_readers;
134  TCR  *writer;
135  void * reader_signal;
136  void * writer_signal;
137  void *malloced_ptr;
138} rwlock;
139
140
141rwlock * rwlock_new(void);
142void rwlock_destroy(rwlock *);
143int rwlock_rlock(rwlock *, TCR *, struct timespec *);
144int rwlock_wlock(rwlock *, TCR *, struct timespec *);
145int rwlock_try_wlock(rwlock *, TCR *);
146int rwlock_try_rlock(rwlock *, TCR *);
147int rwlock_unlock(rwlock *, TCR *);
148
149
150natural
151atomic_and(natural*, natural);
152
153natural
154atomic_ior(natural*, natural);
155
156#define SET_TCR_FLAG(t,bit) atomic_ior(&(t->flags),(1L<<bit))
157#define CLR_TCR_FLAG(t,bit) atomic_and(&(t->flags),~(1L<<bit))
158
159
160#ifdef SIGRTMIN
161#define SIG_SUSPEND_THREAD (SIGRTMIN+6)
162#define SIG_RESUME_THREAD (SIG_SUSPEND_THREAD+1)
163#else
164#define SIG_SUSPEND_THREAD SIGUSR1
165#define SIG_RESUME_THREAD SIGUSR2
166#endif
167
168extern int thread_suspend_signal, thread_resume_signal;
169
170void
171suspend_resume_handler(int, siginfo_t *, ExceptionInformation *);
172
173/* Maybe later
174Boolean
175rwlock_try_rlock(rwlock *);
176
177Boolean
178rwlock_try_wlock(rwlock *);
179*/
Note: See TracBrowser for help on using the repository browser.