Thread.java (Thread(ThreadGroup, Runnable, String)): Pass new parameter constructor.
[official-gcc.git] / libjava / java / lang / natThread.cc
blob42f18c4eb3a9c6d7fb3b08d7912092c7980331bf
1 // natThread.cc - Native part of Thread class.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 #include <config.h>
13 #include <stdlib.h>
15 #include <gcj/cni.h>
16 #include <jvm.h>
17 #include <java-threads.h>
19 #include <gnu/gcj/RawDataManaged.h>
20 #include <java/lang/Thread.h>
21 #include <java/lang/Thread$State.h>
22 #include <java/lang/Thread$UncaughtExceptionHandler.h>
23 #include <java/lang/ThreadGroup.h>
24 #include <java/lang/IllegalArgumentException.h>
25 #include <java/lang/IllegalThreadStateException.h>
26 #include <java/lang/InterruptedException.h>
27 #include <java/lang/NullPointerException.h>
29 #include <jni.h>
30 #include <jvmti.h>
31 #include "jvmti-int.h"
33 #ifdef ENABLE_JVMPI
34 #include <jvmpi.h>
35 #endif
39 static void finalize_native (jobject ptr);
41 // This is called from the constructor to initialize the native side
42 // of the Thread.
43 void
44 java::lang::Thread::initialize_native (void)
46 natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
48 state = JV_NEW;
49 nt->alive_flag = THREAD_DEAD;
51 data = (gnu::gcj::RawDataManaged *) nt;
53 // Register a finalizer to clean up the native thread resources.
54 _Jv_RegisterFinalizer (data, finalize_native);
56 _Jv_MutexInit (&nt->join_mutex);
57 _Jv_CondInit (&nt->join_cond);
59 nt->park_helper.init();
61 nt->thread = _Jv_ThreadInitData (this);
62 // FIXME: if JNI_ENV is set we will want to free it. It is
63 // malloc()d.
64 nt->jni_env = NULL;
67 static void
68 finalize_native (jobject ptr)
70 natThread *nt = (natThread *) ptr;
71 _Jv_ThreadDestroyData (nt->thread);
72 #ifdef _Jv_HaveCondDestroy
73 _Jv_CondDestroy (&nt->join_cond);
74 #endif
75 #ifdef _Jv_HaveMutexDestroy
76 _Jv_MutexDestroy (&nt->join_mutex);
77 #endif
78 _Jv_FreeJNIEnv((JNIEnv*)nt->jni_env);
80 nt->park_helper.destroy();
83 jint
84 java::lang::Thread::countStackFrames (void)
86 // NOTE: This is deprecated in JDK 1.2.
88 // Old applets still call this method. Rather than throwing
89 // UnsupportedOperationException we simply fail silently.
91 return 0;
94 java::lang::Thread *
95 java::lang::Thread::currentThread (void)
97 return _Jv_ThreadCurrent ();
100 jboolean
101 java::lang::Thread::holdsLock (jobject obj)
103 if (!obj)
104 throw new NullPointerException;
105 return !_Jv_ObjectCheckMonitor (obj);
108 jboolean
109 java::lang::Thread::isAlive (void)
111 natThread *nt = (natThread *) data;
112 return nt->alive_flag != (obj_addr_t)THREAD_DEAD;
115 void
116 java::lang::Thread::interrupt (void)
118 checkAccess ();
120 natThread *nt = (natThread *) data;
122 // If a thread is in state ALIVE, we atomically set it to state
123 // SIGNALED and send it a signal. Once we've sent it the signal, we
124 // set its state back to ALIVE.
125 if (compare_and_swap
126 (&nt->alive_flag, Thread::THREAD_ALIVE, Thread::THREAD_SIGNALED))
128 _Jv_ThreadInterrupt (nt->thread);
129 compare_and_swap
130 (&nt->alive_flag, THREAD_SIGNALED, Thread::THREAD_ALIVE);
132 // Even though we've interrupted this thread, it might still be
133 // parked.
134 nt->park_helper.unpark ();
138 void
139 java::lang::Thread::join (jlong millis, jint nanos)
141 if (millis < 0 || nanos < 0 || nanos > 999999)
142 throw new IllegalArgumentException;
144 Thread *current = currentThread ();
146 // Here `NT' is the native structure for the thread we are trying to join.
147 natThread *nt = (natThread *) data;
149 // Now wait for: (1) an interrupt, (2) the thread to exit, or (3)
150 // the timeout to occur.
151 _Jv_MutexLock (&nt->join_mutex);
152 if (! isAlive ())
154 _Jv_MutexUnlock (&nt->join_mutex);
155 return;
157 _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
158 _Jv_MutexUnlock (&nt->join_mutex);
160 if (current->isInterrupted (true))
161 throw new InterruptedException;
164 void
165 java::lang::Thread::resume (void)
167 checkAccess ();
169 // Old applets still call this method. Rather than throwing
170 // UnsupportedOperationException we simply fail silently.
173 void
174 java::lang::Thread::setPriority (jint newPriority)
176 checkAccess ();
177 if (newPriority < MIN_PRIORITY || newPriority > MAX_PRIORITY)
178 throw new IllegalArgumentException;
180 jint gmax = group->getMaxPriority();
181 if (newPriority > gmax)
182 newPriority = gmax;
184 priority = newPriority;
185 natThread *nt = (natThread *) data;
186 _Jv_ThreadSetPriority (nt->thread, priority);
189 void
190 java::lang::Thread::sleep (jlong millis, jint nanos)
192 if (millis < 0 || nanos < 0 || nanos > 999999)
193 throw new IllegalArgumentException;
195 if (millis == 0 && nanos == 0)
196 ++nanos;
198 Thread *current = currentThread ();
200 // We use a condition variable to implement sleeping so that an
201 // interrupt can wake us up.
202 natThread *nt = (natThread *) current->data;
203 _Jv_MutexLock (&nt->join_mutex);
204 _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
205 _Jv_MutexUnlock (&nt->join_mutex);
207 if (current->isInterrupted (true))
208 throw new InterruptedException;
211 void
212 java::lang::Thread::finish_ ()
214 __sync_synchronize();
215 natThread *nt = (natThread *) data;
217 nt->park_helper.deactivate ();
218 group->removeThread (this);
220 if (JVMTI_REQUESTED_EVENT (ThreadEnd))
221 _Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_END, this, nt->jni_env);
223 #ifdef ENABLE_JVMPI
224 if (_Jv_JVMPI_Notify_THREAD_END)
226 JVMPI_Event event;
228 event.event_type = JVMPI_EVENT_THREAD_END;
229 event.env_id = _Jv_GetCurrentJNIEnv ();
231 _Jv_DisableGC ();
232 (*_Jv_JVMPI_Notify_THREAD_END) (&event);
233 _Jv_EnableGC ();
235 #endif
237 // If a method cache was created, free it.
238 _Jv_FreeMethodCache();
240 // Clear out thread locals.
241 locals = NULL;
243 // Signal any threads that are waiting to join() us.
244 _Jv_MutexLock (&nt->join_mutex);
247 JvSynchronize sync (this);
248 nt->alive_flag = THREAD_DEAD;
249 state = JV_TERMINATED;
252 _Jv_CondNotifyAll (&nt->join_cond, &nt->join_mutex);
253 _Jv_MutexUnlock (&nt->join_mutex);
256 // Run once at thread startup, either when thread is attached or when
257 // _Jv_ThreadRun is called.
258 static void
259 _Jv_NotifyThreadStart (java::lang::Thread* thread)
261 if (JVMTI_REQUESTED_EVENT (ThreadStart))
263 natThread *nt = reinterpret_cast<natThread *> (thread->data);
264 _Jv_JVMTI_PostEvent (JVMTI_EVENT_THREAD_START, thread, nt->jni_env);
267 #ifdef ENABLE_JVMPI
268 if (_Jv_JVMPI_Notify_THREAD_START)
270 JVMPI_Event event;
272 jstring thread_name = thread->getName ();
273 jstring group_name = NULL, parent_name = NULL;
274 java::lang::ThreadGroup *group = thread->getThreadGroup ();
276 if (group)
278 group_name = group->getName ();
279 group = group->getParent ();
281 if (group)
282 parent_name = group->getName ();
285 int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
286 int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
287 int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
289 char thread_chars[thread_len + 1];
290 char group_chars[group_len + 1];
291 char parent_chars[parent_len + 1];
293 if (thread_name)
294 JvGetStringUTFRegion (thread_name, 0,
295 thread_name->length(), thread_chars);
296 if (group_name)
297 JvGetStringUTFRegion (group_name, 0,
298 group_name->length(), group_chars);
299 if (parent_name)
300 JvGetStringUTFRegion (parent_name, 0,
301 parent_name->length(), parent_chars);
303 thread_chars[thread_len] = '\0';
304 group_chars[group_len] = '\0';
305 parent_chars[parent_len] = '\0';
307 event.event_type = JVMPI_EVENT_THREAD_START;
308 event.env_id = NULL;
309 event.u.thread_start.thread_name = thread_chars;
310 event.u.thread_start.group_name = group_chars;
311 event.u.thread_start.parent_name = parent_chars;
312 event.u.thread_start.thread_id = (jobjectID) thread;
313 event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
315 _Jv_DisableGC ();
316 (*_Jv_JVMPI_Notify_THREAD_START) (&event);
317 _Jv_EnableGC ();
319 #endif
322 void
323 _Jv_ThreadRun (java::lang::Thread* thread)
327 _Jv_NotifyThreadStart (thread);
328 thread->run ();
330 catch (java::lang::Throwable *t)
332 // Uncaught exceptions are forwarded to the ThreadGroup. If
333 // this results in an uncaught exception, that is ignored.
336 thread->getUncaughtExceptionHandler()->uncaughtException (thread, t);
338 catch (java::lang::Throwable *f)
340 // Nothing.
344 thread->finish_ ();
347 _Jv_Thread_t*
348 _Jv_ThreadGetData (java::lang::Thread* thread)
350 natThread* nt = (natThread*) thread->data;
351 return nt->thread;
354 void
355 java::lang::Thread::start (void)
357 JvSynchronize sync (this);
359 // Its illegal to re-start() a thread, even if its dead.
360 if (!startable_flag)
361 throw new IllegalThreadStateException;
363 natThread *nt = (natThread *) data;
364 nt->alive_flag = THREAD_ALIVE;
365 startable_flag = false;
366 state = JV_RUNNABLE;
367 _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
370 void
371 java::lang::Thread::stop (java::lang::Throwable *)
373 checkAccess ();
375 // Old applets still call this method. Rather than throwing
376 // UnsupportedOperationException we simply fail silently.
379 void
380 java::lang::Thread::suspend (void)
382 checkAccess ();
384 // Old applets still call this method. Rather than throwing
385 // UnsupportedOperationException we simply fail silently.
388 static int nextThreadNumber = 0;
390 jstring
391 java::lang::Thread::gen_name (void)
393 jint i;
394 jclass sync = &java::lang::Thread::class$;
396 JvSynchronize dummy(sync);
397 i = ++nextThreadNumber;
400 // Use an array large enough for "-2147483648"; i.e. 11 chars, + "Thread-".
401 jchar buffer[7+11];
402 jchar *bufend = (jchar *) ((char *) buffer + sizeof(buffer));
403 i = _Jv_FormatInt (bufend, i);
404 jchar *ptr = bufend - i;
405 // Prepend "Thread-".
406 *--ptr = '-';
407 *--ptr = 'd';
408 *--ptr = 'a';
409 *--ptr = 'e';
410 *--ptr = 'r';
411 *--ptr = 'h';
412 *--ptr = 'T';
413 return JvNewString (ptr, bufend - ptr);
416 void
417 java::lang::Thread::yield (void)
419 _Jv_ThreadYield ();
422 ::java::lang::Thread$State *
423 java::lang::Thread::getState()
425 _Jv_InitClass(&::java::lang::Thread$State::class$);
427 switch (state)
429 case JV_BLOCKED:
430 return ::java::lang::Thread$State::BLOCKED;
431 case JV_NEW:
432 return ::java::lang::Thread$State::NEW;
434 case JV_RUNNABLE:
435 return ::java::lang::Thread$State::RUNNABLE;
436 case JV_TERMINATED:
437 return ::java::lang::Thread$State::TERMINATED;
438 case JV_TIMED_WAITING:
439 return ::java::lang::Thread$State::TIMED_WAITING;
440 case JV_WAITING:
441 return ::java::lang::Thread$State::WAITING;
444 // We don't really need a default, but this makes the compiler
445 // happy.
446 return ::java::lang::Thread$State::RUNNABLE;
449 JNIEnv *
450 _Jv_GetCurrentJNIEnv ()
452 java::lang::Thread *t = _Jv_ThreadCurrent ();
453 if (t == NULL)
454 return NULL;
455 return ((natThread *) t->data)->jni_env;
458 void
459 _Jv_SetCurrentJNIEnv (JNIEnv *env)
461 java::lang::Thread *t = _Jv_ThreadCurrent ();
462 JvAssert (t != NULL);
463 ((natThread *) t->data)->jni_env = env;
466 // Attach the current native thread to an existing (but unstarted) Thread
467 // object. Does not register thread with the garbage collector.
468 // Returns -1 on failure, 0 upon success.
469 jint
470 _Jv_AttachCurrentThread(java::lang::Thread* thread)
472 JvSynchronize sync (thread);
473 if (thread == NULL || thread->startable_flag == false)
474 return -1;
475 thread->startable_flag = false;
476 natThread *nt = (natThread *) thread->data;
477 nt->alive_flag = ::java::lang::Thread::THREAD_ALIVE;
478 thread->state = JV_RUNNABLE;
479 _Jv_ThreadRegister (nt->thread);
480 return 0;
483 java::lang::Thread*
484 _Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
486 // Register thread with GC before attempting any allocations.
487 _Jv_GCAttachThread ();
488 java::lang::Thread *thread = _Jv_ThreadCurrent ();
489 if (thread != NULL)
490 return thread;
491 if (name == NULL)
492 name = java::lang::Thread::gen_name ();
493 thread = new java::lang::Thread (NULL, group, NULL, name, false);
494 _Jv_AttachCurrentThread (thread);
495 _Jv_NotifyThreadStart (thread);
496 return thread;
499 java::lang::Thread*
500 _Jv_AttachCurrentThreadAsDaemon(jstring name, java::lang::ThreadGroup* group)
502 java::lang::Thread *thread = _Jv_ThreadCurrent ();
503 if (thread != NULL)
504 return thread;
505 if (name == NULL)
506 name = java::lang::Thread::gen_name ();
507 thread = new java::lang::Thread (NULL, group, NULL, name, false);
508 thread->setDaemon (true);
509 _Jv_AttachCurrentThread (thread);
510 _Jv_NotifyThreadStart (thread);
511 return thread;
514 jint
515 _Jv_DetachCurrentThread (void)
517 java::lang::Thread *t = _Jv_ThreadCurrent ();
518 if (t == NULL)
519 return -1;
521 _Jv_ThreadUnRegister ();
522 _Jv_GCDetachThread ();
523 // Release the monitors.
524 t->finish_ ();
526 return 0;