LCOV - code coverage report
Current view: top level - threads - thread.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 148 249 59.4 %
Date: 2015-06-10 18:10:59 Functions: 18 30 60.0 %

          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             :  */

Generated by: LCOV version 1.11