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