LCOV - code coverage report
Current view: top level - threads - thread.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 16 19 84.2 %
Date: 2017-07-14 10:03:36 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /* src/threads/thread.hpp - 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             : 
      26             : #ifndef THREAD_HPP_
      27             : #define THREAD_HPP_ 1
      28             : 
      29             : #include "config.h"
      30             : 
      31             : #include "native/llni.hpp"
      32             : #include "vm/global.hpp"
      33             : #include "vm/options.hpp"    // for opt_DebugThreads
      34             : #include "vm/os.hpp"
      35             : #include "vm/types.hpp"
      36             : #include "vm/utf8.hpp"       // for Utf8String
      37             : 
      38             : class  Condition;
      39             : class  DumpMemory;
      40             : struct localref_table;
      41             : class  Mutex;
      42             : struct stackframeinfo_t;
      43             : struct JavaVMAttachArgs;
      44             : 
      45             : /* thread states **************************************************************/
      46             : 
      47             : enum ThreadState {
      48             :         THREAD_STATE_NEW           = 0,
      49             :         THREAD_STATE_RUNNABLE      = 1,
      50             :         THREAD_STATE_BLOCKED       = 2,
      51             :         THREAD_STATE_WAITING       = 3,
      52             :         THREAD_STATE_TIMED_WAITING = 4,
      53             :         THREAD_STATE_TERMINATED    = 5,
      54             :         THREAD_STATE_PARKED        = 6,
      55             :         THREAD_STATE_TIMED_PARKED  = 7
      56             : };
      57             : 
      58             : enum ThreadFlag {
      59             :   THREAD_FLAG_JAVA      = 0x01,   // a normal Java thread
      60             :   THREAD_FLAG_INTERNAL  = 0x02,   // CACAO internal thread
      61             :   THREAD_FLAG_DAEMON    = 0x04,   // daemon thread
      62             :   THREAD_FLAG_IN_NATIVE = 0x08    // currently executing native code
      63             : };
      64             : 
      65             : enum SuspendReason {
      66             :   SUSPEND_REASON_NONE      = 0,   // no reason to suspend
      67             :   SUSPEND_REASON_JAVA      = 1,   // suspended from java.lang.Thread
      68             :   SUSPEND_REASON_STOPWORLD = 2,   // suspended from stop-the-world
      69             :   SUSPEND_REASON_DUMP      = 3,   // suspended from threadlist dumping
      70             :   SUSPEND_REASON_JVMTI     = 4    // suspended from JVMTI agent
      71             : };
      72             : 
      73             : /* thread priorities **********************************************************/
      74             : 
      75             : enum ThreadPriority {
      76             :         MIN_PRIORITY  =  1,
      77             :         NORM_PRIORITY =  5,
      78             :         MAX_PRIORITY  = 10
      79             : };
      80             : 
      81             : /* threadobject ***************************************************************/
      82             : 
      83             : #if defined(ENABLE_THREADS)
      84             : # include "threads/posix/threadobject.hpp"
      85             : #else
      86             : # include "threads/none/threadobject.hpp"
      87             : #endif
      88             : 
      89             : struct threadobject {
      90             :         //*****  platform specific thread data
      91             :         cacao::detail::threadobject impl;
      92             : 
      93             :         java_object_t        *object;       /* link to java.lang.Thread object    */
      94             : 
      95             :         ptrint                thinlock;     /* pre-computed thin lock value       */
      96             :         u4                    flags;        /* flag field                         */
      97             :         ThreadState           state;        /* state field                        */
      98             :         
      99             :         //***** for ThreadList
     100             :         bool                  is_in_active_list; /* for debugging only            */
     101             :         s4                    index;        /* thread index, starting with 1      */
     102             : 
     103             :         //***** for the sable tasuki lock extension */
     104             :         bool                  flc_bit;
     105             :         struct threadobject  *flc_list;     /* FLC list head for this thread      */
     106             :         struct threadobject  *flc_tail;     /* tail pointer for FLC list          */
     107             :         struct threadobject  *flc_next;     /* next pointer for FLC list          */
     108             :         java_handle_t        *flc_object;
     109             :         Mutex*                flc_lock;     /* controlling access to these fields */
     110             :         Condition*            flc_cond;
     111             : 
     112             :         //***** these are used for the wait/notify implementation
     113             :         Mutex*                waitmutex;
     114             :         Condition*            waitcond;
     115             : 
     116             :         Mutex*                suspendmutex; /* lock before suspending this thread */
     117             :         Condition*            suspendcond;  /* notify to resume this thread       */
     118             : 
     119             :         bool                  interrupted;
     120             :         bool                  signaled;
     121             :         bool                  park_permit;
     122             : 
     123             :         bool                  suspended;    /* is this thread suspended?          */
     124             :         SuspendReason         suspend_reason; /* reason for suspending            */
     125             : 
     126             :         u1                   *pc;           /* current PC (used for profiling)    */
     127             : 
     128             :         java_object_t        *_exceptionptr;     /* current exception             */
     129             :         stackframeinfo_t     *_stackframeinfo;   /* current native stackframeinfo */
     130             :         localref_table       *_localref_table;   /* JNI local references          */
     131             : 
     132             : #if defined(ENABLE_INTRP)
     133             :         Cell                 *_global_sp;        /* stack pointer for interpreter */
     134             : #endif
     135             : 
     136             : #if defined(ENABLE_GC_CACAO)
     137             :         bool                  gc_critical;  /* indicates a critical section       */
     138             : 
     139             :         sourcestate_t        *ss;
     140             :         executionstate_t     *es;
     141             : #endif
     142             : 
     143             :         DumpMemory*          _dumpmemory;     ///< Dump memory structure.
     144             : 
     145             : #if defined(ENABLE_DEBUG_FILTER)
     146             :         u2                    filterverbosecallctr[2]; /* counters for verbose call filter */
     147             : #endif
     148             : 
     149             : #if !defined(NDEBUG)
     150             :         s4                    tracejavacallindent;
     151             :         u4                    tracejavacallcount;
     152             : #endif
     153             : 
     154             : #if defined(ENABLE_TLH)
     155             :         tlh_t                 tlh;
     156             : #endif
     157             : 
     158             : #if defined(ENABLE_ESCAPE_REASON)
     159             :         void *escape_reasons;
     160             : #endif
     161             : };
     162             : 
     163             : /* debug **********************************************************************/
     164             : 
     165             : #if !defined(NDEBUG)
     166             : # define DEBUGTHREADS(message, thread) \
     167             :         do { \
     168             :                 if (opt_DebugThreads) { \
     169             :                         printf("[Thread %-16s: ", message); \
     170             :                         thread_print_info(thread); \
     171             :                         printf("]\n"); \
     172             :                 } \
     173             :         } while (0)
     174             : #else
     175             : # define DEBUGTHREADS(message, thread)
     176             : #endif
     177             : 
     178             : 
     179             : /* global variables ***********************************************************/
     180             : 
     181             : #if defined(__LINUX__)
     182             : /* XXX Remove for exact-GC. */
     183             : extern bool threads_pthreads_implementation_nptl;
     184             : #endif
     185             : 
     186             : 
     187             : /* state for trace java call **************************************************/
     188             : 
     189             : #if !defined(NDEBUG)
     190             : #       define TRACEJAVACALLINDENT (THREADOBJECT->tracejavacallindent)
     191             : #       define TRACEJAVACALLCOUNT  (THREADOBJECT->tracejavacallcount)
     192             : #endif
     193             : 
     194             : 
     195             : /* counter for verbose call filter ********************************************/
     196             : 
     197             : #if defined(ENABLE_DEBUG_FILTER)
     198             : #       define FILTERVERBOSECALLCTR (THREADOBJECT->filterverbosecallctr)
     199             : #endif
     200             : 
     201             : 
     202             : /* native-world flags *********************************************************/
     203             : 
     204             : #if defined(ENABLE_GC_CACAO)
     205             : # define THREAD_NATIVEWORLD_ENTER THREADOBJECT->flags |=  THREAD_FLAG_IN_NATIVE
     206             : # define THREAD_NATIVEWORLD_EXIT  THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE
     207             : #else
     208             : # define THREAD_NATIVEWORLD_ENTER /*nop*/
     209             : # define THREAD_NATIVEWORLD_EXIT  /*nop*/
     210             : #endif
     211             : 
     212             : 
     213             : /* inline functions ***********************************************************/
     214             : 
     215             : inline static threadobject* thread_get_current(void);
     216             : 
     217             : #if defined(ENABLE_THREADS)
     218             : # include "threads/posix/thread-posix.hpp"
     219             : #else
     220             : # include "threads/none/thread-none.hpp"
     221             : #endif
     222             : 
     223             : /***
     224             :  * Return the java.lang.Thread object for the current thread.
     225             :  */
     226       21990 : inline static java_handle_t *thread_get_current_object(void) {
     227       21990 :         return LLNI_WRAP(thread_get_current()->object);
     228             : }
     229             : 
     230             : 
     231             : /* cacaothread_get_state *******************************************************
     232             : 
     233             :    Returns the current state of the given thread.
     234             : 
     235             :    ARGUMENTS:
     236             :        t ... the thread to check
     237             : 
     238             :    RETURN:
     239             :        thread state
     240             : 
     241             : *******************************************************************************/
     242             : 
     243           0 : inline static int cacaothread_get_state(threadobject *t)
     244             : {
     245           0 :         return t->state;
     246             : }
     247             : 
     248             : 
     249             : /* thread_is_attached **********************************************************
     250             : 
     251             :    Returns if the given thread is attached to the VM.
     252             : 
     253             :    ARGUMENTS:
     254             :        t ... the thread to check
     255             : 
     256             :    RETURN:
     257             :        true .... the thread is attached to the VM
     258             :        false ... the thread is not
     259             : 
     260             : *******************************************************************************/
     261             : 
     262         413 : inline static bool thread_is_attached(threadobject *t)
     263             : {
     264             :         java_handle_t *o;
     265             : 
     266         413 :         o = LLNI_WRAP(t->object);
     267             : 
     268         413 :         return o != NULL;
     269             : }
     270             : 
     271             : 
     272             : /* thread_is_daemon ************************************************************
     273             : 
     274             :    Returns if the given thread is a daemon thread.
     275             : 
     276             :    ARGUMENTS:
     277             :        t ... the thread to check
     278             : 
     279             :    RETURN:
     280             :        true .... the thread is a daemon thread
     281             :        false ... the thread is not
     282             : 
     283             : *******************************************************************************/
     284             : 
     285        1307 : inline static bool thread_is_daemon(threadobject *t)
     286             : {
     287        1307 :         return (t->flags & THREAD_FLAG_DAEMON) != 0;
     288             : }
     289             : 
     290             : 
     291             : /* thread_current_is_attached **************************************************
     292             : 
     293             :    Returns if the current thread is attached to the VM.
     294             : 
     295             :    RETURN:
     296             :        true .... the thread is attached to the VM
     297             :        false ... the thread is not
     298             : 
     299             : *******************************************************************************/
     300             : 
     301         131 : inline static bool thread_current_is_attached(void)
     302             : {
     303             :         threadobject  *t;
     304             : 
     305         131 :         t = thread_get_current();
     306             : 
     307         131 :         if (t == NULL)
     308           0 :                 return false;
     309             : 
     310         131 :         return thread_is_attached(t);
     311             : }
     312             : 
     313     3378134 : inline static struct stackframeinfo_t* threads_get_current_stackframeinfo(void)
     314             : {
     315     3378134 :         return THREADOBJECT->_stackframeinfo;
     316             : }
     317             : 
     318     6709995 : inline static void threads_set_current_stackframeinfo(struct stackframeinfo_t* sfi)
     319             : {
     320     6709995 :         THREADOBJECT->_stackframeinfo = sfi;
     321     6709995 : }
     322             : 
     323             : 
     324             : /* function prototypes ********************************************************/
     325             : 
     326             : void          threads_preinit(void);
     327             : void          threads_init(void);
     328             : 
     329             : void          thread_free(threadobject *t);
     330             : 
     331             : bool          threads_thread_start_internal(Utf8String name, functionptr f);
     332             : void          threads_thread_start(java_handle_t *object);
     333             : 
     334             : bool          thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
     335             : bool          thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
     336             : bool          thread_detach_current_thread(void);
     337             : 
     338             : bool          thread_detach_current_external_thread(void);
     339             : 
     340             : void          thread_fprint_name(threadobject *t, FILE *stream);
     341             : void          thread_print_info(threadobject *t);
     342             : 
     343             : intptr_t      threads_get_current_tid(void);
     344             : intptr_t      threads_get_tid(threadobject*);
     345             : 
     346             : void          thread_set_state_runnable(threadobject *t);
     347             : void          thread_set_state_waiting(threadobject *t);
     348             : void          thread_set_state_timed_waiting(threadobject *t);
     349             : void          thread_set_state_parked(threadobject *t);
     350             : void          thread_set_state_timed_parked(threadobject *t);
     351             : void          thread_set_state_terminated(threadobject *t);
     352             : 
     353             : threadobject *thread_get_thread(java_handle_t *h);
     354             : 
     355             : bool          threads_thread_is_alive(threadobject *t);
     356             : bool          thread_is_interrupted(threadobject *t);
     357             : void          thread_set_interrupted(threadobject *t, bool interrupted);
     358             : void          threads_thread_interrupt(threadobject *thread);
     359             : 
     360             : 
     361             : void threads_start_thread(threadobject *thread, functionptr function);
     362             : 
     363             : void threads_set_thread_priority(threadobject *t, int priority);
     364             : 
     365             : bool threads_suspend_thread(threadobject *thread, SuspendReason reason);
     366             : bool threads_resume_thread(threadobject *thread, SuspendReason reason);
     367             : void threads_suspend_ack();
     368             : 
     369             : void threads_join_all_threads(void);
     370             : 
     371             : void threads_sleep(int64_t millis, int32_t nanos);
     372             : 
     373             : void threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
     374             : 
     375             : void threads_park(bool absolute, int64_t nanos);
     376             : void threads_unpark(threadobject *thread);
     377             : 
     378             : #if defined(ENABLE_TLH)
     379             : void threads_tlh_add_frame();
     380             : void threads_tlh_remove_frame();
     381             : #endif
     382             : 
     383             : /* implementation specific functions */
     384             : 
     385             : void          threads_impl_preinit(void);
     386             : void          threads_impl_init(void);
     387             : 
     388             : #if defined(ENABLE_GC_CACAO)
     389             : void          threads_mutex_gc_lock(void);
     390             : void          threads_mutex_gc_unlock(void);
     391             : #endif
     392             : 
     393             : void          threads_impl_thread_clear(threadobject *t);
     394             : void          threads_impl_thread_reuse(threadobject *t);
     395             : void          threads_impl_clear_heap_pointers(threadobject *t);
     396             : void          threads_impl_thread_start(threadobject *thread, functionptr f);
     397             : 
     398             : void          threads_yield(void);
     399             : 
     400             : void          thread_handle_set_priority(java_handle_t *th, int);
     401             : bool          thread_handle_is_interrupted(java_handle_t *th);
     402             : void          thread_handle_interrupt(java_handle_t *th);
     403             : int           thread_handle_get_state(java_handle_t *th);
     404             : 
     405             : #endif // THREAD_HPP_
     406             : 
     407             : 
     408             : /*
     409             :  * These are local overrides for various environment variables in Emacs.
     410             :  * Please do not remove this and leave it at the end of the file, where
     411             :  * Emacs will automagically detect them.
     412             :  * ---------------------------------------------------------------------
     413             :  * Local variables:
     414             :  * mode: c++
     415             :  * indent-tabs-mode: t
     416             :  * c-basic-offset: 4
     417             :  * tab-width: 4
     418             :  * End:
     419             :  * vim:noexpandtab:sw=4:ts=4:
     420             :  */

Generated by: LCOV version 1.11