c8c3abcd808529d7ee6714051bd2b2a2177b6717
[cacao.git] / src / threads / thread.cpp
1 /* src/threads/thread.cpp - machine independent thread functions
2
3    Copyright (C) 1996-2011
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
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <unistd.h>
31
32 #include "vm/types.h"
33
34 #include "mm/memory.hpp"
35
36 #if defined(ENABLE_GC_BOEHM)
37 /* We need to include Boehm's gc.h here for GC_register_my_thread and
38    friends. */
39 # include "mm/boehm-gc/include/gc.h"
40 #endif
41
42 #include "native/llni.h"
43 #include "native/native.hpp"
44
45 #include "threads/lock.hpp"
46 #include "threads/threadlist.hpp"
47 #include "threads/thread.hpp"
48
49 #include "vm/jit/builtin.hpp"
50 #include "vm/class.hpp"
51 #include "vm/exceptions.hpp"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/method.hpp"
55 #include "vm/options.h"
56 #include "vm/string.hpp"
57 #include "vm/utf8.h"
58 #include "vm/vm.hpp"
59
60 #if defined(ENABLE_STATISTICS)
61 # include "vm/statistics.h"
62 #endif
63
64 #include "vm/jit/stacktrace.hpp"
65
66
67 /* global variables ***********************************************************/
68
69 static methodinfo    *thread_method_init;
70 static java_handle_t *threadgroup_system;
71 static java_handle_t *threadgroup_main;
72
73 #if defined(__LINUX__)
74 /* XXX Remove for exact-GC. */
75 bool threads_pthreads_implementation_nptl;
76 #endif
77
78
79 /* static functions ***********************************************************/
80
81 static void          thread_create_initial_thread(void);
82 static threadobject *thread_new(int32_t flags);
83
84
85 /* threads_preinit *************************************************************
86
87    Do some early initialization of stuff required.
88
89 *******************************************************************************/
90
91 void threads_preinit(void)
92 {
93         threadobject *mainthread;
94 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
95         char         *pathbuf;
96         size_t        len;
97 #endif
98
99         TRACESUBSYSTEMINITIALIZATION("threads_preinit");
100
101 #if defined(__LINUX__)
102         /* XXX Remove for exact-GC. */
103
104         /* On Linux we need to check the pthread implementation. */
105
106         /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
107         /* If the glibc is a pre-2.3.2 version, we fall back to
108            linuxthreads. */
109
110 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
111         len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
112
113         /* Some systems return as length 0 (maybe cross-compilation
114            related).  In this case we also fall back to linuxthreads. */
115
116         if (len > 0) {
117                 pathbuf = MNEW(char, len);
118
119                 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
120
121                 if (strstr(pathbuf, "NPTL") != NULL)
122                         threads_pthreads_implementation_nptl = true;
123                 else
124                         threads_pthreads_implementation_nptl = false;
125         }
126         else
127                 threads_pthreads_implementation_nptl = false;
128 # else
129         threads_pthreads_implementation_nptl = false;
130 # endif
131 #endif
132
133         /* Initialize the threads implementation (sets the thinlock on the
134            main thread). */
135
136         threads_impl_preinit();
137
138         /* Create internal thread data-structure for the main thread. */
139
140         mainthread = thread_new(THREAD_FLAG_JAVA);
141
142         /* The main thread should always have index 1. */
143
144         if (mainthread->index != 1)
145                 vm_abort("threads_preinit: main thread index not 1: %d != 1",
146                                  mainthread->index);
147
148         /* Thread is already running. */
149
150         mainthread->state = THREAD_STATE_RUNNABLE;
151
152         /* Store the internal thread data-structure in the TSD. */
153
154         thread_set_current(mainthread);
155 }
156
157
158 /* threads_init ****************************************************************
159
160    Initialize the main thread.
161
162 *******************************************************************************/
163
164 void threads_init(void)
165 {
166         TRACESUBSYSTEMINITIALIZATION("threads_init");
167
168         /* Create the system and main thread groups. */
169
170         ThreadRuntime::thread_create_initial_threadgroups(&threadgroup_main, &threadgroup_system);
171
172         /* Cache the java.lang.Thread initialization method. */
173
174         thread_method_init = ThreadRuntime::get_thread_init_method();
175
176         if (thread_method_init == NULL)
177                 vm_abort("threads_init: failed to resolve thread init method");
178
179         thread_create_initial_thread();
180 }
181
182
183 /* thread_create_object ********************************************************
184
185    Create a Java thread object for the given thread data-structure,
186    initializes it and adds the thread to the threadgroup.
187
188    ARGUMENTS:
189
190        t ....... thread
191        name .... thread name
192        group ... threadgroup
193
194    RETURN:
195
196 *******************************************************************************/
197
198 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
199 {
200         /* Create a java.lang.Thread Java object. */
201
202         java_handle_t* h = builtin_new(class_java_lang_Thread);
203
204         if (h == NULL)
205                 return false;
206
207         java_lang_Thread jlt(h);
208
209         // Set the Java object in the thread data-structure.  This
210         // indicates that the thread is attached to the VM.
211         thread_set_object(t, jlt.get_handle());
212
213         return ThreadRuntime::invoke_thread_initializer(jlt, t, thread_method_init, name, group);
214 }
215
216
217 /* thread_create_initial_thread ***********************************************
218
219    Create the initial thread: main
220
221 *******************************************************************************/
222
223 static void thread_create_initial_thread(void)
224 {
225         threadobject  *t;
226         java_handle_t *name;
227
228         /* Get the main-thread (NOTE: The main thread is always the first
229            thread in the list). */
230
231         t = ThreadList::get_main_thread();
232
233         /* The thread name. */
234
235         name = javastring_new(utf_main);
236
237 #if defined(ENABLE_INTRP)
238         /* create interpreter stack */
239
240         if (opt_intrp) {
241                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
242                 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
243         }
244 #endif
245
246         /* Create the Java thread object. */
247
248         if (!thread_create_object(t, name, threadgroup_main))
249                 vm_abort("thread_create_initial_thread: failed to create Java object");
250
251         /* Initialize the implementation specific bits. */
252
253         threads_impl_init();
254
255         DEBUGTHREADS("starting (main)", t);
256 }
257
258
259 /* thread_new ******************************************************************
260
261    Allocates and initializes an internal thread data-structure and
262    adds it to the threads list.
263
264 *******************************************************************************/
265
266 static threadobject *thread_new(int32_t flags)
267 {
268         int32_t       index;
269         threadobject *t;
270         
271         /* Lock the thread lists */
272
273         ThreadList::lock();
274
275         index = ThreadList::get_free_thread_index();
276
277         /* Allocate a thread data structure. */
278
279         /* First, try to get one from the free-list. */
280
281         t = ThreadList::get_free_thread();
282
283         if (t != NULL) {
284                 /* Equivalent of MZERO on the else path */
285
286                 threads_impl_thread_clear(t);
287         }
288         else {
289 #if defined(ENABLE_GC_BOEHM)
290                 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
291 #else
292                 t = NEW(threadobject);
293 #endif
294
295 #if defined(ENABLE_STATISTICS)
296                 if (opt_stat)
297                         size_threadobject += sizeof(threadobject);
298 #endif
299
300                 /* Clear memory. */
301
302                 MZERO(t, threadobject, 1);
303
304                 // Initialize the mutex and the condition.
305                 t->flc_lock = new Mutex();
306                 t->flc_cond = new Condition();
307
308                 t->waitmutex = new Mutex();
309                 t->waitcond = new Condition();
310
311                 t->suspendmutex = new Mutex();
312                 t->suspendcond = new Condition();
313
314 #if defined(ENABLE_TLH)
315                 tlh_init(&(t->tlh));
316 #endif
317
318 #if defined(ENABLE_GC_CACAO)
319                 /* Register reference to java.lang.Thread with the GC. */
320                 /* FIXME is it ok to do this only once? */
321
322                 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
323                 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
324 #endif
325
326                 t->_dumpmemory = new DumpMemory();
327         }
328
329         /* Pre-compute the thinlock-word. */
330
331         assert(index != 0);
332
333         t->index     = index;
334         t->thinlock  = Lockword::pre_compute_thinlock(t->index);
335         t->flags     = flags;
336         t->state     = THREAD_STATE_NEW;
337
338 #if defined(ENABLE_GC_CACAO)
339         t->flags    |= THREAD_FLAG_IN_NATIVE; 
340 #endif
341
342         /* Initialize the implementation-specific bits. */
343
344         threads_impl_thread_reuse(t);
345
346         /* Add the thread to the thread list. */
347
348         ThreadList::add_to_active_thread_list(t);
349
350         /* Unlock the thread lists. */
351
352         ThreadList::unlock();
353
354         return t;
355 }
356
357
358 /* thread_free *****************************************************************
359
360    Remove the thread from the threads-list and free the internal
361    thread data structure.  The thread index is added to the
362    thread-index free-list.
363
364    IN:
365        t ... thread data structure
366
367 *******************************************************************************/
368
369 void thread_free(threadobject *t)
370 {
371         /* Set the reference to the Java object to NULL. */
372
373         thread_set_object(t, NULL);
374
375         /* Release the thread. */
376
377         ThreadList::release_thread(t);
378 }
379
380
381 /* threads_thread_start_internal ***********************************************
382
383    Start an internal thread in the JVM.  No Java thread objects exists
384    so far.
385
386    IN:
387       name.......UTF-8 name of the thread
388       f..........function pointer to C function to start
389
390 *******************************************************************************/
391
392 bool threads_thread_start_internal(utf *name, functionptr f)
393 {
394         threadobject *t;
395
396         /* Enter the join-mutex, so if the main-thread is currently
397            waiting to join all threads, the number of non-daemon threads
398            is correct. */
399
400         threads_mutex_join_lock();
401
402         /* Create internal thread data-structure. */
403
404         t = thread_new(THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON);
405
406         /* The thread is flagged as (non-)daemon thread, we can leave the
407            mutex. */
408
409         threads_mutex_join_unlock();
410
411         /* Create the Java thread object. */
412
413         if (!thread_create_object(t, javastring_new(name), threadgroup_system))
414                 return false;
415
416         /* Start the thread. */
417
418         threads_impl_thread_start(t, f);
419
420         /* everything's ok */
421
422         return true;
423 }
424
425
426 /* threads_thread_start ********************************************************
427
428    Start a Java thread in the JVM.  Only the java thread object exists
429    so far.
430
431    IN:
432       object.....the java thread object java.lang.Thread
433
434 *******************************************************************************/
435
436 void threads_thread_start(java_handle_t *object)
437 {
438         java_lang_Thread jlt(object);
439
440         /* Enter the join-mutex, so if the main-thread is currently
441            waiting to join all threads, the number of non-daemon threads
442            is correct. */
443
444         threads_mutex_join_lock();
445
446         /* Create internal thread data-structure. */
447
448         threadobject* t = thread_new(THREAD_FLAG_JAVA);
449
450 #if defined(ENABLE_JAVASE)
451         /* Is this a daemon thread? */
452
453         if (jlt.get_daemon() == true)
454                 t->flags |= THREAD_FLAG_DAEMON;
455 #endif
456
457         /* The thread is flagged and (non-)daemon thread, we can leave the
458            mutex. */
459
460         threads_mutex_join_unlock();
461
462         /* Link the two objects together. */
463
464         thread_set_object(t, object);
465
466         ThreadRuntime::setup_thread_vmdata(jlt, t);
467
468         /* Start the thread.  Don't pass a function pointer (NULL) since
469            we want Thread.run()V here. */
470
471         threads_impl_thread_start(t, NULL);
472 }
473
474
475 /**
476  * Attaches the current thread to the VM.
477  *
478  * @param vm_aargs Attach arguments.
479  * @param isdaemon true if the attached thread should be a daemon
480  *                 thread.
481  *
482  * @return true on success, false otherwise.
483  */
484 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
485 {
486         bool           result;
487         threadobject  *t;
488         utf           *u;
489         java_handle_t *name;
490         java_handle_t *group;
491
492     /* If the current thread has already been attached, this operation
493            is a no-op. */
494
495         result = thread_current_is_attached();
496
497         if (result == true)
498                 return true;
499
500         /* Enter the join-mutex, so if the main-thread is currently
501            waiting to join all threads, the number of non-daemon threads
502            is correct. */
503
504         threads_mutex_join_lock();
505
506         /* Create internal thread data structure. */
507
508         t = thread_new(THREAD_FLAG_JAVA);
509
510         if (isdaemon)
511                 t->flags |= THREAD_FLAG_DAEMON;
512
513         /* Store the internal thread data-structure in the TSD. */
514
515         thread_set_current(t);
516
517         /* The thread is flagged and (non-)daemon thread, we can leave the
518            mutex. */
519
520         threads_mutex_join_unlock();
521
522         DEBUGTHREADS("attaching", t);
523
524         /* Get the thread name. */
525
526         if (vm_aargs != NULL) {
527                 u = utf_new_char(vm_aargs->name);
528         }
529         else {
530                 u = utf_null;
531         }
532
533         name = javastring_new(u);
534
535 #if defined(ENABLE_JAVASE)
536         /* Get the threadgroup. */
537
538         if (vm_aargs != NULL)
539                 group = (java_handle_t *) vm_aargs->group;
540         else
541                 group = NULL;
542
543         /* If no threadgroup was given, use the main threadgroup. */
544
545         if (group == NULL)
546                 group = threadgroup_main;
547 #endif
548
549 #if defined(ENABLE_INTRP)
550         /* create interpreter stack */
551
552         if (opt_intrp) {
553                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
554                 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
555         }
556 #endif
557
558         /* Create the Java thread object. */
559
560         if (!thread_create_object(t, name, group))
561                 return false;
562
563         /* The thread is completely initialized. */
564
565         thread_set_state_runnable(t);
566
567         return true;
568 }
569
570
571 /**
572  * Attaches the current external thread to the VM.  This function is
573  * called by JNI's AttachCurrentThread.
574  *
575  * @param vm_aargs Attach arguments.
576  * @param isdaemon true if the attached thread should be a daemon
577  *                 thread.
578  *
579  * @return true on success, false otherwise.
580  */
581 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
582 {
583         int result;
584
585 #if defined(ENABLE_GC_BOEHM)
586         struct GC_stack_base sb;
587
588         /* Register the thread with Boehm-GC.  This must happen before the
589            thread allocates any memory from the GC heap.*/
590
591         result = GC_get_stack_base(&sb);
592
593         if (result != GC_SUCCESS)
594                 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
595
596         GC_register_my_thread(&sb);
597 #endif
598
599         result = thread_attach_current_thread(vm_aargs, isdaemon);
600
601         if (result == false) {
602 #if defined(ENABLE_GC_BOEHM)
603                 /* Unregister the thread. */
604
605                 GC_unregister_my_thread();
606 #endif
607
608                 return false;
609         }
610
611         return true;
612 }
613
614
615 /**
616  * Detaches the current external thread from the VM.  This function is
617  * called by JNI's DetachCurrentThread.
618  *
619  * @return true on success, false otherwise.
620  */
621 bool thread_detach_current_external_thread(void)
622 {
623         int result;
624
625         result = thread_detach_current_thread();
626
627         if (result == false)
628                 return false;
629
630 #if defined(ENABLE_GC_BOEHM)
631         /* Unregister the thread with Boehm-GC.  This must happen after
632            the thread allocates any memory from the GC heap. */
633
634         /* Don't detach the main thread.  This is a workaround for
635            OpenJDK's java launcher. */
636         if (thread_get_current()->index != 1)
637                 GC_unregister_my_thread();
638 #endif
639
640         return true;
641 }
642
643
644 /* thread_fprint_name **********************************************************
645
646    Print the name of the given thread to the given stream.
647
648    ARGUMENTS:
649        t ........ thread data-structure
650        stream ... stream to print to
651
652 *******************************************************************************/
653
654 void thread_fprint_name(threadobject *t, FILE *stream)
655 {
656         if (thread_get_object(t) == NULL)
657                 vm_abort("");
658
659         java_lang_Thread jlt(thread_get_object(t));
660
661         ThreadRuntime::print_thread_name(jlt, stream);
662 }
663
664
665 /* thread_print_info ***********************************************************
666
667    Print information of the passed thread.
668
669    ARGUMENTS:
670        t ... thread data-structure.
671
672 *******************************************************************************/
673
674 void thread_print_info(threadobject *t)
675 {
676         java_lang_Thread jlt(thread_get_object(t));
677
678         /* Print as much as we can when we are in state NEW. */
679
680         if (jlt.get_handle() != NULL) {
681                 /* Print thread name. */
682
683                 printf("\"");
684                 thread_fprint_name(t, stdout);
685                 printf("\"");
686         }
687         else {
688         }
689
690         if (thread_is_daemon(t))
691                 printf(" daemon");
692
693         if (jlt.get_handle() != NULL) {
694                 printf(" prio=%d", jlt.get_priority());
695         }
696
697 #if SIZEOF_VOID_P == 8
698         printf(" t=0x%016lx tid=0x%016lx (%ld)",
699                    (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
700 #else
701         printf(" t=0x%08x tid=0x%08x (%d)",
702                    (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
703 #endif
704
705         printf(" index=%d", t->index);
706
707         /* Print thread state. */
708
709         int state = cacaothread_get_state(t);
710
711         switch (state) {
712         case THREAD_STATE_NEW:
713                 printf(" new");
714                 break;
715         case THREAD_STATE_RUNNABLE:
716                 printf(" runnable");
717                 break;
718         case THREAD_STATE_BLOCKED:
719                 printf(" blocked");
720                 break;
721         case THREAD_STATE_WAITING:
722                 printf(" waiting");
723                 break;
724         case THREAD_STATE_TIMED_WAITING:
725                 printf(" waiting on condition");
726                 break;
727         case THREAD_STATE_PARKED:
728                 printf(" parked");
729                 break;
730         case THREAD_STATE_TIMED_PARKED:
731                 printf(" timed parked");
732                 break;
733         case THREAD_STATE_TERMINATED:
734                 printf(" terminated");
735                 break;
736         default:
737                 vm_abort("thread_print_info: unknown thread state %d", state);
738         }
739 }
740
741
742 /* threads_get_current_tid *****************************************************
743
744    Return the tid of the current thread.
745    
746    RETURN VALUE:
747        the current tid
748
749 *******************************************************************************/
750
751 intptr_t threads_get_current_tid(void)
752 {
753         threadobject *thread;
754
755         thread = THREADOBJECT;
756
757         /* this may happen during bootstrap */
758
759         if (thread == NULL)
760                 return 0;
761
762         return (intptr_t) thread->tid;
763 }
764
765
766 /**
767  * Set the current state of the given thread. This method should only
768  * be called while holding the threadlist-lock and after checking that
769  * the new state is valid. It is best to not call this method directly
770  * but call the specific setter methods below.
771  */
772 static inline void thread_set_state(threadobject *t, int state)
773 {
774         // Set the state of our internal threadobject.
775         t->state = state;
776
777         ThreadRuntime::set_javathread_state(t, state);
778 }
779
780
781 /* thread_set_state_runnable ***************************************************
782
783    Set the current state of the given thread to THREAD_STATE_RUNNABLE.
784
785    NOTE: If the thread has already terminated, don't set the state.
786          This is important for threads_detach_thread.
787
788 *******************************************************************************/
789
790 void thread_set_state_runnable(threadobject *t)
791 {
792         if (t->state != THREAD_STATE_TERMINATED) {
793                 thread_set_state(t, THREAD_STATE_RUNNABLE);
794
795                 DEBUGTHREADS("is RUNNABLE", t);
796         }
797 }
798
799
800 /* thread_set_state_waiting ****************************************************
801
802    Set the current state of the given thread to THREAD_STATE_WAITING.
803
804    NOTE: If the thread has already terminated, don't set the state.
805          This is important for threads_detach_thread.
806
807 *******************************************************************************/
808
809 void thread_set_state_waiting(threadobject *t)
810 {
811         if (t->state != THREAD_STATE_TERMINATED) {
812                 thread_set_state(t, THREAD_STATE_WAITING);
813
814                 DEBUGTHREADS("is WAITING", t);
815         }
816 }
817
818
819 /* thread_set_state_timed_waiting **********************************************
820
821    Set the current state of the given thread to
822    THREAD_STATE_TIMED_WAITING.
823
824    NOTE: If the thread has already terminated, don't set the state.
825          This is important for threads_detach_thread.
826
827 *******************************************************************************/
828
829 void thread_set_state_timed_waiting(threadobject *t)
830 {
831         if (t->state != THREAD_STATE_TERMINATED) {
832                 thread_set_state(t, THREAD_STATE_TIMED_WAITING);
833
834                 DEBUGTHREADS("is TIMED_WAITING", t);
835         }
836 }
837
838
839 /* thread_set_state_parked *****************************************************
840
841    Set the current state of the given thread to THREAD_STATE_PARKED.
842
843    NOTE: If the thread has already terminated, don't set the state.
844          This is important for threads_detach_thread.
845
846 *******************************************************************************/
847
848 void thread_set_state_parked(threadobject *t)
849 {
850         if (t->state != THREAD_STATE_TERMINATED) {
851                 thread_set_state(t, THREAD_STATE_PARKED);
852
853                 DEBUGTHREADS("is PARKED", t);
854         }
855 }
856
857
858 /* thread_set_state_timed_parked ***********************************************
859
860    Set the current state of the given thread to THREAD_STATE_TIMED_PARKED.
861
862    NOTE: If the thread has already terminated, don't set the state.
863          This is important for threads_detach_thread.
864
865 *******************************************************************************/
866
867 void thread_set_state_timed_parked(threadobject *t)
868 {
869         if (t->state != THREAD_STATE_TERMINATED) {
870                 thread_set_state(t, THREAD_STATE_TIMED_PARKED);
871
872                 DEBUGTHREADS("is TIMED_PARKED", t);
873         }
874 }
875
876
877 /* thread_set_state_terminated *************************************************
878
879    Set the current state of the given thread to
880    THREAD_STATE_TERMINATED.
881
882 *******************************************************************************/
883
884 void thread_set_state_terminated(threadobject *t)
885 {
886         /* Set the state inside a lock. */
887
888         ThreadList::lock();
889
890         thread_set_state(t, THREAD_STATE_TERMINATED);
891
892         DEBUGTHREADS("is TERMINATED", t);
893
894         ThreadList::unlock();
895 }
896
897
898 /* thread_get_thread **********************************************************
899
900    Return the thread data structure of the given Java thread object.
901
902    ARGUMENTS:
903        h ... java.lang.{VM}Thread object
904
905    RETURN VALUE:
906        the thread object
907
908    NOTE:
909        Usage of this function without the thread list lock held is
910        almost certainly a bug.
911
912 *******************************************************************************/
913
914 threadobject *thread_get_thread(java_handle_t *h)
915 {
916         return ThreadRuntime::get_threadobject_from_thread(h);
917 }
918
919
920 /* threads_thread_is_alive *****************************************************
921
922    Returns if the give thread is alive.
923
924 *******************************************************************************/
925
926 bool threads_thread_is_alive(threadobject *t)
927 {
928         int state;
929
930         state = cacaothread_get_state(t);
931
932         switch (state) {
933         case THREAD_STATE_NEW:
934         case THREAD_STATE_TERMINATED:
935                 return false;
936
937         case THREAD_STATE_RUNNABLE:
938         case THREAD_STATE_BLOCKED:
939         case THREAD_STATE_WAITING:
940         case THREAD_STATE_TIMED_WAITING:
941         case THREAD_STATE_PARKED:
942         case THREAD_STATE_TIMED_PARKED:
943                 return true;
944
945         default:
946                 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
947         }
948
949         /* keep compiler happy */
950
951         return false;
952 }
953
954 /* thread_is_interrupted *******************************************************
955
956    Check if the given thread has been interrupted.
957
958    ARGUMENTS:
959        t ... the thread to check
960
961    RETURN VALUE:
962       true, if the given thread had been interrupted
963
964 *******************************************************************************/
965
966 bool thread_is_interrupted(threadobject *t)
967 {
968         /* We need the mutex because classpath will call this function when
969            a blocking system call is interrupted. The mutex ensures that it will
970            see the correct value for the interrupted flag. */
971
972         t->waitmutex->lock();
973         bool interrupted = t->interrupted;
974         t->waitmutex->unlock();
975
976         return interrupted;
977 }
978
979
980 /* thread_set_interrupted ******************************************************
981
982    Set the interrupted flag to the given value.
983
984    ARGUMENTS:
985        interrupted ... value to set
986
987 *******************************************************************************/
988
989 void thread_set_interrupted(threadobject *t, bool interrupted)
990 {
991         t->waitmutex->lock();
992         t->interrupted = interrupted;
993         t->waitmutex->unlock();
994 }
995
996 /* thread_handle_set_priority **************************************************
997
998    Calls threads_set_thread_priority for the threadobject associated
999    with the thread indicated by handle th, while holding the thread
1000    list lock.
1001
1002 *******************************************************************************/
1003
1004 void thread_handle_set_priority(java_handle_t *th, int priority)
1005 {
1006         ThreadListLocker l;
1007         
1008         threadobject *t = thread_get_thread(th);
1009         /* For GNU classpath, this should not happen, because both
1010            setPriority() and start() are synchronized. */
1011         assert(t != 0);
1012         threads_set_thread_priority(t->tid, priority);
1013 }
1014
1015 /* thread_handle_is_interrupted ************************************************
1016
1017    Calls thread_is_interrupted for the threadobject associated with
1018    the thread indicated by handle th, while holding the thread list
1019    lock.
1020
1021 *******************************************************************************/
1022
1023 bool thread_handle_is_interrupted(java_handle_t *th)
1024 {
1025         ThreadListLocker l;
1026         
1027         threadobject *t = thread_get_thread(th);
1028         return t ? thread_is_interrupted(t) : false;
1029 }
1030
1031 /* thread_handle_interrupt *****************************************************
1032
1033    Calls threads_thread_interrupt for the threadobject associated with
1034    the thread indicated by handle th, while holding the thread list
1035    lock.
1036
1037 *******************************************************************************/
1038
1039 void thread_handle_interrupt(java_handle_t *th)
1040 {
1041         ThreadListLocker l;
1042         
1043         threadobject *t = thread_get_thread(th);
1044         /* For GNU classpath, this should not happen, because both
1045            interrupt() and start() are synchronized. */
1046         assert(t != 0);
1047         threads_thread_interrupt(t);
1048 }
1049
1050 /* thread_handle_get_state *****************************************************
1051
1052    Calls cacaothread_get_state for the threadobject associated with
1053    the thread indicated by handle th, while holding the thread list
1054    lock.
1055
1056 *******************************************************************************/
1057
1058 int thread_handle_get_state(java_handle_t *th)
1059 {
1060         ThreadListLocker l;
1061
1062         threadobject *t = thread_get_thread(th);
1063         return t ? cacaothread_get_state(t) : THREAD_STATE_NEW;
1064 }
1065
1066
1067 /*
1068  * These are local overrides for various environment variables in Emacs.
1069  * Please do not remove this and leave it at the end of the file, where
1070  * Emacs will automagically detect them.
1071  * ---------------------------------------------------------------------
1072  * Local variables:
1073  * mode: c++
1074  * indent-tabs-mode: t
1075  * c-basic-offset: 4
1076  * tab-width: 4
1077  * End:
1078  * vim:noexpandtab:sw=4:ts=4:
1079  */