Fix LDC, LDC_W, and INSTANCEOF opcodes, more debugging
[jamvm-avr32-jem.git] / src / thread.h
blobfe66584ff4c24283040890becd6a6f6e8e16c7f6
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007
3 * Robert Lougher <rob@lougher.org.uk>.
5 * This file is part of JamVM.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #ifndef CREATING
23 #include <pthread.h>
24 #include <setjmp.h>
25 #include <stdlib.h>
27 /* Thread states */
29 #define CREATING 0
30 #define STARTED 1
31 #define RUNNING 2
32 #define WAITING 3
33 #define TIMED_WAITING 4
34 #define BLOCKED 5
35 #define SUSPENDED 6
37 /* thread priorities */
39 #define MIN_PRIORITY 1
40 #define NORM_PRIORITY 5
41 #define MAX_PRIORITY 10
43 /* Enable/Disable suspend modes */
45 #define SUSP_BLOCKING 1
46 #define SUSP_CRITICAL 2
48 typedef struct thread Thread;
50 typedef struct monitor {
51 pthread_mutex_t lock;
52 Thread *owner;
53 Object *obj;
54 int count;
55 int in_wait;
56 uintptr_t entering;
57 int wait_count;
58 Thread *wait_set;
59 struct monitor *next;
60 } Monitor;
62 struct thread {
63 int id;
64 pthread_t tid;
65 char state;
66 char suspend;
67 char blocking;
68 char interrupted;
69 char interrupting;
70 ExecEnv *ee;
71 void *stack_top;
72 void *stack_base;
73 Monitor *wait_mon;
74 Monitor *blocked_mon;
75 Thread *wait_prev;
76 Thread *wait_next;
77 pthread_cond_t wait_cv;
78 long long blocked_count;
79 long long waited_count;
80 Thread *prev, *next;
81 unsigned int wait_id;
82 unsigned int notify_id;
85 extern Thread *threadSelf();
86 extern Thread *threadSelf0(Object *jThread);
88 extern void *getStackTop(Thread *thread);
89 extern void *getStackBase(Thread *thread);
91 extern int getThreadsCount();
92 extern int getPeakThreadsCount();
93 extern void resetPeakThreadsCount();
94 extern long long getTotalStartedThreadsCount();
96 extern void threadInterrupt(Thread *thread);
97 extern void threadSleep(Thread *thread, long long ms, int ns);
98 extern void threadYield(Thread *thread);
100 extern int threadIsAlive(Thread *thread);
101 extern int threadInterrupted(Thread *thread);
102 extern int threadIsInterrupted(Thread *thread);
103 extern int systemIdle(Thread *self);
105 extern void suspendAllThreads(Thread *thread);
106 extern void resumeAllThreads(Thread *thread);
108 extern void createVMThread(char *name, void (*start)(Thread*));
110 extern void disableSuspend0(Thread *thread, void *stack_top);
111 extern void enableSuspend(Thread *thread);
112 extern void fastEnableSuspend(Thread *thread);
114 extern Thread *attachJNIThread(char *name, char is_daemon, Object *group);
115 extern void detachJNIThread(Thread *thread);
117 extern char *getThreadStateString(Thread *thread);
119 extern Thread *findThreadById(long long id);
120 extern void suspendThread(Thread *thread);
121 extern void resumeThread(Thread *thread);
123 #define disableSuspend(thread) \
125 sigjmp_buf *env; \
126 env = alloca(sizeof(sigjmp_buf)); \
127 sigsetjmp(*env, FALSE); \
128 disableSuspend0(thread, (void*)env);\
131 #define fastDisableSuspend(thread) \
133 thread->blocking = SUSP_CRITICAL; \
134 MBARRIER(); \
137 typedef struct {
138 pthread_mutex_t lock;
139 pthread_cond_t cv;
140 } VMWaitLock;
142 typedef pthread_mutex_t VMLock;
144 #define initVMLock(lock) pthread_mutex_init(&lock, NULL)
145 #define initVMWaitLock(wait_lock) { \
146 pthread_mutex_init(&wait_lock.lock, NULL); \
147 pthread_cond_init(&wait_lock.cv, NULL); \
150 #define lockVMLock(lock, self) { \
151 self->state = BLOCKED; \
152 pthread_mutex_lock(&lock); \
153 self->state = RUNNING; \
156 #define tryLockVMLock(lock, self) \
157 (pthread_mutex_trylock(&lock) == 0)
159 #define unlockVMLock(lock, self) if(self) pthread_mutex_unlock(&lock)
161 #define lockVMWaitLock(wait_lock, self) lockVMLock(wait_lock.lock, self)
162 #define unlockVMWaitLock(wait_lock, self) unlockVMLock(wait_lock.lock, self)
164 #define waitVMWaitLock(wait_lock, self) { \
165 self->state = WAITING; \
166 pthread_cond_wait(&wait_lock.cv, &wait_lock.lock); \
167 self->state = RUNNING; \
170 #define timedWaitVMWaitLock(wait_lock, self, ms) { \
171 struct timeval tv; \
172 struct timespec ts; \
173 gettimeofday(&tv, 0); \
174 ts.tv_sec = tv.tv_sec + ms/1000; \
175 ts.tv_nsec = (tv.tv_usec + ((ms%1000)*1000))*1000; \
176 if(ts.tv_nsec > 999999999L) { \
177 ts.tv_sec++; \
178 ts.tv_nsec -= 1000000000L; \
180 self->state = TIMED_WAITING; \
181 pthread_cond_timedwait(&wait_lock.cv, &wait_lock.lock, &ts); \
182 self->state = RUNNING; \
185 #define notifyVMWaitLock(wait_lock, self) pthread_cond_signal(&wait_lock.cv)
186 #define notifyAllVMWaitLock(wait_lock, self) pthread_cond_broadcast(&wait_lock.cv)
187 #endif