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