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