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