CACAO
thread-none.cpp
Go to the documentation of this file.
1 /* src/threads/none/thread-none.cpp - fake threads
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #include "threads/thread.hpp"
26 #include <cassert>
27 #include "threads/condition.hpp" // for Condition
28 #include "threads/lock.hpp" // for lock_monitor_enter, etc
29 #include "threads/mutex.hpp" // for Mutex
30 #include "threads/thread.hpp" // for DEBUGTHREADS, etc
31 #include "threads/threadlist.hpp" // for ThreadList
32 #include "threads/ThreadRuntime.hpp" // for ThreadRuntime
33 #include "vm/exceptions.hpp"
34 #include "vm/javaobjects.hpp" // for java_lang_Thread
35 #include "vm/vm.hpp" // for vm_call_method
36 
37 using namespace cacao;
38 
39 /* global variables ***********************************************************/
40 
42 
43 
44 /* functions ******************************************************************/
45 
46 /***
47  * Do some early initialization of stuff required.
48  *
49  * ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
50  * is called AFTER this function!
51  */
53 
54 
55 /***
56  * Initializes the implementation specific bits.
57  */
59 }
60 
61 /***
62  * Should start a thread, nop
63  */
65 
66 
67 /* threads_set_thread_priority *************************************************
68 
69  Set the priority of the given thread.
70 
71  IN:
72  tid..........thread id
73  priority.....priority to set
74 
75 ******************************************************************************/
76 
78 {
79 }
80 
81 /**
82  * Detaches the current thread from the VM.
83  *
84  * @return true on success, false otherwise
85  */
87 {
89 
90  /* Sanity check. */
91 
92  assert(t != NULL);
93 
94  /* If the given thread has already been detached, this operation
95  is a no-op. */
96 
97  if (thread_is_attached(t) == false)
98  return true;
99 
100  DEBUGTHREADS("detaching", t);
101 
102  java_handle_t* object = LLNI_WRAP(t->object);
103  java_lang_Thread jlt(object);
104 
105 #if defined(ENABLE_JAVASE)
106  java_handle_t* group = jlt.get_group();
107 
108  /* If there's an uncaught exception, call uncaughtException on the
109  thread's exception handler, or the thread's group if this is
110  unset. */
111 
113 
114  if (e != NULL) {
115  /* We use the type void* for handler here, as it's not trivial
116  to build the java_lang_Thread_UncaughtExceptionHandler
117  header file with cacaoh. */
118 
120 
121  classinfo* c;
122  java_handle_t* h;
123 
124  if (handler != NULL) {
125  LLNI_class_get(handler, c);
126  h = (java_handle_t *) handler;
127  }
128  else {
129  LLNI_class_get(group, c);
130  h = (java_handle_t *) group;
131  }
132 
134  utf8::uncaughtException,
135  utf8::java_lang_Thread_java_lang_Throwable__V,
136  NULL,
137  true);
138 
139  if (m == NULL)
140  return false;
141 
142  (void) vm_call_method(m, h, object, e);
143 
145  return false;
146  }
147 
148  /* XXX TWISTI: should all threads be in a ThreadGroup? */
149 
150  /* Remove thread from the thread group. */
151 
152  if (group != NULL) {
153  classinfo* c;
154  LLNI_class_get(group, c);
155 
157 
158  if (m == NULL)
159  return false;
160 
161  (void) vm_call_method(m, group, object);
162 
164  return false;
165 
166  // Clear the ThreadGroup in the Java thread object (Mauve
167  // test: gnu/testlet/java/lang/Thread/getThreadGroup).
168  jlt.set_group(NULL);
169  }
170 #endif
171 
172  /* Thread has terminated. */
173 
175 
176  /* Notify all threads waiting on this thread. These are joining
177  this thread. */
178 
179  /* Free the internal thread data-structure. */
180 
181  thread_free(t);
182 
183  return true;
184 }
185 
186 /**
187  * Suspend the passed thread. Execution of that thread stops until the thread
188  * is explicitly resumed again.
189  *
190  * @param thread The thread to be suspended.
191  * @param reason Reason for suspending the given thread.
192  * @return True of operation was successful, false otherwise.
193  */
195 {
196  // Sanity check.
197  assert(reason != SUSPEND_REASON_NONE);
198 
199  // Check if thread is already suspended.
200  if (thread->suspended)
201  return false;
202 
203  // Check if thread is in the process of suspending.
204  if (thread->suspend_reason != SUSPEND_REASON_NONE)
205  return false;
206 
207  // Set the reason for suspending the thread.
208  thread->suspend_reason = reason;
209  return true;
210 }
211 
212 
213 /**
214  * Resumes execution of the passed thread.
215  *
216  * @param thread The thread to be resumed.
217  * @param reason Reason for suspending the given thread.
218  * @return True of operation was successful, false otherwise.
219  */
221 {
222  // Sanity check.
223  assert(thread != THREADOBJECT);
224  assert(reason != SUSPEND_REASON_NONE);
225 
226  // Check if thread really is suspended.
227  if (!thread->suspended)
228  return false;
229 
230  // Threads can only be resumed for the same reason they were suspended.
231  if (thread->suspend_reason != reason)
232  return false;
233 
234  // Clear the reason for suspending the thread.
236  return true;
237 }
238 
240 {
241  t->object = 0;
242  t->flc_object = 0;
243 }
244 
245 /***
246  * Acknowledges the suspension of the current thread.
247  */
249 
250 /***
251  * Join all non-daemon threads.
252  */
254 
255 /***
256  * Clears all fields in threadobject.
257  */
259  t->object = NULL;
260 
261  t->thinlock = 0;
262 
263  t->index = 0;
264  t->flags = 0;
265  t->state = THREAD_STATE_NEW;
266  t->is_in_active_list = false;
267 
268  t->interrupted = false;
269  t->signaled = false;
270 
271  t->suspended = false;
273 
274  t->pc = NULL;
275 
276  t->_exceptionptr = NULL;
277  t->_stackframeinfo = NULL;
278  t->_localref_table = NULL;
279 
280 #if defined(ENABLE_INTRP)
281  t->_global_sp = NULL;
282 #endif
283 
284 #if defined(ENABLE_GC_CACAO)
285  t->gc_critical = false;
286 
287  t->ss = NULL;
288  t->es = NULL;
289 #endif
290 
291  // Simply reuse the existing dump memory.
292 }
293 
294 
295 /***
296  * Resets some implementation fields in threadobject.
297  */
299 
300 /***
301  * Interrupt the given thread.
302  *
303  * The thread gets its interrupted flag is set to true.
304  */
306  // Signal the thread a "waitcond" and tell it that it has been
307  // interrupted.
308 
309  DEBUGTHREADS("interrupted", t);
310 
311  t->interrupted = true;
312 }
313 
314 /***
315  * Sleep the current thread for the specified amount of time.
316  *
317  * @param millis Milliseconds to sleep.
318  * @param nanos Nanoseconds to sleep.
319  */
320 void threads_sleep(int64_t millis, int32_t nanos) {
321  if (millis < 0) {
322  exceptions_throw_illegalargumentexception(/*"timeout value is negative"*/);
323  return;
324  }
325 
327 
329  // Clear interrupted flag
330  // (Mauve test: gnu/testlet/java/lang/Thread/interrupt).
331 
332  thread_set_interrupted(t, false);
333 
334  exceptions_throw_interruptedexception(/*"sleep interrupted"*/);
335  return;
336  }
337 
338  // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
339  // Note: JDK treats a zero length sleep is like Thread.yield(),
340  // without checking the interrupted status of the thread. It's
341  // unclear if this is a bug in the implementation or the spec.
342  // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
343  if (millis == 0 && nanos == 0) {
344  threads_yield();
345  } else {
346  if (thread_is_interrupted(t)) {
347  thread_set_interrupted(t, false);
348 
349  // An other exception could have been thrown
350  // (e.g. ThreadDeathException).
353  }
354  }
355 }
356 
357 
358 /***
359  * Wait for the given maximum amount of time on a monitor until either
360  * we are notified, we are interrupted, or the time is up.
361  */
363 
364 
365 /**
366  * Park the current thread for the specified amount of time or until a
367  * specified deadline.
368  *
369  * @param absolute Is the time in nanos a deadline or a duration?
370  * @param nanos Nanoseconds to park (absolute=false)
371  * or deadline in milliseconds (absolute=true)
372  */
373 void threads_park(bool absolute, int64_t nanos) {}
374 
375 /**
376  * Unpark the specified thread.
377  *
378  * @param t The thread to unpark.
379  */
381 
382 
383 /***
384  * Yield to the scheduler.
385  */
386 void threads_yield(void) {}
387 
388 
389 /***
390  * Return the tid of a thread.
391  */
393  return 0;
394 }
395 
396 
397 /*
398  * These are local overrides for various environment variables in Emacs.
399  * Please do not remove this and leave it at the end of the file, where
400  * Emacs will automagically detect them.
401  * ---------------------------------------------------------------------
402  * Local variables:
403  * mode: c++
404  * indent-tabs-mode: t
405  * c-basic-offset: 4
406  * tab-width: 4
407  * End:
408  * vim:noexpandtab:sw=4:ts=4:
409  */
void exceptions_throw_illegalargumentexception(void)
SuspendReason
Definition: thread.hpp:65
methodinfo * class_resolveclassmethod(classinfo *c, Utf8String name, Utf8String desc, classinfo *referer, bool throwexception)
Definition: class.cpp:1211
void threads_thread_interrupt(threadobject *t)
bool threads_suspend_thread(threadobject *thread, SuspendReason reason)
Suspend the passed thread.
void threads_unpark(threadobject *t)
Unpark the specified thread.
intptr_t threads_get_tid(threadobject *t)
void exceptions_throw_interruptedexception(void)
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
java_handle_t * vm_call_method(methodinfo *m, java_handle_t *o,...)
static java_handle_t * get_thread_exception_handler(const java_lang_Thread &jlt)
void threads_impl_thread_clear(threadobject *t)
void threads_set_thread_priority(threadobject *t, int priority)
Definition: thread-none.cpp:77
int64_t s8
Definition: types.hpp:48
#define DEBUGTHREADS(message, thread)
Definition: thread.hpp:166
void(* functionptr)(void)
Definition: global.hpp:39
ptrint thinlock
Definition: thread.hpp:95
java_handle_t * get_group() const
#define LLNI_class_get(obj, variable)
Definition: llni.hpp:60
#define LLNI_WRAP(obj)
Definition: llni.hpp:51
java_object_t * _exceptionptr
Definition: thread.hpp:128
bool suspended
Definition: thread.hpp:123
void threads_impl_thread_start(threadobject *thread, functionptr f)
Definition: thread-none.cpp:64
localref_table * _localref_table
Definition: thread.hpp:130
void threads_wait_with_timeout_relative(threadobject *thread, s8 millis, s4 nanos)
bool interrupted
Definition: thread.hpp:119
JNIEnv jthread thread
Definition: jvmti.h:207
SuspendReason suspend_reason
Definition: thread.hpp:124
#define exceptions_get_and_clear_exception
Definition: md-asm.hpp:98
bool thread_is_interrupted(threadobject *t)
Definition: thread.cpp:926
void thread_free(threadobject *t)
Definition: thread.cpp:371
threadobject * thread_current
Definition: thread-none.cpp:41
void threads_join_all_threads()
int32_t s4
Definition: types.hpp:45
ThreadState state
Definition: thread.hpp:97
void threads_suspend_ack()
void thread_set_state_terminated(threadobject *t)
Definition: thread.cpp:848
void set_group(java_handle_t *value)
bool thread_detach_current_thread(void)
Detaches the current thread from the VM.
Definition: thread-none.cpp:86
static methodinfo * get_threadgroup_remove_method(classinfo *c)
java_handle_t * flc_object
Definition: thread.hpp:108
void threads_impl_preinit()
Definition: thread-none.cpp:52
MIIterator e
void thread_set_interrupted(threadobject *t, bool interrupted)
Definition: thread.cpp:949
static bool thread_is_attached(threadobject *t)
Definition: thread.hpp:262
static threadobject * thread_get_current()
Return the threadobject for the current thread.
Definition: thread-none.hpp:56
void threads_impl_init()
Definition: thread-none.cpp:58
void threads_park(bool absolute, int64_t nanos)
Park the current thread for the specified amount of time or until a specified deadline.
void threads_impl_clear_heap_pointers(threadobject *t)
bool signaled
Definition: thread.hpp:120
java_handle_t * exceptions_get_exception(void)
Definition: exceptions.cpp:76
GNU Classpath java/lang/Thread.
java_object_t * object
Definition: thread.hpp:93
stackframeinfo_t * _stackframeinfo
Definition: thread.hpp:129
void threads_sleep(int64_t millis, int32_t nanos)
bool is_in_active_list
Definition: thread.hpp:100
#define THREADOBJECT
Definition: thread-none.hpp:47
void threads_impl_thread_reuse(threadobject *t)
void threads_yield(void)
bool threads_resume_thread(threadobject *thread, SuspendReason reason)
Resumes execution of the passed thread.