vm/include/open/hythread_ext.h (267 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief Extended Treading and synchronization support
* @details
* Thread Manager native interface. Provides basic capablitites for managing native threads in the system.
*
* <p>
* <h2>Overview</h2>
* The Thread Manager (TM) component provides various threading functionality for VM and class libraries code.
* provides support for threading inside the virtual machine and for class libraries.
* The implementation of thread management uses the black-box approach exposing two interfaces: Java and native.
* The whole component is divided into two layers: the middle layer of native threading with the layer of
* Java threading on top. The implementation of Thread manager is based solely on the Apache Portable Runtime (APR) layer.
* <p>
* The top layer provides the following functionality (see jthread, thread_ti.h):
* <ul>
* <li> Maps Java threads onto OS native threads
* <li> Support kernel classes support
* <li> Support JVMTI
* </ul>
* The middle layer does the following (see hythread.h, hythread_ext.h):
* <ul>
* <li> Provides API for native threading
* <li> Wrapping 223shield224 on top of porting layer
* <li> Provides support for safe suspension and interrupt
* <li> Additional functionality that missed in porting layer
* </ul>
* <p>
*
* <h2>Interaction</h2>
* The following components are primary customers of the Thread Manager:
* <ul>
* <li> Kernel classes
* <li> Garbage collector
* <li> java.util.concurrent classes
* <li> java.lang.management classes
* <li> JVMTI
* </ul>
* These components interact with different parts of thread management: some work with Java threads and objects,
* while others interact with the middle layer of native threading. Whenever the component operates with Java
* objects and threads, it would call the top (Java) interface functions. Otherwise, it would call the middle (native)
* interface functions.
* <h2>Safe suspension</h2>
* One of the key features of thread management in the VM is the safe suspension functionality.
* The purpose of the safe suspension mechanism is mostly to ensure that:
* <ul>
* <li> Suspended thread can be safely explored by the Garbage Collector while enumerating live references;
* <li> Suspended thread is guaranteed to do not hold any system-critical locks which can be requested by the other parts of VM,
* such as the locks associated with the native memory heap.
* </ul>
* At every time moment, thread can be in one of three possible states:
* <ul>
* <li> Safe region. A period of time during thread execution when the thread can be safely suspended. This would typically be a region of a
native C code where java objects and stack are not changed. An example is native file I/O call which reads a big amount of data from disk.
* <li> Unsafe region. A period of time during thread execution when the code is in process of changing java objects or impacts java stack,
such as parts of the JITT-ed java code or JNI function calls. Suspending a thread in that region would typically be unsafe.
* <li> Safe point. A single point during the thread execution time when the thread can safely suspended. For example, JIT may want to injec
t the safe points in the Java code between the selected chunks of the assembly code, those size is determined in terms of performance balanc
e between safe point function call overhead and suspension time overhead.
* </ul>
* Each thread managed by TM has the following fields:
* <ul>
* <li> safe_region 226 boolean flag which reports whether suspend is safe at this moment or not.
* <li> request 226 integer indicating if any request for suspension were made for this thread
* <li> suspend_count 226 integer indicating how many requests for suspension were made for this thread
* <li> safe_region_event 226 event indicating that thread has reached safe region
* <li> resume_event 226 event indicating that thread needs to be awakened
* </ul>
* The suspension algorithm typically invokes two threads 226 223suspender224 thread and 223suspendee224 thread.
* A typical example is than "suspender" is GC thread, and the "suspendee" is Java thread.
* The safe thread suspension algorithm works as follows:
* <pre>
* 1. GC thread invokes thread_supend() method of a thread manager which does the following:
* a. If Java thread was already requested to suspend, increase the suspend_count count and return;
* b. Increase suspend_count for Java thread;
* c. If Java thread is currently in unsafe region, wait while it reaches the safe region.
* 2. GC thread, after completing the enumeration-related activities, calls the resume_thread() method which does the following:
* a. If suspend_count was previously set, decrease the number of suspend requests;
* b. If the number of suspend requests reaches zero, notifies the Java thread that it can wake up now.
* 3. A Java thread may reach safe point, which is denoted by calling the safe_point() method in the Java thread.
* The safe_point() method does the following:
* a. If there was request for suspension then:
* i. notify GC thread that it can proceed with enumeration activities
* ii. wait for the resume notification to come from the GC thread
* 4. A Java thread may enter the safe region, which is denoted by calling the suspend_enable() method in the Java thread.
* The suspend_enable() method does the following:
* a. Sets the flag safe_region to true;
* b. If there was a request for suspension, notifies the GC thread that Java thread has reached safe region so GC may
* proceed with enumeration activities
* 5. A Java thread may leave the safe region, which is denoted by calling the suspend_disable() method in the Java thread.
* The suspend_disable() method does the following:
* a. Sets the flag safe_region to false;
* b. Calls the safe_point() method.
* </pre>
*
* For more detailes see thread manager component documentation located at vm/thread/doc/ThreadManager.htm
*
*/
#if !defined(HYTHREAD_EXT_H)
#define HYTHREAD_EXT_H
#include "open/types.h"
#include "open/hythread.h"
#if defined(__cplusplus)
extern "C" {
#endif
#include <open/types.h>
#include <apr_pools.h>
#include <apr_thread_mutex.h>
#include <apr_thread_cond.h>
#include <apr_thread_rwlock.h>
#include <apr_portable.h>
#include <assert.h>
#include "port_barriers.h"
//@{
/**
* Opaque structures
*/
//@{
#if defined(LINUX) || defined(FREEBSD)
#include <pthread.h>
#define osmutex_t pthread_mutex_t
#define hycond_t pthread_cond_t
#endif // LINUX || FREEBSD
#ifdef _WIN32
#define osmutex_t CRITICAL_SECTION
#define hycond_t struct HyCond
#include "hycond_win.h"
#endif // _WIN32
#if defined(__linux__) || defined(FREEBSD)
#include <sys/ucontext.h>
#define osthread_t pthread_t
#define thread_context_t ucontext_t
#elif _WIN32
#define osthread_t HANDLE
#define thread_context_t CONTEXT
#else // !_WIN32 && !__linux__
#error "threading is only supported on __linux__ or _WIN32"
#endif // !_WIN32 && !__linux__
#if !defined (_IPF_)
//use lock reservation
#define LOCK_RESERVATION
#endif // !defined (_IPF_)
typedef struct HyLatch *hylatch_t;
typedef struct HyThread *hythread_iterator_t;
typedef struct HyThreadLibraryInternal *hythread_library_t;
typedef U_32 hythread_thin_monitor_t;
typedef void (*hythread_event_callback_proc)(void);
typedef int (HYTHREAD_PROC *hythread_wrapper_t)(void*);
typedef struct hythread_start_proc_data * hythread_start_proc_data_t;
/**
* Native thread control structure.
*/
typedef struct HyThread {
#ifndef POSIX
// This is dummy pointer for Microsoft Visual Studio debugging
// If this is removed, Visual Studio, when attached to VM, will show
// no symbolic information
void* reserved;
#endif
// Public fields exported by HyThread_public. If you change these fields,
// please, check fields in hythread.h/HyThread_public
/**
* Number of requests made for this thread, it includes both
* suspend requests and safe point callback requests.
* The field is modified by atomic operations.
*
* Increment in functions:
* 1. send_suspend_request()
* - sets suspend request for a given thread
* 2. hythread_set_safepoint_callback()
* - sets safe point callback request for a given thread
*
* Decrement in functions:
* 1. hythread_resume()
* - removes suspend request for a given thread
* 2. hythread_exception_safe_point()
* - removes safe point callback request for current thread
*/
U_32 request;
/**
* Field indicating that thread can safely be suspended.
* Safe suspension is enabled on value 0.
*
* The disable_count is increased/decreaded in
* hythread_suspend_disable()/hythread_suspend_enable() function
* for current thread only.
*
* Also disable_count could be reset to value 0 and restored in
* hythread_set_suspend_disable()/hythread_set_suspend_disable() function
* for current thread only.
*
* Function hythread_exception_safe_point() sets disable_count to
* value 1 before safe point callback function calling and restores
* it after the call.
*
* Function thread_safe_point_impl() sets disable_count to
* value 0 before entering to the safe point and restores it
* after exitting.
*/
int16 disable_count;
/**
* Group for this thread. Different groups are needed in order
* to be able to quickly iterate over the specific group.
* Examples are: Java threads, GC private threads.
* Equal to the address of the head of the list of threads for this group.
*/
hythread_group_t group;
/**
* Array representing thread local storage
*/
void *thread_local_storage[10];
// Private fields
/**
* Each thread keeps a pointer to the library it belongs to.
*/
hythread_library_t library;
// Suspension
/**
* Number of suspend requests made for this thread.
* The field is modified by atomic operations.
*
* After increment/decrement of suspend_count, request field
* should be incremented/decremented too.
*/
U_32 suspend_count;
/**
* Function to be executed at safepoint upon thread resume.
*
* Field is set in hythread_set_safepoint_callback() function
* and reset hythread_exception_safe_point() function.
*
* After set/reset of safepoint_callback, request field
* should be incremented/decremented too.
*/
hythread_event_callback_proc safepoint_callback;
/**
* Event used to notify suspended thread that it needs to wake up.
*/
hysem_t resume_event;
// Basic manipulation fields
/**
* Points to the next thread within the group.
*/
hythread_t next;
/**
* Points to the last thread within the group.
*/
hythread_t prev;
/**
* Handle to OS thread.
*/
osthread_t os_handle;
// Synchronization stuff
/**
* Thread local lock, used to serialize thread state;
*/
osmutex_t mutex;
/**
* Monitor used to implement wait function for sleep/park;
*/
hythread_monitor_t monitor;
/**
* Current conditional variable thread is waiting on (used for interrupting)
*/
hycond_t *current_condition;
// State
/**
* Thread state. Holds thread state flags as defined in JVMTI specification, plus some additional
* flags. See <a href=http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html#GetThreadState>
* JVMTI Specification </a> for more details.
*/
IDATA state;
// Attributes
/**
* Hint for scheduler about thread priority
*/
int priority;
/**
* Flag illustrates that java thread status
*/
char java_status;
/**
* Release indicator
*/
char need_to_free;
/**
* Flag of interruption
*/
U_32 interrupted;
// Monitors
/**
* Monitor this thread is waiting on now.
*/
hythread_monitor_t waited_monitor;
/**
* ID for this thread. The maximum number of threads is governed by the size of lockword record.
*/
IDATA thread_id;
} HyThread;
/**
* Start procedure data structure.
*/
typedef struct hythread_start_proc_data {
/**
* A new thread
*/
hythread_t thread;
/**
* Thread group of a new thread
*/
hythread_group_t group;
/**
* Thread start procedure
*/
hythread_entrypoint_t proc;
/**
* Start procedure arguments
*/
void *proc_args;
} hythread_start_proc_data;
typedef struct tm_props {
int use_soft_unreservation;
} tm_props;
extern VMIMPORT tm_props *tm_properties;
//@}
/** @name Thread Manager initialization / shutdown
*/
//@{
//temporary, should be static for the file containing dinamic library
//initialization
////
IDATA VMCALL hythread_global_lock();
IDATA VMCALL hythread_global_unlock();
void VMCALL hythread_init(hythread_library_t lib);
void VMCALL hythread_shutdown();
void VMCALL hythread_shutdowning();
int VMCALL hythread_lib_state();
IDATA VMCALL hythread_lib_create(hythread_library_t * lib);
void VMCALL hythread_lib_destroy(hythread_library_t lib);
hythread_group_t VMCALL get_java_thread_group(void);
//@}
/** @name Basic manipulation
*/
//@{
IDATA VMCALL hythread_create_ex(hythread_t new_thread, hythread_group_t group, UDATA stacksize, UDATA priority, hythread_wrapper_t wrapper, hythread_entrypoint_t func, void *data);
IDATA VMCALL hythread_attach_ex(hythread_t new_handle, hythread_library_t lib, hythread_group_t group);
void VMCALL hythread_detach_ex(hythread_t thread);
IDATA VMCALL hythread_set_to_group(hythread_t thread, hythread_group_t group);
IDATA VMCALL hythread_remove_from_group(hythread_t thread);
void VMCALL hythread_set_self(hythread_t thread);
UDATA VMCALL hythread_clear_interrupted_other(hythread_t thread);
void VMCALL hythread_yield_other(hythread_t thread);
IDATA VMCALL hythread_get_self_id();
IDATA VMCALL hythread_get_id(hythread_t t);
hythread_t VMCALL hythread_get_thread(IDATA id);
IDATA VMCALL hythread_struct_init(hythread_t new_thread);
IDATA VMCALL hythread_struct_release(hythread_t thread);
IDATA VMCALL hythread_cancel_all(hythread_group_t group);
IDATA hythread_group_create(hythread_group_t *group);
IDATA VMCALL hythread_group_release(hythread_group_t group);
IDATA VMCALL hythread_group_get_list(hythread_group_t **list, int* size);
UDATA VMCALL hythread_tls_get_offset(hythread_tls_key_t key);
UDATA VMCALL hythread_tls_get_request_offset();
UDATA VMCALL hythread_get_thread_times(hythread_t thread, int64* pkernel, int64* puser);
UDATA VMCALL hythread_uses_fast_tls(void);
IDATA VMCALL hythread_get_hythread_offset_in_tls(void);
IDATA VMCALL hythread_get_struct_size();
IDATA VMCALL hythread_thread_lock(hythread_t thread);
IDATA VMCALL hythread_thread_unlock(hythread_t thread);
IDATA VMCALL hythread_get_state(hythread_t thread);
IDATA VMCALL hythread_set_state(hythread_t thread, IDATA state);
int VMCALL hythread_reset_suspend_disable();
void VMCALL hythread_set_suspend_disable(int count);
int VMCALL hythread_is_fat_lock(hythread_thin_monitor_t lockword);
hythread_monitor_t VMCALL hythread_inflate_lock(hythread_thin_monitor_t *lockword_ptr);
IDATA VMCALL hythread_owns_thin_lock(hythread_t thread, hythread_thin_monitor_t lockword);
IDATA VMCALL hythread_unreserve_lock(hythread_thin_monitor_t *lockword_ptr);
IDATA VMCALL hythread_get_thread_id_offset();
IDATA VMCALL hythread_set_thread_stop_callback(hythread_t thread, hythread_event_callback_proc stop_callback);
IDATA VMCALL hythread_wait_for_nondaemon_threads(hythread_t thread, IDATA threads_to_keep);
IDATA VMCALL hythread_increase_nondaemon_threads_count(hythread_t thread);
IDATA VMCALL hythread_decrease_nondaemon_threads_count(hythread_t thread, IDATA threads_to_keep);
//@}
/** @name Conditional variable
*/
//@{
IDATA VMCALL hycond_create (hycond_t *cond);
IDATA VMCALL hycond_wait (hycond_t *cond, osmutex_t *mutex);
IDATA VMCALL hycond_wait_timed (hycond_t *cond, osmutex_t *mutex, I_64 millis, IDATA nanos);
IDATA VMCALL hycond_wait_timed_raw(hycond_t * cond, osmutex_t * mutex, I_64 ms, IDATA nano);
IDATA VMCALL hycond_wait_interruptable (hycond_t *cond, osmutex_t *mutex, I_64 millis, IDATA nanos);
IDATA VMCALL hycond_notify (hycond_t *cond);
IDATA VMCALL hycond_notify_all (hycond_t *cond);
IDATA VMCALL hycond_destroy (hycond_t *cond);
//@}
/** @name Safe suspension support
*/
//@{
hy_inline IDATA VMCALL hythread_is_suspend_enabled();
hy_inline void VMCALL hythread_suspend_enable();
hy_inline void VMCALL hythread_suspend_disable();
void hythread_safe_point();
void hythread_safe_point_other(hythread_t thread);
void VMCALL hythread_exception_safe_point();
void VMCALL hythread_send_suspend_request(hythread_t thread);
IDATA VMCALL hythread_suspend_other(hythread_t thread);
IDATA VMCALL hythread_set_safepoint_callback(hythread_t thread, hythread_event_callback_proc callback);
IDATA VMCALL hythread_suspend_all(hythread_iterator_t *t, hythread_group_t group);
IDATA VMCALL hythread_resume_all(hythread_group_t group);
//@}
/** @name Latch
*/
//@{
IDATA VMCALL hylatch_create(hylatch_t *latch, IDATA count);
IDATA VMCALL hylatch_wait(hylatch_t latch);
IDATA VMCALL hylatch_wait_timed(hylatch_t latch, I_64 ms, IDATA nano);
IDATA VMCALL hylatch_wait_interruptable(hylatch_t latch, I_64 ms, IDATA nano);
IDATA VMCALL hylatch_set(hylatch_t latch, IDATA count);
IDATA VMCALL hylatch_count_down(hylatch_t latch);
IDATA VMCALL hylatch_get_count(IDATA *count, hylatch_t latch);
IDATA VMCALL hylatch_destroy(hylatch_t latch);
//@}
/** @name Thread iterator support
*/
//@{
hythread_iterator_t VMCALL hythread_iterator_create(hythread_group_t group);
IDATA VMCALL hythread_iterator_release(hythread_iterator_t *it);
IDATA VMCALL hythread_iterator_reset(hythread_iterator_t *it);
hythread_t VMCALL hythread_iterator_next(hythread_iterator_t *it);
IDATA VMCALL hythread_iterator_has_next(hythread_iterator_t it);
IDATA VMCALL hythread_iterator_size(hythread_iterator_t iterator);
//@}
/** @name Semaphore
*/
//@{
IDATA hysem_create(hysem_t *sem, UDATA initial_count, UDATA max_count);
IDATA VMCALL hysem_wait_timed(hysem_t sem, I_64 ms, IDATA nano);
IDATA VMCALL hysem_wait_interruptable(hysem_t sem, I_64 ms, IDATA nano);
IDATA VMCALL hysem_getvalue(IDATA *count, hysem_t sem);
IDATA hysem_set(hysem_t sem, IDATA count);
//@}
/** @name Thin monitors support
*/
//@{
IDATA VMCALL hythread_thin_monitor_create(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_enter(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_exit(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_release(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_wait(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_wait_timed(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano);
IDATA VMCALL hythread_thin_monitor_wait_interruptable(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano);
IDATA VMCALL hythread_thin_monitor_notify(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_notify_all(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_destroy(hythread_thin_monitor_t *lockword);
hythread_t VMCALL hythread_thin_monitor_get_owner(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_get_recursion(hythread_thin_monitor_t *lockword);
void VMCALL hythread_native_resource_is_live(U_32);
void VMCALL hythread_reclaim_resources();
//@}
/** @name State query
*/
//@{
int VMCALL hythread_is_alive(hythread_t thread) ;
int VMCALL hythread_is_terminated(hythread_t thread) ;
int VMCALL hythread_is_runnable(hythread_t thread) ;
int VMCALL hythread_is_blocked_on_monitor_enter(hythread_t thread) ;
int VMCALL hythread_is_waiting(hythread_t thread) ;
int VMCALL hythread_is_waiting_indefinitely(hythread_t thread) ;
int VMCALL hythread_is_waiting_with_timeout(hythread_t thread) ;
int VMCALL hythread_is_sleeping(hythread_t thread) ;
int VMCALL hythread_is_in_monitor_wait(hythread_t thread) ;
int VMCALL hythread_is_parked(hythread_t thread) ;
int VMCALL hythread_is_suspended(hythread_t thread) ;
int VMCALL hythread_is_interrupted(hythread_t thread) ;
int VMCALL hythread_is_in_native(hythread_t thread) ;
int VMCALL hythread_is_daemon(hythread_t thread) ;
// inline functions declarations
/**
* Returns non-zero if thread is suspended.
*/
hy_inline IDATA VMCALL hythread_is_suspend_enabled(){
return ((HyThread_public *)tm_self_tls)->disable_count == 0;
}
/**
* Denotes the beginning of the code region where safe suspension is possible.
*
* The method decreases the disable_count field. The disable_count could be
* recursive, so safe suspension region is enabled on value 0.
*
* <p>
* A thread marks itself with functions hythread_suspend_enable()
* and hythread_suspend_disable() in order to denote a safe region of code.
* A thread may also call hythread_safe_point() method to denote a selected
* point where safe suspension is possible.
*/
hy_inline void VMCALL hythread_suspend_enable() {
register hythread_t thread;
assert(!hythread_is_suspend_enabled());
thread = tm_self_tls;
((HyThread_public *)thread)->disable_count--;
}
/**
* Denotes the end of the code region where safe suspension was possible.
*
* The method increases the disable_count field. The disable_count could be
* recursive, so safe suspension region is enabled on value 0.
* If there was a suspension request set for this thread, the method invokes
* hythread_safe_point().
* <p>
* A thread marks itself with functions hythread_suspend_enable()
* and hythread_suspend_disable() in order to denote a safe region of code.
* A thread may also call hythread_safe_point() method to denote a selected
* point where safe suspension is possible.
*/
hy_inline void VMCALL hythread_suspend_disable()
{
register hythread_t thread;
// Check that current thread is in default thread group.
// Justification: GC suspends and enumerates threads from
// default group only.
assert(((HyThread_public *)hythread_self())->group == get_java_thread_group());
thread = tm_self_tls;
((HyThread_public *)thread)->disable_count++;
//port_rw_barrier();
if (((HyThread_public *)thread)->request &&
((HyThread_public *)thread)->disable_count == 1) {
// enter to safe point if suspend request was set
// and suspend disable was made a moment ago
// (it's a point of entry to the unsafe region)
hythread_safe_point_other(thread);
}
return;
}
#define TM_THREAD_QUANTITY_OF_PREDEFINED_TLS_KEYS 1
//@}
/**
* TM Thread states constants. They are compatible with JVMTI.
*/
//@{
// 0x00000000 Thread is new.
#define TM_THREAD_STATE_NEW 0
// 0x00000001 Thread is alive. Zero if thread is new (not started) or terminated.
#define TM_THREAD_STATE_ALIVE JVMTI_THREAD_STATE_ALIVE
// 0x00000002 Thread has completed execution.
#define TM_THREAD_STATE_TERMINATED JVMTI_THREAD_STATE_TERMINATED
// 0x00000004 Thread is runnable.
#define TM_THREAD_STATE_WAITING JVMTI_THREAD_STATE_WAITING
// 0x00000010 Thread is waiting without a timeout. For example, Object.wait().
#define TM_THREAD_STATE_WAITING_INDEFINITELY JVMTI_THREAD_STATE_WAITING_INDEFINITELY
// 0x00000020 Thread is waiting with a maximum time to wait specified.
// For example, Object.wait(long).
#define TM_THREAD_STATE_WAITING_WITH_TIMEOUT JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
// 0x00000040 Thread is sleeping. For example, Thread.sleep(long).
#define TM_THREAD_STATE_RUNNABLE JVMTI_THREAD_STATE_RUNNABLE
// 0x00000080 Thread is waiting.
#define TM_THREAD_STATE_SLEEPING JVMTI_THREAD_STATE_SLEEPING
// 0x00000100 Thread is waiting on an object monitor -- Object.wait.
#define TM_THREAD_STATE_IN_MONITOR_WAIT JVMTI_THREAD_STATE_IN_OBJECT_WAIT
// 0x00000200 Thread is parked.
// For example: LockSupport.park, LockSupport.parkUtil and LockSupport.parkNanos.
#define TM_THREAD_STATE_PARKED JVMTI_THREAD_STATE_PARKED
// 0x00000400 Thread is waiting to enter a synchronization block/method or,
// after an Object.wait(), waiting to re-enter a synchronization block/method.
#define TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
// 0x00000800 Thread is unparked, to track staled unparks
#define TM_THREAD_STATE_UNPARKED 0x0800
// 0x00100000 Thread suspended.
// For example, java.lang.Thread.suspend()
// or a JVMTI suspend function (such as SuspendThread)
// has been called on the thread. If this bit is set,
// the other bits refer to the thread state before suspension.
#define TM_THREAD_STATE_SUSPENDED JVMTI_THREAD_STATE_SUSPENDED
// 0x00200000 Thread has been interrupted.
#define TM_THREAD_STATE_INTERRUPTED JVMTI_THREAD_STATE_INTERRUPTED
// 0x00400000 Thread is in native code. That is a native method is running which
// has not called back into the VM or Java programming language code.
#define TM_THREAD_STATE_IN_NATIVE JVMTI_THREAD_STATE_IN_NATIVE
#define WAIT_INTERRUPTABLE 1
#define WAIT_NONINTERRUPTABLE 0
/**
* TM functions error codes (they are mostly coming from APR).
*/
#define TM_ERROR_NONE (0) // No error has occurred. This is the error code that is returned on successful completion of the function.
#define TM_ERROR_INVALID_MONITOR (50) // Monitor pointer provided to the function id invalid
#define TM_ERROR_NOT_MONITOR_OWNER (51) // Thread is not owner of the monitor
#define TM_ERROR_INTERRUPT (52) // The call has been interrupted before completion.
#define TM_ERROR_NULL_POINTER (100) // Pointer is unexpectedly NULL.
#define TM_ERROR_OUT_OF_MEMORY (110) // The function attempted to allocate memory and no more memory was available for allocation.
#define TM_ERROR_ACCESS_DENIED (111) // The desired functionality has not been enabled in this virtual machine.
#define TM_ERROR_WRONG_PHASE (112) // The desired functionality is not available in the current phase. Always returned if the virtual machine has completed running.
#define TM_ERROR_INTERNAL (113) // An unexpected internal error has occurred.
#define TM_ERROR_UNATTACHED_THREAD (115) // The thread being used to call this function is not attached to the virtual machine. Calls must be made from attached threads. See AttachCurrentThread in the JNI invocation API.
#define TM_ERROR_INVALID_ENVIRONMENT (116) // The JVMTI environment provided is no longer connected or is not an environment.
#define TM_ERROR_MAX_THREADS (117) //Max number of threads exceeded
#define TM_ERROR_ILLEGAL_STATE (51) //incorrect syncronizer state For example monitor wait without lock.
#define TM_ERROR_RUNNING_THREADS (119) //error relesing group/destroying library if there are running threads
#define TM_ERROR_EBUSY APR_EBUSY // returned by try_lock
#define TM_ERROR_TIMEOUT APR_TIMEUP // returned by try_lock
#define TM_ERROR_START 1000
// possible values for tm_status_t
#define TM_OS_ERROR (TM_ERROR_START+1)
// if default stack size is not through -Xss parameter, it is 512kb
#ifndef POINTER64
#define TM_DEFAULT_STACKSIZE (512 * 1024)
#else
// Make stack size default to 2Mb on 64-bit platforms
#define TM_DEFAULT_STACKSIZE (2048 * 1024)
#endif
// java thread status
#define TM_STATUS_WITHOUT_JAVA 0 // native thread cannot has associated java thread
#define TM_STATUS_ALLOCATED 1 // associated java thread is allocated
#define TM_STATUS_INITIALIZED 2 // associated java thread is initialized
#define TM_LIBRARY_STATUS_NOT_INITIALIZED 0
#define TM_LIBRARY_STATUS_INITIALIZED 1
#define TM_LIBRARY_STATUS_SHUTDOWN 2
#if defined(__cplusplus)
}
#endif
#endif /* HYTHREAD_EXT_H */