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

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

Some things are different when USE_FUTEX is defined.

Declare a variable used to control the generation logging output for
TCR creation/access.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.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#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
49#ifdef USE_FUTEX
50#include <linux/futex.h>
51#include <sys/syscall.h>
52#endif
53
54#include <syslog.h>
55
56Boolean extern threads_initialized;
57Boolean extern log_tcr_info;
58
59#define LOCK_SPINLOCK(x,tcr) get_spin_lock(&(x),tcr)
60#define RELEASE_SPINLOCK(x) (x)=0
61
62#define TCR_TO_TSD(tcr) ((void *)((natural)(tcr)+TCR_BIAS))
63#define TCR_FROM_TSD(tsd) ((TCR *)((natural)(tsd)-TCR_BIAS))
64
65#ifdef USE_POSIX_SEMAPHORES
66typedef sem_t * SEMAPHORE;
67#define SEM_WAIT(s) sem_wait((SEMAPHORE)s)
68#define SEM_RAISE(s) sem_post((SEMAPHORE)s)
69#define SEM_BROADCAST(s, count) do {while(count) {SEM_RAISE(s);(count)--;}}while(0)
70#define SEM_TIMEDWAIT(s,t) sem_timedwait((SEMAPHORE)s,(struct timespec *)t)
71#endif
72
73#ifdef USE_MACH_SEMAPHORES
74typedef semaphore_t SEMAPHORE;
75#define SEM_WAIT(s) semaphore_wait((SEMAPHORE)(natural)s)
76#define SEM_RAISE(s) semaphore_signal((SEMAPHORE)(natural)s)
77#define SEM_BROADCAST(s,count)semaphore_signal_all((SEMAPHORE)(natural)s)
78#define SEM_TIMEDWAIT(s,t) semaphore_timedwait((SEMAPHORE)(natural)s,t)
79#endif
80
81void sem_wait_forever(SEMAPHORE s);
82
83#ifdef USE_POSIX_SEMAPHORES
84#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)s)
85#endif
86
87#ifdef USE_MACH_SEMAPHORES
88#define SEM_WAIT_FOREVER(s) sem_wait_forever((SEMAPHORE)(natural)s)
89#endif
90
91typedef struct
92{
93  signed_natural avail;
94  TCR* owner;
95  signed_natural  count;
96  void* signal;
97  signed_natural waiting;
98  void *malloced_ptr;
99  signed_natural spinlock;
100} _recursive_lock, *RECURSIVE_LOCK;
101
102
103int lock_recursive_lock(RECURSIVE_LOCK, TCR *);
104int unlock_recursive_lock(RECURSIVE_LOCK, TCR *);
105RECURSIVE_LOCK new_recursive_lock(void);
106void destroy_recursive_lock(RECURSIVE_LOCK);
107int recursive_lock_trylock(RECURSIVE_LOCK, TCR *, int *);
108
109#define LOCK(m, t) lock_recursive_lock((RECURSIVE_LOCK)ptr_from_lispobj(m), (TCR *)t)
110#define UNLOCK(m, t) unlock_recursive_lock((RECURSIVE_LOCK)ptr_from_lispobj(m), (TCR *)t)
111
112/* Hmm.  This doesn't look like the MacOS Thread Manager ... */
113LispObj current_thread_osid(void);
114void *current_native_thread_id(void);
115void *new_semaphore(int);
116void destroy_semaphore(void**);
117void tsd_set(LispObj, void *);
118void *tsd_get(LispObj);
119TCR *new_tcr(natural, natural);
120TCR *initial_thread_tcr;
121
122#define DEFAULT_THREAD_STACK_SIZE ((size_t) -1)
123#define MINIMAL_THREAD_STACK_SIZE ((size_t) 0)
124
125
126LispObj create_system_thread(size_t stack_size, 
127                             void* stackaddr,
128                             void* (*start_routine)(void *),
129                             void* param);
130
131TCR *get_tcr(Boolean);
132TCR *get_interrupt_tcr(Boolean);
133Boolean suspend_tcr(TCR *);
134Boolean resume_tcr(TCR *);
135
136typedef struct
137{
138  signed_natural spin; /* need spin lock to change fields */
139  signed_natural state; /* 0 = free, positive if writer, negative if readers; */
140  natural blocked_writers;
141  natural blocked_readers;
142  TCR  *writer;
143#ifdef USE_FUTEX
144  natural reader_signal;
145  natural writer_signal;
146#else
147  void * reader_signal;
148  void * writer_signal;
149#endif
150  void *malloced_ptr;
151} rwlock;
152
153
154rwlock * rwlock_new(void);
155void rwlock_destroy(rwlock *);
156int rwlock_rlock(rwlock *, TCR *, struct timespec *);
157int rwlock_wlock(rwlock *, TCR *, struct timespec *);
158int rwlock_try_wlock(rwlock *, TCR *);
159int rwlock_try_rlock(rwlock *, TCR *);
160int rwlock_unlock(rwlock *, TCR *);
161
162
163natural
164atomic_and(natural*, natural);
165
166natural
167atomic_ior(natural*, natural);
168
169#define SET_TCR_FLAG(t,bit) atomic_ior(&(t->flags),(1L<<bit))
170#define CLR_TCR_FLAG(t,bit) atomic_and(&(t->flags),~(1L<<bit))
171
172
173#ifdef SIGRTMIN
174#define SIG_SUSPEND_THREAD (SIGRTMIN+6)
175#define SIG_RESUME_THREAD (SIG_SUSPEND_THREAD+1)
176#else
177#define SIG_SUSPEND_THREAD SIGUSR1
178#define SIG_RESUME_THREAD SIGUSR2
179#endif
180
181extern int thread_suspend_signal, thread_resume_signal;
182
183void
184suspend_resume_handler(int, siginfo_t *, ExceptionInformation *);
185
186/* Maybe later
187Boolean
188rwlock_try_rlock(rwlock *);
189
190Boolean
191rwlock_try_wlock(rwlock *);
192*/
Note: See TracBrowser for help on using the repository browser.