/*
 *  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
 * @ingroup Thread
 * @brief Threading and synchronization support
 */

#include "threaddef.h"
#include <stdlib.h>

#define CDEV_CURRENT_FUNCTION _prototypes_private
static hythread_t allocate_thread PROTOTYPE ((int globalIsLocked));
static void free_thread
PROTOTYPE ((hythread_t thread, int globalAlreadyLocked));
static IDATA interrupt_waiting_thread
PROTOTYPE ((hythread_t self, hythread_t threadToInterrupt));
static void remove_from_queue
PROTOTYPE ((hythread_t volatile *queue, hythread_t thread));
static IDATA destroy_thread
PROTOTYPE ((hythread_t thread, int globalAlreadyLocked));
void VMCALL hythread_shutdown PROTOTYPE ((void));
static void HYTHREAD_PROC tls_null_finalizer PROTOTYPE ((void *entry));
static I_32 HYTHREAD_PROC interruptServer PROTOTYPE ((void *entryArg));
static hythread_monitor_t VMCALL hythread_monitor_acquire
PROTOTYPE ((hythread_t self, IDATA policy, IDATA policyData));
void VMCALL hythread_init PROTOTYPE ((hythread_library_t lib));
static IDATA init_global_monitor PROTOTYPE ((hythread_library_t lib));
static void tls_finalize PROTOTYPE ((hythread_t thread));
static void free_monitor_pools PROTOTYPE ((void));
static void *VMCALL thread_malloc PROTOTYPE ((void *unused, U_32 size));
static void NORETURN internal_exit PROTOTYPE ((void));
static IDATA monitor_wait
PROTOTYPE ((hythread_monitor_t monitor, I_64 millis, IDATA nanos,
            IDATA interruptable));
static IDATA monitor_enter
PROTOTYPE ((hythread_t self, hythread_monitor_t monitor));
static UDATA init_monitor
PROTOTYPE ((hythread_monitor_t monitor, UDATA flags));

static IDATA monitor_enter_three_tier
PROTOTYPE ((hythread_t self, hythread_monitor_t monitor));

static hytime_t getCurrentCycles PROTOTYPE ((void));
static hythread_monitor_pool_t allocate_monitor_pool PROTOTYPE ((void));
static IDATA create_thread
PROTOTYPE ((hythread_t * handle, UDATA stacksize, UDATA priority,
            UDATA suspend, hythread_entrypoint_t entrypoint, void *entryarg,
            int globalIsLocked));
static void interrupt_thread
PROTOTYPE ((hythread_t thread, UDATA interruptFlag));

static void unblock_spinlock_threads
PROTOTYPE ((hythread_t self, hythread_monitor_t monitor));

static void notify_thread
PROTOTYPE ((hythread_t threadToNotify, int setNotifiedFlag));
static IDATA monitor_exit
PROTOTYPE ((hythread_t self, hythread_monitor_t monitor));
static WRAPPER_TYPE thread_wrapper PROTOTYPE ((WRAPPER_ARG arg));
static void VMCALL thread_free PROTOTYPE ((void *unused, void *ptr));
static void enqueue_thread
PROTOTYPE ((hythread_t * queue, hythread_t thread));
static IDATA monitor_notify_one_or_all
PROTOTYPE ((hythread_monitor_t monitor, int notifyall));

#undef CDEV_CURRENT_FUNCTION

#if defined(THREAD_ASSERTS)
/*
 * Helper variable for asserts.
 * We use this to keep track of when the global lock is owned.
 * We don't want to do a re-entrant enter on the global lock 
 */
hythread_t global_lock_owner = UNOWNED;
#endif

#define BOUNDED_I64_TO_IDATA(longValue) ((longValue) > 0x7FFFFFFF ? 0x7FFFFFFF : (IDATA)(longValue))

#define HYTHREAD_MAX_TLS_KEYS (sizeof( ((HyThreadLibrary*)NULL)->tls_finalizers ) / sizeof( ((HyThreadLibrary*)NULL)->tls_finalizers[0] ))

#define CDEV_CURRENT_FUNCTION hythread_init
/**
 * Initialize a Hy threading library.
 * 
 * @note This must only be called once.
 * 
 * If any OS threads were created before calling this function, they must be attached using
 * hythread_attach before accessing any Hy thread library functions. 
 * 
 * @param[in] lib pointer to the Hy thread library to be initialized (non-NULL)
 * @return The Hy thread library's initStatus will be set to 0 on success or 
 * a negative value on failure.
 * 
 * @see hythread_attach, hythread_shutdown
 */
void VMCALL
hythread_init (hythread_library_t lib)
{
  ASSERT (lib);

  lib->spinlock = 0;
  lib->threadCount = 0;
  lib->globals = NULL;
  lib->stack_usage = 0;

  /* set all TLS finalizers to NULL. This indicates that the key is unused */
  memset (lib->tls_finalizers, 0, sizeof (lib->tls_finalizers));

  STATIC_ASSERT (CALLER_LAST_INDEX <= MAX_CALLER_INDEX);

  if (TLS_ALLOC (lib->self_ptr))
    goto init_cleanup1;

  lib->monitor_pool = allocate_monitor_pool ();
  if (lib->monitor_pool == NULL)
    goto init_cleanup2;

  if (!MUTEX_INIT (lib->monitor_mutex))
    goto init_cleanup3;
  if (!MUTEX_INIT (lib->tls_mutex))
    goto init_cleanup4;
  if (!MUTEX_INIT (lib->global_mutex))
    goto init_cleanup5;

  lib->thread_pool =
    pool_new (sizeof (HyThread), 0, 0, 0, thread_malloc, thread_free, NULL);
  if (lib->thread_pool == NULL)
    goto init_cleanup6;

  lib->global_pool =
    pool_new (sizeof (HyThreadGlobal), 0, 0, 0, thread_malloc, thread_free,
              NULL);
  if (lib->global_pool == NULL)
    goto init_cleanup7;

  if (init_global_monitor (lib))
    goto init_cleanup8;

  lib->initStatus = 1;
  return;

init_cleanup8:pool_kill (lib->global_pool);
init_cleanup7:pool_kill (lib->thread_pool);
init_cleanup6:MUTEX_DESTROY (lib->global_mutex);
init_cleanup5:MUTEX_DESTROY (lib->tls_mutex);
init_cleanup4:MUTEX_DESTROY (lib->monitor_mutex);
init_cleanup3:free_monitor_pools ();
init_cleanup2:TLS_DESTROY (lib->self_ptr);
init_cleanup1:lib->initStatus = -1;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_self
/** 
 * Return the hythread_t for the current thread.
 * 
 * @note Must be called only by an attached thread
 * 
 * @return hythread_t for the current thread
 *
 * @see hythread_attach
 * 
 */
hythread_t VMCALL
hythread_self (void)
{
  return MACRO_SELF ();
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_create
/**
 * Create a new OS thread.
 * 
 * The created thread is attached to the threading library.<br>
 * <br>
 * Unlike POSIX, this doesn't require an attributes structure.
 * Instead, any interesting attributes (e.g. stacksize) are
 * passed in with the arguments.
 *
 * @param[out] handle a pointer to a hythread_t which will point to the thread (if successfully created)
 * @param[in] stacksize the size of the new thread's stack (bytes)<br>
 *			0 indicates use default size
 * @param[in] priority priorities range from HYTHREAD_PRIORITY_MIN to HYTHREAD_PRIORITY_MAX (inclusive)
 * @param[in] suspend set to non-zero to create the thread in a suspended state.
 * @param[in] entrypoint pointer to the function which the thread will run
 * @param[in] entryarg a value to pass to the entrypoint function
 *
 * @return  0 on success or negative value on failure
 *
 * @see hythread_exit, hythread_resume
 */
IDATA VMCALL
hythread_create (hythread_t * handle, UDATA stacksize, UDATA priority,
                 UDATA suspend, hythread_entrypoint_t entrypoint,
                 void *entryarg)
{
  return create_thread (handle, stacksize, priority, suspend, entrypoint,
                        entryarg, GLOBAL_NOT_LOCKED);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION create_thread
/*
 * Create a new OS thread and attach it.
 */
static IDATA
create_thread (hythread_t * handle, UDATA stacksize, UDATA priority,
               UDATA suspend, hythread_entrypoint_t entrypoint,
               void *entryarg, int globalIsLocked)
{
  hythread_t thread;
  hythread_library_t lib = GLOBAL_DATA (default_library);

  ASSERT (lib->initStatus);

  if (priority > HYTHREAD_PRIORITY_MAX)
    {
      goto cleanup0;
    }

  if (stacksize == 0)
    {
      stacksize = STACK_DEFAULT_SIZE;
    }

  thread = allocate_thread (globalIsLocked);
  if (!thread)
    {
      goto cleanup0;
    }
  if (handle)
    {
      *handle = thread;
    }
  thread->library = lib;
  thread->priority = priority;
  thread->attachcount = 0;
  thread->stacksize = stacksize;

  memset (thread->tls, 0, sizeof (thread->tls));

  thread->interrupter = NULL;

  if (!COND_INIT (thread->condition))
    {
      goto cleanup1;
    }
  if (!MUTEX_INIT (thread->mutex))
    {
      goto cleanup2;
    }

  thread->flags = suspend ? HYTHREAD_FLAG_SUSPENDED : 0;
  thread->entrypoint = entrypoint;
  thread->entryarg = entryarg;

  if (IS_JLM_ENABLED (thread))
    {
      hythread_jlm_thread_init (thread);
    }

#if defined(LINUX)
  thread->jumpBuffer = NULL;
#endif

  if (!THREAD_CREATE (thread, stacksize, priority, thread_wrapper, thread))
    {
      goto cleanup3;
    }

  return 0;

/* Cleanup points */
cleanup3:MUTEX_DESTROY (thread->mutex);
cleanup2:COND_DESTROY (thread->condition);
cleanup1:free_thread (thread, GLOBAL_NOT_LOCKED);
cleanup0:if (handle)
    *handle = NULL;
  return -1;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_attach
/**
 * Attach an OS thread to the threading library.
 * 
 * Create a new hythread_t to represent the existing OS thread.
 * Attaching a thread is required when a thread was created 
 * outside of the Hy threading library wants to use any of the 
 * Hy threading library functionality.
 *
 * If the OS thread is already attached, handle is set to point 
 * to the existing hythread_t.
 *
 * @param[out] handle pointer to a hythread_t to be set (will be ignored if null)
 * @return  0 on success or negative value on failure
 *
 * @see hythread_detach
 */
IDATA VMCALL
hythread_attach (hythread_t * handle)
{
  hythread_t thread;

  if (init_thread_library ())
    {
      goto cleanup0;
    }

  if ((thread = MACRO_SELF ()) != NULL)
    {
      if (handle)
        {
          *handle = thread;
        }
      THREAD_LOCK (thread, thread, CALLER_ATTACH);
      thread->attachcount++;
      THREAD_UNLOCK (thread, thread);
      return 0;
    }

  thread = allocate_thread (GLOBAL_NOT_LOCKED);
  if (!thread)
    {
      goto cleanup0;
    }

  thread->library = GLOBAL_DATA (default_library);
  thread->attachcount = 1;
  thread->priority = HYTHREAD_PRIORITY_NORMAL;
  thread->flags = HYTHREAD_FLAG_ATTACHED;

  if (!COND_INIT (thread->condition))
    {
      goto cleanup1;
    }

  if (!MUTEX_INIT (thread->mutex))
    {
      goto cleanup2;
    }

#if defined(WIN32)
  {
    DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
                     GetCurrentProcess (), &thread->handle, 0, TRUE,
                     DUPLICATE_SAME_ACCESS);
  }
#else
  thread->handle = THREAD_SELF ();
#endif

  initialize_thread_priority (thread);

  TLS_SET (thread->library->self_ptr, thread);

  thread->tid = RAS_THREAD_ID ();

  if (handle)
    {
      *handle = thread;
    }
  return 0;

/* failure points */
cleanup2:COND_DESTROY (thread->condition);
cleanup1:free_thread (thread, GLOBAL_NOT_LOCKED);
cleanup0:return -1;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_suspend
/**
 * Suspend the current thread. 
 * 
 * Stop the current thread from executing until it is resumed.
 * 
 * @return none
 *
 * @see hythread_resume
 */
void VMCALL
hythread_suspend (void)
{
  hythread_t self = MACRO_SELF ();
  ASSERT (self);

  THREAD_LOCK (self, self, CALLER_SUSPEND);
  self->flags |= HYTHREAD_FLAG_SUSPENDED;

  COND_WAIT (self->condition, self->mutex);
  if ((self->flags & HYTHREAD_FLAG_SUSPENDED) == 0)
    break;
  COND_WAIT_LOOP ();

  THREAD_UNLOCK (self, self);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_resume
/**
 * Resume a thread. 
 *
 * Take a threads out of the suspended state. 
 * 
 * If the thread is not suspended, no action is taken.
 *
 * @param[in] thread a thread to be resumed
 * @return none
 * 
 * @see hythread_create, hythread_suspend
 */
void VMCALL
hythread_resume (hythread_t thread)
{
  hythread_t self;

  ASSERT (thread);

  if ((thread->flags & HYTHREAD_FLAG_SUSPENDED) == 0)
    {
      /* it wasn't suspended! */
      return;
    }

  self = MACRO_SELF ();
  ASSERT (self);

  THREAD_LOCK (self, thread, CALLER_RESUME);

  /* 
   * The thread _should_ only be OS suspended once, but
   * handle the case where it's suspended more than once anyway.
   */
  COND_NOTIFY_ALL (thread->condition);
  thread->flags &= ~HYTHREAD_FLAG_SUSPENDED;

  THREAD_UNLOCK (self, thread);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_yield
/** 
 * Yield the processor.
 * 
 * @return none
 */
void VMCALL
hythread_yield (void)
{
  THREAD_YIELD ();
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_init
/*
 * Acquire and initialize a new monitor from the threading library.
 *
 * @param[out] handle pointer to a hythread_monitor_t to be set to point to the new monitor
 * @param[in] flags initial flag values for the monitor
 * @return 0 on success, negative value on failure
 * 
 * @deprecated This has been replaced by hythread_monitor_init_with_name
 * @see hythread_monitor_init_with_name
 */
IDATA VMCALL
hythread_monitor_init (hythread_monitor_t * handle, UDATA flags)
{
  IDATA rc;

  /* Initialize monitor with default locking policy */
  rc =
    hythread_monitor_init_policy (handle, flags, HYTHREAD_LOCKING_DEFAULT,
                                  HYTHREAD_LOCKING_NO_DATA);
  return rc;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_init_policy
/*
 * Acquire and initialize a new monitor with given locking policy from the threading library.
 *
 * @param[out] handle pointer to a hythread_monitor_t to be set to point to the new monitor
 * @param[in] flags initial flag values for the monitor
 * @param[in] locking policy for the monitor 
 * @param[in] data associated with locking policy or HYTHREAD_LOCKING_NO_DATA
 * @return 0 on success, negative value on failure
 * 
 */
IDATA VMCALL
hythread_monitor_init_policy (hythread_monitor_t * handle, UDATA flags,
                              IDATA policy, IDATA policyData)
{
  hythread_monitor_t monitor;

  hythread_t self = MACRO_SELF ();
  ASSERT (self);
  ASSERT (handle);

  monitor = hythread_monitor_acquire (self, policy, policyData);
  if (NULL == monitor)
    {
      return -1;
    }

  if (init_monitor (monitor, flags) != 0)
    {
      return -1;
    }

  if (IS_JLM_ENABLED (self))
    {
      hythread_jlm_monitor_init (monitor);
    }

  *handle = monitor;
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_destroy
/**
 * Destroy a monitor.
 * 
 * Destroying a monitor frees the internal resources associated
 * with it.
 *
 * @note A monitor must NOT be destroyed if threads are waiting on
 * it, or if it is currently owned.
 *
 * @param[in] monitor a monitor to be destroyed
 * @return  0 on success or non-0 on failure (the monitor is in use)
 * 
 * @see hythread_monitor_init_with_name
 */
IDATA VMCALL
hythread_monitor_destroy (hythread_monitor_t monitor)
{
  hythread_t self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (monitor);

  GLOBAL_LOCK (self, CALLER_MONITOR_DESTROY);

  if (monitor->owner || monitor->waiting)
    {
      /* This monitor is in use! It was probably abandoned when a thread was cancelled.
       * There's actually a very small timing hole here -- if the thread had just locked the 
       * mutex and not yet set the owner field when it was cancelled, we have no way of
       * knowing that the mutex may be in an invalid state. The same thing can happen
       * if the thread has just cleared the field and is about to unlock the mutex.
       * Hopefully the OS takes care of this for us, but it might not.
       */
      GLOBAL_UNLOCK (self);
      return HYTHREAD_ILLEGAL_MONITOR_STATE;
    }

  monitor->owner = (hythread_t) self->library->monitor_pool->next_free;
  monitor->count = FREE_TAG;
  monitor->userData = 0;
  self->library->monitor_pool->next_free = monitor;

  GLOBAL_UNLOCK (self);
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_enter
/**
 * Enter a monitor.
 * 
 * A thread may re-enter a monitor it owns multiple times, but must
 * exit the monitor the same number of times before any other thread
 * wanting to enter the monitor is permitted to continue.
 *
 * @param[in] monitor a monitor to be entered
 * @return 0 on success<br>
 * HYTHREAD_PRIORITY_INTERRUPTED if the thread was priority interrupted while blocked
 * 
 * @see hythread_monitor_enter_using_threadId, hythread_monitor_exit, hythread_monitor_exit_using_threadId
 */
IDATA VMCALL
hythread_monitor_enter (hythread_monitor_t monitor)
{
  hythread_t self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (monitor);
  ASSERT (FREE_TAG != monitor->count);

  if (monitor->owner == self)
    {
      ASSERT (monitor->count >= 1);
      monitor->count++;

      if (IS_JLM_ENABLED (self))
        {
          ASSERT (monitor->tracing);
          monitor->tracing->recursive_count++;
          monitor->tracing->enter_count++;
        }                       /* if (IS_JLM_ENABLED(self)) */

      return 0;
    }

  return monitor_enter (self, monitor);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_exit
/**
 * Exit a monitor.
 * 
 * Exit a monitor, and if the owning count is zero, release it.
 *
 * @param[in] monitor a monitor to be exited
 * @return 0 on success, <br>HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor
 * 
 * @see hythread_monitor_exit_using_threadId, hythread_monitor_enter, hythread_monitor_enter_using_threadId
 */
IDATA VMCALL
hythread_monitor_exit (hythread_monitor_t monitor)
{
  hythread_t self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (monitor);
  ASSERT (FREE_TAG != monitor->count);

  if (monitor->owner != self)
    {
      return HYTHREAD_ILLEGAL_MONITOR_STATE;
    }

  return monitor_exit (self, monitor);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_wait
/** 
 * Wait on a monitor until notified.
 *
 * Release the monitor, wait for a signal (notification), then re-acquire the monitor.
 * 
 * @param[in] monitor a monitor to be waited on
 * @return 0 if the monitor has been waited on, notified, and reobtained<br>
 * HYTHREAD_INVALID_ARGUMENT if millis or nanos is out of range (millis or nanos < 0, or nanos >= 1E6)<br>
 * HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor
 * 
 * @see hythread_monitor_wait_interruptable, hythread_monitor_wait_timed, hythread_monitor_enter
 * 
 */
IDATA VMCALL
hythread_monitor_wait (hythread_monitor_t monitor)
{
  return monitor_wait (monitor, 0, 0, WAIT_UNINTERRUPTABLE);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_notify
/**
 * Notify a single thread waiting on a monitor.
 * 
 * A thread is considered to be waiting on the monitor if 
 * it is currently blocked while executing hythread_monitor_wait on the monitor.
 * 
 * If no threads are waiting, no action is taken.
 *
 * @param[in] monitor a monitor to be signaled
 * @return  0 once the monitor has been signaled<br>HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor
 * 
 * @see hythread_monitor_notify_all, hythread_monitor_enter, hythread_monitor_wait
 */
IDATA VMCALL
hythread_monitor_notify (hythread_monitor_t monitor)
{
  return monitor_notify_one_or_all (monitor, NOTIFY_ONE);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_notify_all
/**
 * Notify all threads waiting on a monitor.
 * 
 * A thread is considered to be waiting on the monitor if 
 * it is currently blocked while executing hythread_monitor_wait on the monitor.
 * 
 * If no threads are waiting, no action is taken.
 *
 *
 * @param[in] monitor a monitor to be signaled
 * @return  0 once the monitor has been signaled<br>HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor
 * 
 * @see hythread_monitor_notify, hythread_monitor_enter, hythread_monitor_wait
 */
IDATA VMCALL
hythread_monitor_notify_all (hythread_monitor_t monitor)
{
  return monitor_notify_one_or_all (monitor, NOTIFY_ALL);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_tls_alloc
/**
 * Allocate a thread local storage (TLS) key.
 * 
 * Create and return a new, unique key for thread local storage.  
 * 
 * @note The hande returned will be >=0, so it is safe to test the handle against 0 to see if it's been
 * allocated yet.
 * 
 * @param[out] handle pointer to a key to be initialized with a key value
 * @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated)
 * 
 * @see hythread_tls_free, hythread_tls_set
 */
IDATA VMCALL
hythread_tls_alloc (hythread_tls_key_t * handle)
{
  return hythread_tls_alloc_with_finalizer (handle, tls_null_finalizer);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_tls_free
/**
 * Release a TLS key.
 * 
 * Release a TLS key previously allocated by hythread_tls_alloc.
 * 
 * @param[in] key TLS key to be freed
 * @return 0 on success or negative value on failure
 *
 * @see hythread_tls_alloc, hythread_tls_set
 *
 */
IDATA VMCALL
hythread_tls_free (hythread_tls_key_t key)
{
  HyPoolState state;
  hythread_t each;
  hythread_library_t lib = GLOBAL_DATA (default_library);
  ASSERT (lib);

  /* clear the TLS in every existing thread */
  GLOBAL_LOCK_SIMPLE (lib);
  each = pool_startDo (lib->thread_pool, &state);
  while (each)
    {
      each->tls[key - 1] = NULL;
      each = pool_nextDo (&state);
    }
  GLOBAL_UNLOCK_SIMPLE (lib);

  /* now return the key to the free set */
  MUTEX_ENTER (lib->tls_mutex);
  lib->tls_finalizers[key - 1] = NULL;
  MUTEX_EXIT (lib->tls_mutex);

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_tls_set
/**
 * Set a thread's TLS value.
 *
 * @param[in] thread a thread 
 * @param[in] key key to have TLS value set (any value returned by hythread_alloc)
 * @param[in] value value to be stored in TLS
 * @return 0 on success or negative value on failure
 *  
 * @see hythread_tls_alloc, hythread_tls_free, hythread_tls_get
 */
IDATA VMCALL
hythread_tls_set (hythread_t thread, hythread_tls_key_t key, void *value)
{
  thread->tls[key - 1] = value;

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_set_priority
/**
 * Set a thread's execution priority.
 * 
 * @param[in] thread a thread
 * @param[in] priority
 * Use the following symbolic constants for priorities:<br>
 *				HYTHREAD_PRIORITY_MAX<br>
 *				HYTHREAD_PRIORITY_USER_MAX<br>
 *				HYTHREAD_PRIORITY_NORMAL<br>
 *				HYTHREAD_PRIORITY_USER_MIN<br>
 *				HYTHREAD_PRIORITY_MIN<br>
 * 
 * @returns 0 on success or negative value on failure (priority wasn't changed)
 * 
 * 
 */
IDATA VMCALL
hythread_set_priority (hythread_t thread, UDATA priority)
{
  ASSERT (thread);

  if (priority > HYTHREAD_PRIORITY_MAX)
    {
      return -1;
    }

  if (THREAD_SET_PRIORITY (thread->handle, priority_map[priority]))
    {
      return -1;
    }

  thread->priority = priority;

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_interrupt
/** 
 * Interrupt a thread.
 * 
 * If the thread is currently blocked (i.e. waiting on a monitor_wait or sleeping)
 * resume the thread and cause it to return from the blocking function with
 * HYTHREAD_INTERRUPTED.
 * 
 * @param[in] thread a thead to be interrupted
 * @return none
 */
void VMCALL
hythread_interrupt (hythread_t thread)
{
  interrupt_thread (thread, HYTHREAD_FLAG_INTERRUPTED);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_interrupted
/**
 * Return the value of a thread's interrupted flag.
 * 
 * @param[in] thread thread to be queried
 * @return 0 if not interrupted, non-zero if interrupted
 */
UDATA VMCALL
hythread_interrupted (hythread_t thread)
{
  ASSERT (thread);
  return (thread->flags & HYTHREAD_FLAG_INTERRUPTED) != 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_clear_interrupted
/**
 * Clear the interrupted flag of the current thread and return its previous value.
 * 
 * @return  previous value of interrupted flag: non-zero if the thread had been interrupted.
 */
UDATA VMCALL
hythread_clear_interrupted (void)
{
  UDATA oldFlags;
  hythread_t self = MACRO_SELF ();
  ASSERT (self);

  THREAD_LOCK (self, self, CALLER_CLEAR_INTERRUPTED);
  oldFlags = self->flags;
  self->flags = oldFlags & ~HYTHREAD_FLAG_INTERRUPTED;
  THREAD_UNLOCK (self, self);

  return (oldFlags & HYTHREAD_FLAG_INTERRUPTED) != 0;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION remove_from_queue
/*
 * Remove a thread from a monitor's queue.
 * 
 * @param[in] queue head of a monitor's queue
 * @param[in] thread thread to be removed from queue
 * @return none
 */
static void
remove_from_queue (hythread_t volatile *queue, hythread_t thread)
{
  hythread_t queued, next;

  ASSERT (thread);

  if ((queued = *queue) == NULL)
    return;

  if (queued == thread)
    {
      *queue = thread->next;
      thread->next = NULL;
    }
  else
    {
      while ((next = queued->next) != NULL && next != thread)
        {
          queued = next;
        }
      if (next != NULL)
        {
          queued->next = thread->next;
          thread->next = NULL;
        }
    }

  ASSERT (NULL == thread->next);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION allocate_monitor_pool
/*
 * Create and initialize a pool of monitors.
 * 
 * @return pointer to a new monitor pool on success, NULL on failure
 * 
 */
static hythread_monitor_pool_t
allocate_monitor_pool (void)
{
  int i;
  hythread_monitor_t entry;
  hythread_monitor_pool_t pool =
    (hythread_monitor_pool_t) malloc (sizeof (HyThreadMonitorPool));
  if (pool == NULL)
    {
      return NULL;
    }
  memset (pool, 0, sizeof (HyThreadMonitorPool));

  pool->next_free = entry = &pool->entries[0];
  for (i = 0; i < MONITOR_POOL_SIZE - 1; i++, entry++)
    {
      entry->count = FREE_TAG;
      entry->owner = (hythread_t) (entry + 1);
      /* entry->waiting = entry->blocked = NULL; *//* (unnecessary) */
      entry->flags = HYTHREAD_MONITOR_MUTEX_UNINITIALIZED;
    }
  /* initialize the last monitor */
  entry->count = FREE_TAG;
  entry->flags = HYTHREAD_MONITOR_MUTEX_UNINITIALIZED;

  return pool;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION thread_wrapper
/*
 * Function we pass to the OS for new threads.
 * 
 * @param arg pointer to the hythread_t for the new thread
 * @return none
 */
static WRAPPER_TYPE
thread_wrapper (WRAPPER_ARG arg)
{
  hythread_t thread = (hythread_t) arg;
  hythread_library_t lib = thread->library;
  UDATA flags;

  ASSERT (thread);
  ASSERT (lib);

  thread->tid = RAS_THREAD_ID ();

  TLS_SET (lib->self_ptr, thread);

  if (lib->stack_usage)
    {
      paint_stack (thread);
    }

  if (thread->flags & HYTHREAD_FLAG_CANCELED)
    {
      internal_exit ();
    }

  /* Handle the create-suspended case */
  /* (This code is basically the same as hythread_suspend, but we need to
     test the condition under mutex or else there's a timing hole) */
  THREAD_LOCK (thread, thread, CALLER_THREAD_WRAPPER);
  if (thread->flags & HYTHREAD_FLAG_SUSPENDED)
    {
      COND_WAIT (thread->condition, thread->mutex);
      if ((thread->flags & HYTHREAD_FLAG_SUSPENDED) == 0)
        break;
      COND_WAIT_LOOP ();
    }
  thread->flags |= HYTHREAD_FLAG_STARTED;
  flags = thread->flags;
  THREAD_UNLOCK (thread, thread);

  if (thread->flags & HYTHREAD_FLAG_CANCELED)
    {
      internal_exit ();
    }

#if defined(LINUX)
  /* Workaround for NPTL bug on Linux. See hythread_exit() */
  {
    jmp_buf jumpBuffer;
    if (0 == setjmp (jumpBuffer))
      {
        thread->jumpBuffer = &jumpBuffer;
        thread->entrypoint (thread->entryarg);
      }
    thread->jumpBuffer = NULL;
  }
#else
  thread->entrypoint (thread->entryarg);
#endif

  internal_exit ();
  /* UNREACHABLE */
  WRAPPER_RETURN ();
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION monitor_notify_one_or_all
/*
 * Signal one or all threads waiting on the monitor.
 * 
 * If no threads are waiting, this does nothing.
 * 
 * @param[in] monitor monitor to be notified on
 * @param[in] notifyall 0 to notify one, non-zero to notify all
 * @return 0 once the monitor has been signalled<br>
 * HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not 
 * own the monitor
 * 
 */
static IDATA
monitor_notify_one_or_all (hythread_monitor_t monitor, int notifyall)
{

  hythread_t self = MACRO_SELF ();
  hythread_t queue, next;
  int someoneNotified = 0;

  ASSERT (self);
  ASSERT (monitor);

  if (monitor->owner != self)
    {
      ASSERT_DEBUG (0);
      return HYTHREAD_ILLEGAL_MONITOR_STATE;
    }

  MONITOR_LOCK (self, monitor, CALLER_NOTIFY_ONE_OR_ALL);

  next = monitor->waiting;

  while (next)
    {
      queue = next;
      next = queue->next;
      THREAD_LOCK (self, queue, CALLER_NOTIFY_ONE_OR_ALL);
      if (queue->flags & HYTHREAD_FLAG_WAITING)
        {
          notify_thread (queue, SET_NOTIFIED_FLAG);
          someoneNotified = 1;
        }
      THREAD_UNLOCK (self, queue);

      if ((someoneNotified) && (!notifyall))
        {
          break;
        }
    }

  MONITOR_UNLOCK (self, monitor);

  return 0;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION notify_thread
/*
 * Notify a thread.
 * 
 * Helper routine because we notify a thread in 
 * a couple of places.
 * @note: assumes the caller has THREAD_LOCK'd the 
 * thread being notified (and owns the monitor being notified on)
 * @param[in] threadToNotify thread to notify
 * @param[in] setNotifiedFlag indicates whether to set the notified thread's notified flag.
 * @return none
 */
static void
notify_thread (hythread_t threadToNotify, int setNotifiedFlag)
{
  ASSERT (threadToNotify);
  ASSERT (threadToNotify->flags & HYTHREAD_FLAG_WAITING);

  threadToNotify->flags &= ~HYTHREAD_FLAG_WAITING;
  threadToNotify->flags |= HYTHREAD_FLAG_BLOCKED;
  if (setNotifiedFlag)
    {
      threadToNotify->flags |= HYTHREAD_FLAG_NOTIFIED;
    }
  COND_NOTIFY_ALL (threadToNotify->condition);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_sleep_interruptable
/** 
 * Suspend the current thread from executing 
 * for at least the specified time.
 *
 * @param[in] millis
 * @param[in] nanos 
 * @return  0 on success<br>
 *    HYTHREAD_INVALID_ARGUMENT if the arguments are invalid<br>
 *    HYTHREAD_INTERRUPTED if the sleep was interrupted
 *
 * @see hythread_sleep
 */
IDATA VMCALL
hythread_sleep_interruptable (I_64 millis, IDATA nanos)
{
  hythread_t self = MACRO_SELF ();
  IDATA boundedMillis = BOUNDED_I64_TO_IDATA (millis);

  ASSERT (self);

  if ((millis < 0) || (nanos < 0) || (nanos >= 1000000))
    {
      return HYTHREAD_INVALID_ARGUMENT;
    }

  THREAD_LOCK (self, self, CALLER_SLEEP_INTERRUPTABLE);

  if (self->flags & HYTHREAD_FLAG_INTERRUPTED)
    {
      self->flags &= ~HYTHREAD_FLAG_INTERRUPTED;
      THREAD_UNLOCK (self, self);
      return HYTHREAD_INTERRUPTED;
    }

  if (self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED)
    {
      self->flags &= ~HYTHREAD_FLAG_PRIORITY_INTERRUPTED;
      THREAD_UNLOCK (self, self);
      return HYTHREAD_PRIORITY_INTERRUPTED;
    }

  self->flags |=
    HYTHREAD_FLAG_SLEEPING | HYTHREAD_FLAG_INTERRUPTABLE |
    HYTHREAD_FLAG_TIMER_SET;

  COND_WAIT_IF_TIMEDOUT (self->condition, self->mutex, boundedMillis, nanos)
  {
    break;
  }
  else
  {
    if (self->flags & HYTHREAD_FLAG_INTERRUPTED)
      {
        self->flags &=
          ~(HYTHREAD_FLAG_INTERRUPTED | HYTHREAD_FLAG_SLEEPING |
            HYTHREAD_FLAG_INTERRUPTABLE | HYTHREAD_FLAG_TIMER_SET);
        THREAD_UNLOCK (self, self);
        return HYTHREAD_INTERRUPTED;
      }
    if (self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED)
      {
        self->flags &=
          ~(HYTHREAD_FLAG_PRIORITY_INTERRUPTED | HYTHREAD_FLAG_SLEEPING |
            HYTHREAD_FLAG_INTERRUPTABLE | HYTHREAD_FLAG_TIMER_SET);
        THREAD_UNLOCK (self, self);
        return HYTHREAD_PRIORITY_INTERRUPTED;
      }
  }
  COND_WAIT_TIMED_LOOP ();

  self->flags &=
    ~(HYTHREAD_FLAG_SLEEPING | HYTHREAD_FLAG_INTERRUPTABLE |
      HYTHREAD_FLAG_TIMER_SET);
  THREAD_UNLOCK (self, self);
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_sleep
/** 
 * Suspend the current thread from executing 
 * for at least the specified time.
 *
 * @param[in] millis minimum number of milliseconds to sleep
 * @return  0 on success<br> HYTHREAD_INVALID_ARGUMENT if millis < 0
 *
 * @see hythread_sleep_interruptable
 */
IDATA VMCALL
hythread_sleep (I_64 millis)
{
  hythread_t self = MACRO_SELF ();

  IDATA boundedMillis = (millis > 0x7FFFFFFF ? 0x7FFFFFFF : (IDATA) millis);

  ASSERT (self);

  if (millis < 0)
    {
      return HYTHREAD_INVALID_ARGUMENT;
    }

  THREAD_LOCK (self, self, CALLER_SLEEP);

  self->flags |= HYTHREAD_FLAG_SLEEPING | HYTHREAD_FLAG_TIMER_SET;

  COND_WAIT_IF_TIMEDOUT (self->condition, self->mutex, boundedMillis, 0)
  {
    break;
  }
  COND_WAIT_TIMED_LOOP ();

  self->flags &= ~(HYTHREAD_FLAG_SLEEPING | HYTHREAD_FLAG_TIMER_SET);
  THREAD_UNLOCK (self, self);
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_lock
/*
 * Acquire the threading library's global lock.
 * 
 * @param[in] self hythread_t for the current thread
 * @param[in] monitor must be NULL
 * @return none
 * 
 * @deprecated This has been replaced by hythread_lib_lock.
 * @see hythread_lib_lock, hythread_lib_unlock
 */
void VMCALL
hythread_monitor_lock (hythread_t self, hythread_monitor_t monitor)
{
  ASSERT (self);

  if (monitor == NULL)
    {
      GLOBAL_LOCK (self, CALLER_GLOBAL_LOCK);
    }
  else
    {
      ASSERT (0);
    }
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_unlock
/*
 * Release the threading library's global lock.
 * 
 * @param[in] self hythread_t for the current thread
 * @param[in] monitor
 * @return none
 * 
 * @deprecated This has been replaced by hythread_lib_unlock.
 * @see hythread_lib_lock, hythread_lib_unlock
 */
void VMCALL
hythread_monitor_unlock (hythread_t self, hythread_monitor_t monitor)
{
  ASSERT (self);

  if (monitor == NULL)
    {
      GLOBAL_UNLOCK (self);
    }
  else
    {
      ASSERT (0);
    }
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_acquire
/*
 * Acquire a monitor from the threading library. (Private)
 * 
 * @param[in] self current thread
 * @param[in] locking policy 
 * @param[in] locking policy data or HYTHREAD_LOCKING_NO_DATA
 * @return NULL on failure, non-NULL on success
 *
 * @see hythread_monitor_init_with_name, hythread_monitor_destroy
 *
 * 
 */
static hythread_monitor_t VMCALL
hythread_monitor_acquire (hythread_t self, IDATA policy, IDATA policyData)
{
  hythread_monitor_t entry;
  hythread_monitor_pool_t pool = self->library->monitor_pool;
  IDATA rc;

  ASSERT (self);
  ASSERT (pool);

  GLOBAL_LOCK (self, CALLER_MONITOR_ACQUIRE);

  entry = pool->next_free;
  if (entry == NULL)
    {
      hythread_monitor_pool_t last_pool = pool;
      while (last_pool->next != NULL)
        last_pool = last_pool->next;
      last_pool->next = allocate_monitor_pool ();
      if (last_pool->next == NULL)
        {
          /* failed to grow monitor pool */
          GLOBAL_UNLOCK (self);
          return NULL;
        }
      entry = last_pool->next->next_free;
    }

  /* the first time that a mutex is acquired from the pool, we need to 
   * initialize its mutex
   */
  if (entry->flags == HYTHREAD_MONITOR_MUTEX_UNINITIALIZED)
    {

      rc = MUTEX_INIT (entry->mutex);

      if (!rc)
        {
          /* failed to initialize mutex */
          ASSERT_DEBUG (0);
          GLOBAL_UNLOCK (self);
          return NULL;
        }

      entry->flags = 0;

    }

  pool->next_free = (hythread_monitor_t) entry->owner;
  entry->count = 0;

  GLOBAL_UNLOCK (self);

  return entry;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_cancel
/** 
 * Terminate a running thread.
 * 
 * @note This should only be used as a last resort.  The system may be in
 * an unpredictable state once a thread is cancelled.  In addition, the thread
 * may not even stop running if it refuses to cancel.
 * 
 * @param[in] thread a thread to be terminated 
 * @return none
 */
void VMCALL
hythread_cancel (hythread_t thread)
{
  hythread_monitor_t monitor = NULL;
  hythread_t self = MACRO_SELF ();

  ASSERT (thread);
  THREAD_LOCK (self, thread, CALLER_CANCEL);

  /* Special case -- we can cancel cleanly if the thread hasn't started yet */
  if ((thread->flags & HYTHREAD_FLAG_STARTED) == 0)
    {
      thread->flags |= HYTHREAD_FLAG_CANCELED;
      THREAD_UNLOCK (self, thread);
      hythread_resume (thread);
      return;
    }

  THREAD_CANCEL (thread->handle);

  thread->flags |= HYTHREAD_FLAG_CANCELED;

  THREAD_UNLOCK (self, thread);

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_detach
/**
 * Detaches the current thread from the threading library.
 * 
 * Detach must only be called by an attached thread.  The actual parameter
 * must be the the current thread's hythread_t, or NULL (in which case this
 * function retrieves and uses the current thread's hythread_t).  This
 * function cannot be used to detach an arbitrary thread.
 *
 * When detached, internal resources associated with the thread are freed
 * and the hythread_t structure becomes invalid.
 * 
 * @param[in] thread
 *            the hythread_t of the current thread to be detached, or NULL
 *            meaning the current thread struct is looked-up and detached.
 * @return none
 * 
 * @see hythread_attach
 */
void VMCALL
hythread_detach (hythread_t thread)
{
  UDATA destroy = 0;
  UDATA attached = 0;
  hythread_t self = MACRO_SELF ();

  if (thread == NULL)
    {
      thread = self;
    }
  ASSERT (thread);

  THREAD_LOCK (self, thread, CALLER_DETACH);
  if (thread->attachcount < 1)
    {
      /* error! */
    }
  else
    {
      if (--thread->attachcount == 0)
        {
          if (thread->flags & HYTHREAD_FLAG_ATTACHED)
            {
              /* this is an attached thread, and it is now fully
                 detached.  Mark it dead so that it can be destroyed */
              thread->flags |= HYTHREAD_FLAG_DEAD;
              attached = destroy = 1;
            }
          else
            {
              destroy = thread->flags & HYTHREAD_FLAG_DEAD;
            }
        }
    }
  THREAD_UNLOCK (self, thread);

  if (destroy)
    {
      hythread_library_t library = thread->library;

      tls_finalize (thread);

      destroy_thread (thread, GLOBAL_NOT_LOCKED);
      if (attached)
        {
          TLS_SET (library->self_ptr, NULL);
        }
    }
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_exit
/**
 * Exit the current thread.
 * 
 * If the thread has been detached, it is destroyed.
 * 
 * If monitor is not NULL, the monitor will be exited before the thread terminates. 
 * This is useful if the thread wishes to signal its termination to a watcher, since
 * it exits the monitor and terminates the thread without ever returning control
 * to the thread's routine, which might be running in a DLL which is about to
 * be closed.
 *
 * @param[in] monitor monitor to be exited before exiting (ignored if NULL)
 * @return none
 */
void VMCALL NORETURN
hythread_exit (hythread_monitor_t monitor)
{
  hythread_t self = MACRO_SELF ();

  if (monitor)
    {
      hythread_monitor_exit (monitor);
    }

  /* Walk all monitors: if this thread owns a monitor, exit it */
  monitor = NULL;
  while ((monitor = hythread_monitor_walk (monitor)) != NULL)
    {
      if (monitor->owner == self)
        {
          monitor->count = 1;   /* exit n-1 times */
          hythread_monitor_exit (monitor);
        }
    }

#if defined(LINUX)
  /* NPTL calls __pthread_unwind() from pthread_exit(). That walks the stack.
   * We can't allow that to happen, since our caller might have already been 
   * unloaded. Walking the calling frame could cause a crash. Instead, we
   * longjmp back out to the initial frame.
   */
  if (self->jumpBuffer)
    {
      longjmp (*(jmp_buf *) self->jumpBuffer, 1);
    }
#endif

  internal_exit ();

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_priority_interrupt
/** 
 * Priority interrupt a thread.
 *
 * If the thread is currently blocked (i.e. waiting on a monitor_wait or sleeping)
 * resume the thread and return from the blocking function with
 * HYTHREAD_PRIORITY_INTERRUPTED
 * 
 * @param[in] thread a thead to be priority interrupted
 * @return none
 */
void VMCALL
hythread_priority_interrupt (hythread_t thread)
{
  interrupt_thread (thread, HYTHREAD_FLAG_PRIORITY_INTERRUPTED);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_priority_interrupted
/**
 * Return the value of a thread's priority interrupted flag.
 * 
 * @param[in] thread thread to be queried
 * @return 0 if not priority interrupted, non-zero if priority interrupted flag set
 */
UDATA VMCALL
hythread_priority_interrupted (hythread_t thread)
{
  return (thread->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED) != 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_clear_priority_interrupted
/**
 * Clear the priority interrupted flag of the current thread and return its previous value.
 * 
 * @return  previous value of priority interrupted flag: nonzero if the thread had been priority interrupted.
 */
UDATA VMCALL
hythread_clear_priority_interrupted (void)
{
  UDATA oldFlags;
  hythread_t self = MACRO_SELF ();
  ASSERT (self);

  THREAD_LOCK (self, self, CALLER_CLEAR_PRIORITY_INTERRUPTED);
  oldFlags = self->flags;
  self->flags = oldFlags & ~HYTHREAD_FLAG_PRIORITY_INTERRUPTED;
  THREAD_UNLOCK (self, self);

  return (oldFlags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED) != 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_try_enter
/** 
 * Attempt to enter a monitor without blocking.
 * 
 * If the thread must block before it enters the monitor this function
 * returns immediately with a negative value to indicate failure.
 * 
 * @param[in] monitor a monitor
 * @return  0 on success or negative value on failure
 *
 * @see hythread_monitor_try_enter_using_threadId
 *
 */
IDATA VMCALL
hythread_monitor_try_enter (hythread_monitor_t monitor)
{
  return hythread_monitor_try_enter_using_threadId (monitor, MACRO_SELF ());
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_shutdown
/**
 * Shut down the Hy threading library associated with the current thread.
 * 
 * @return none
 * 
 * @see hythread_init
 */
void VMCALL
hythread_shutdown (void)
{
  hythread_library_t lib = GLOBAL_DATA (default_library);
  ASSERT (lib);
  MUTEX_DESTROY (lib->tls_mutex);
  MUTEX_DESTROY (lib->monitor_mutex);
  MUTEX_DESTROY (lib->global_mutex);
  pool_kill (lib->global_pool);
  free_monitor_pools ();
#if !defined(LINUX)
  TLS_DESTROY (lib->self_ptr);
  pool_kill (lib->thread_pool);
#endif /* LINUX */

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION allocate_thread
/*
 * Allocate a hythread_t from the hythread_t pool.
 * 
 * @note assumes the threading library's thread pool is already initialized
 * @param[in] globalIsLocked indicates whether the threading library global mutex is already locked.
 * @return a new hythread_t on success, NULL on failure.
 * 
 */
static hythread_t
allocate_thread (int globalIsLocked)
{
  hythread_t result;
  hythread_library_t lib = GLOBAL_DATA (default_library);
  ASSERT (lib);

  if (!globalIsLocked)
    {
      GLOBAL_LOCK_SIMPLE (lib);
    }
  lib->threadCount++;
  result = pool_newElement (lib->thread_pool);
  if (!globalIsLocked)
    {
      GLOBAL_UNLOCK_SIMPLE (lib);
    }

  if (result)
    {
      memset (result, 0, sizeof (HyThread));
    }

  return result;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION free_thread
/*
 * Return a hythread_t to the threading library's monitor pool.
 *
 * @param[in] thread thread to be returned to the pool
 * @param[in] globalAlreadyLocked indicated whether the threading library global 
 * mutex is already locked
 * @return none
 */
static void
free_thread (hythread_t thread, int globalAlreadyLocked)
{
  hythread_library_t lib = thread->library;

  ASSERT (thread);

  if (!globalAlreadyLocked)
    {
      GLOBAL_LOCK_SIMPLE (lib);
    }
  pool_removeElement (lib->thread_pool, thread);
  lib->threadCount--;

  if (!globalAlreadyLocked)
    {
      GLOBAL_UNLOCK_SIMPLE (lib);
    }

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION thread_malloc
/*
 * Malloc a thread (hythread_t struct).
 * 
 * Helper function used by the library's thread pool
 * 
 * @param unused ignored
 * @param size size of struct to be alloc'd
 * @return pointer to the malloc'd memory<br>
 * 0 on failure
 *
 */
static void *VMCALL
thread_malloc (void *unused, U_32 size)
{
  return malloc (size);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION thread_free
/*
 * Free a thread (hythread_t struct)
 * Function used by the library's thread pool
 * 
 * @param unused ignored
 * @param prt pointer to hythread_t to be freed
 * @return none
 *
 */
static void VMCALL
thread_free (void *unused, void *ptr)
{
  free (ptr);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION free_monitor_pools
/*
 * Free the Hy threading library's monitor pool.
 * 
 * This requires destroying each and every one of the 
 * monitors in the pool.
 * 
 * @return none
 */
static void
free_monitor_pools (void)
{
  hythread_library_t lib = GLOBAL_DATA (default_library);
  hythread_monitor_pool_t pool = lib->monitor_pool;

  ASSERT (lib);
  ASSERT (pool);

  while (pool)
    {
      int i;
      hythread_monitor_pool_t next = pool->next;
      hythread_monitor_t entry = &pool->entries[0];
      for (i = 0; i < MONITOR_POOL_SIZE - 1; i++, entry++)
        {
          if (entry->flags != HYTHREAD_MONITOR_MUTEX_UNINITIALIZED)
            {
              MUTEX_DESTROY (entry->mutex);
            }
        }
      free (pool);
      pool = next;
    }

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION init_global_monitor
/* 
 * Initialize the mutex used to synchronize access 
 * to thread library global data.
 *
 * @param[in] lib pointer to the thread library
 * @return 0 on success or negative value on failure
 * 
 */
static IDATA
init_global_monitor (hythread_library_t lib)
{
  hythread_monitor_pool_t pool = lib->monitor_pool;
  hythread_monitor_t monitor = pool->next_free;
  ASSERT (monitor);
  pool->next_free = (hythread_monitor_t) monitor->owner;

  if (init_monitor (monitor, 0) != 0)
    {
      return -1;
    }
  if (!MUTEX_INIT (monitor->mutex))
    {
      return -1;
    }

  monitor->name = "Thread global";

  *hythread_global ("global_monitor") = (UDATA) monitor;

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION internal_exit
/*
 * Exit from the current thread.
 * 
 * If the thread has been detached it is destroyed.
 */
static void NORETURN
internal_exit (void)
{

  hythread_t self = MACRO_SELF ();
  hythread_library_t lib = self->library;
  int detached;

  ASSERT (self);
  ASSERT (lib);

  tls_finalize (self);

  GLOBAL_LOCK (self, CALLER_INTERNAL_EXIT1);
  THREAD_LOCK (self, self, CALLER_INTERNAL_EXIT1);
  self->flags |= HYTHREAD_FLAG_DEAD;
  detached = self->attachcount == 0;

  /* 
   * Is there an interruptServer thread out there
   * trying to interrupt us? Its services are 
   * no longer required.
   */
  if (self->interrupter)
    {
      THREAD_LOCK (self, self->interrupter, CALLER_INTERNAL_EXIT1);
      self->interrupter->flags |= HYTHREAD_FLAG_CANCELED;
      THREAD_UNLOCK (self, self->interrupter);
      self->interrupter = NULL;
    }

  THREAD_UNLOCK (self, self);

  /* On z/OS we create the thread in the detached state, so the */
  /* call to pthread_detach is not required.                     @dfa1 */
  THREAD_DETACH (self->handle);

  if (detached)
    {
      destroy_thread (self, GLOBAL_IS_LOCKED);
    }

  GLOBAL_UNLOCK_SIMPLE (lib);
  THREAD_EXIT ();
  ASSERT (0);
  /* UNREACHABLE */

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION enqueue_thread
/*
 * Add a thread to a monitor's wait queue.
 * 
 * @note The calling thread must be the current owner of the monitor
 * @param[in] queue head of the monitor's wait queue
 * @param[in] thread thread to be added
 * @return none
 * 
 */
static void
enqueue_thread (hythread_t * queue, hythread_t thread)
{
  hythread_t qthread = *queue;

  ASSERT (thread);
  /* can't be on two queues at the same time */
  ASSERT (NULL == thread->next);

  if (qthread != NULL)
    {
      while (qthread->next)
        {
          qthread = qthread->next;
        }
      qthread->next = thread;
    }
  else
    {
      *queue = thread;
    }

  ASSERT (*queue != NULL);
  ASSERT (NULL == thread->next);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_wait_timed
/** 
 * Wait on a monitor until notified or timed out.
 *
 * A timeout of 0 (0ms, 0ns) indicates wait indefinitely.
 * 
 * @param[in] monitor a monitor to be waited on
 * @param[in] millis >=0
 * @param[in] nanos >=0
 *
 * @return  0 the monitor has been waited on, notified, and reobtained<br>
 * HYTHREAD_INVALID_ARGUMENT millis or nanos is out of range (millis or nanos < 0, or nanos >= 1E6)<br>
 * HYTHREAD_ILLEGAL_MONITOR_STATE the current thread does not own the monitor<br>
 * HYTHREAD_TIMED_OUT the timeout expired
 * 
 * @see hythread_monitor_wait, hythread_monitor_wait_interruptable, hythread_monitor_enter
 * 
 */
IDATA VMCALL
hythread_monitor_wait_timed (hythread_monitor_t monitor, I_64 millis,
                             IDATA nanos)
{
  return monitor_wait (monitor, millis, nanos, WAIT_UNINTERRUPTABLE);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_dump_trace

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_dump_all

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_dump_trace

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_global
/** 
 * Fetch or create a 'named global'.
 *
 * Return a pointer to the data associated with a named global with the specified name.<br>
 * A new named global is created if a named global with the specified name can't be found.
 *
 * @param[in] name name of named global to read/create
 * @return a pointer to a UDATA associated with name<br>
 * 0 on failure.
 * 
 */
UDATA *VMCALL
hythread_global (const char *name)
{
  HyThreadGlobal *global;
  hythread_library_t lib = GLOBAL_DATA (default_library);

  MUTEX_ENTER (lib->global_mutex);

  global = lib->globals;

  while (global)
    {
      if (strcmp (global->name, name) == 0)
        {
          MUTEX_EXIT (lib->global_mutex);
          return &global->data;
        }
      global = global->next;
    }

  /*
   * If we got here, we couldn't find it, therefore
   * we will create a new one
   */

  global = pool_newElement (lib->global_pool);
  if (global == NULL)
    {
      MUTEX_EXIT (lib->global_mutex);
      return NULL;
    }

  global->next = lib->globals;
  global->name = name;
  global->data = 0;
  lib->globals = global;

  MUTEX_EXIT (lib->global_mutex);

  return &global->data;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hysem_init
/*
 * Initialize a semaphore.
 *
 * Acquire a semaphore from the threading library.
 * 
 * @param[out] sp pointer to semaphore to be initialized
 * @param[in] initValue initial count value (>=0) for the semaphore
 * @return  0 on success or negative value on failure
 *
 * @deprecated Semaphores are no longer supported.
 * 
 * @see hysem_destroy, hysem_init, hysem_post
 */
IDATA VMCALL
hysem_init (hysem_t * sp, I_32 initValue)
{
  hysem_t s;
  IDATA rc = -1;

  (*sp) = s = SEM_CREATE (initValue);
  if (s)
    {
      rc = SEM_INIT (s, 0, initValue);
    }
  return rc;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hysem_destroy
/*
 * Destroy a semaphore.
 *
 * Returns the resources associated with a semaphore back to the Hy threading library.
 * 
 * @param[in] s semaphore to be destroyed
 * @return  0 on success or negative value on failure
 *
 * @deprecated Semaphores are no longer supported.
 * 
 * @see hysem_init, hysem_wait, hysem_post
 */
IDATA VMCALL
hysem_destroy (hysem_t s)
{
  int rval = 0;
  if (s)
    {
      rval = SEM_DESTROY (s);
      SEM_FREE (s);
    }
  return rval;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hysem_post
/*
 * Release a semaphore by 1.
 * 
 * @param[in] s semaphore to be released by 1
 * @return  0 on success or negative value on failure
 *
 * @deprecated Semaphores are no longer supported.
 *
 * @see hysem_init, hysem_destroy, hysem_wait
 */
IDATA VMCALL
hysem_post (hysem_t s)
{
  if (s)
    {
      return SEM_POST (s);
    }
  return -1;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hysem_wait
/*
 * Wait on a semaphore.
 * 
 * @param[in] s semaphore to be waited on 
 * @return  0 on success or negative value on failure
 *
 * @deprecated Semaphores are no longer supported.
 *
 * @see hysem_init, hysem_destroy, hysem_wait
 *
 */
IDATA VMCALL
hysem_wait (hysem_t s)
{
  if (s)
    {
      while (SEM_WAIT (s) != 0)
        {
          /* loop until success */
        }
      return 0;
    }
  else
    {
      return -1;
    }

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION error

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION monitor_enter
/*
 * Enter a monitor.
 * 
 * A thread may enter a monitor it owns multiple times, but must
 * exit the monitor the same number of times before other threads
 * waiting on the monitor are permitted to continue
 * 
 * @param[in] self current thread
 * @param[in] monitor monitor to enter
 * @return 0 on success<br>
 * HYTHREAD_PRIORITY_INTERRUPTED if the thread was priority 
 * interrupted while blocked
 */
static IDATA
monitor_enter (hythread_t self, hythread_monitor_t monitor)
{

  ASSERT (self);
  ASSERT (0 == self->monitor);
  ASSERT (monitor);
  ASSERT (monitor->owner != self);
  ASSERT (FREE_TAG != monitor->count);

  return monitor_enter_three_tier (self, monitor);

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION monitor_enter_three_tier

/*
 * Enter a three-tier monitor.
 * 
 * Spin on a spinlock. Block when that fails, and repeat.
 * 
 * @param[in] self current thread
 * @param[in] monitor monitor to enter
 * @return 0 on success
 */

static IDATA
monitor_enter_three_tier (hythread_t self, hythread_monitor_t monitor)
{
  int firstTimeBlocking = 1;

  while (1)
    {

      if (hythread_spinlock_acquire (self, monitor) == 0)
        {
          monitor->owner = self;
          monitor->count = 1;
          ASSERT (monitor->spinlockState !=
                  HYTHREAD_MONITOR_SPINLOCK_UNOWNED);
          break;
        }

      MONITOR_LOCK (self, monitor, CALLER_MONITOR_ENTER_THREE_TIER1);

      if (HYTHREAD_MONITOR_SPINLOCK_UNOWNED ==
          hythread_spinlock_swapState (monitor,
                                       HYTHREAD_MONITOR_SPINLOCK_EXCEEDED))
        {
          MONITOR_UNLOCK (self, monitor);
          monitor->owner = self;
          monitor->count = 1;
          ASSERT (monitor->spinlockState !=
                  HYTHREAD_MONITOR_SPINLOCK_UNOWNED);
          break;
        }

      THREAD_LOCK (self, self, CALLER_MONITOR_ENTER_THREE_TIER2);
      self->flags |= (HYTHREAD_FLAG_BLOCKED);
      self->monitor = monitor;
      THREAD_UNLOCK (self, self);

      /* 
       * First time we've had to block? 
       * If so, record the info for JLM.
       */
      if (IS_JLM_ENABLED (self))
        {
          if (firstTimeBlocking)
            {
              firstTimeBlocking = 0;

            }
        }

      enqueue_thread (&monitor->blocking, self);
      COND_WAIT (self->condition, monitor->mutex);
      break;
      COND_WAIT_LOOP ();
      remove_from_queue (&monitor->blocking, self);

      MONITOR_UNLOCK (self, monitor);

    }

  /* We now own the monitor */

  /*
   * If the monitor field is set, we must have blocked on it
   * at some point. We're no longer blocked, so clear this.
   */
  if (self->monitor != 0)
    {
      THREAD_LOCK (self, self, CALLER_MONITOR_ENTER_THREE_TIER3);
      self->flags &= ~(HYTHREAD_FLAG_BLOCKED);
      self->monitor = 0;
      THREAD_UNLOCK (self, self);
    }

  /* Did we block? If so, finish up the JLM calcs */
  /* TODO: this is pretty much the same as in monitor_enter.... */
  if (IS_JLM_ENABLED (self))
    {
      monitor->tracing->enter_count++;
      if (0 == firstTimeBlocking)
        {
          monitor->tracing->slow_count++;

        }
    }

  ASSERT (!(self->flags & HYTHREAD_FLAG_BLOCKED));
  ASSERT (0 == self->monitor);

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION monitor_exit
/*
 * Exit a monitor.
 * 
 * If the current thread is not the owner of the monitor, the
 * mutex is unaffected, and an error is returned. This should be
 * tested to determine if IllegalMonitorState should be
 * thrown.
 * 
 * @param[in] self current thread
 * @param[in] monitor monitor to be exited
 * @return 0 on success<br>
 * HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not 
 * own the monitor
 */
static IDATA
monitor_exit (hythread_t self, hythread_monitor_t monitor)
{

  ASSERT (monitor);
  ASSERT (self);
  ASSERT (0 == self->monitor);

  if (monitor->owner != self)
    {
      ASSERT_DEBUG (0);
      return HYTHREAD_ILLEGAL_MONITOR_STATE;
    }

  monitor->count--;
  ASSERT (monitor->count >= 0);

  if (monitor->count == 0)
    {
      monitor->owner = NULL;

      if (HYTHREAD_MONITOR_SPINLOCK_EXCEEDED ==
          hythread_spinlock_swapState (monitor,
                                       HYTHREAD_MONITOR_SPINLOCK_UNOWNED))
        {
          MONITOR_LOCK (self, monitor, CALLER_MONITOR_EXIT1);
          unblock_spinlock_threads (self, monitor);
          MONITOR_UNLOCK (self, monitor);
        }

    }

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION unblock_spinlock_threads

/*
 * Notify all threads blocked on the monitor's mutex, waiting
 * to be told that it's ok to try again to get the spinlock.
 * 
 * Assumes that the caller already owns the monitor's mutex.
 *
 */
static void
unblock_spinlock_threads (hythread_t self, hythread_monitor_t monitor)
{
  hythread_t queue, next;

  ASSERT (self);
  ASSERT (monitor);

  next = monitor->blocking;
  while (next)
    {
      queue = next;
      next = queue->next;
      COND_NOTIFY_ALL (queue->condition);
    }
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_reset_tracing

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_wait_interruptable
/** 
 * Wait on a monitor until notified, interrupted (priority or normal), or timed out.
 *
 * A timeout of 0 (0ms, 0ns) indicates wait indefinitely.
 * 
 * If 'interruptable' is non-zero, the wait may be interrupted by one of the 
 * interrupt functions. (i.e. hythread_interrupt, hythread_priority_interrupt);
 *
 * @param[in] monitor a monitor to be waited on
 * @param[in] millis >=0
 * @param[in] nanos >=0
 * @param[in] interruptable non-zero if the wait is to be interruptable
 *
 * @return   0 the monitor has been waited on, notified, and reobtained<br>
 * HYTHREAD_INVALID_ARGUMENT if millis or nanos is out of range (millis or nanos < 0, or nanos >= 1E6)<br>
 * HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor<br>
 * HYTHREAD_INTERRUPTED if the thread was interrupted while waiting<br>
 * HYTHREAD_PRIORITY_INTERRUPTED if the thread was priority interrupted while waiting, or while re-obtaining the monitor<br>
 * HYTHREAD_TIMED_OUT if the timeout expired<br>
 * 
 * @see hythread_monitor_wait, hythread_monitor_wait_timed, hythread_monitor_enter
 * @see hythread_interrupt, hythread_priority_interrupt *
 */
IDATA VMCALL
hythread_monitor_wait_interruptable (hythread_monitor_t monitor, I_64 millis,
                                     IDATA nanos)
{
  return monitor_wait (monitor, millis, nanos, WAIT_INTERRUPTABLE);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_num_waiting
/**
 * Returns how many threads are currently waiting on a monitor.
 * 
 * @note This can only be called by the owner of this monitor.
 *
 * @param[in] monitor a monitor
 * @return number of threads waiting on the monitor (>=0)
 */
UDATA VMCALL
hythread_monitor_num_waiting (hythread_monitor_t monitor)
{
  UDATA numWaiting = 0;
  hythread_t curr;
  hythread_t self = MACRO_SELF ();

  ASSERT (monitor);

  MONITOR_LOCK (self, monitor, CALLER_MONITOR_NUM_WAITING);

  curr = monitor->waiting;
  while (curr != NULL)
    {
      numWaiting++;
      curr = curr->next;
    }

  MONITOR_UNLOCK (self, monitor);

  return numWaiting;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION monitor_wait
/*
 * 
 * Wait on a monitor.
 * 
 * Release the monitor, wait for a signal (notification), then re-acquire the monitor.
 * 
 * In this function, we 'unwind' any recursive hold (monitor->count) the thread has 
 * on the monitor and release the OS monitor. When the monitor is re-acquired, 
 * the recursive count is restored to its original value.
 *
 * A timeout of 0 (0ms, 0ns) indicates wait indefinitely.
 * 
 * If 'interruptable' is non-zero, the wait may be interrupted by one of the 
 * interrupt functions. (i.e. hythread_interrupt, hythread_priority_interrupt);
 *
 * @param[in] monitor monitor to be waited on
 * @param[in] millis >=0
 * @param[in] nanos >=0
 * @param[in] interruptable non-zero if the wait is to be interruptable
 *
 * @return HYTHREAD_INVALID_ARGUMENT      - if millis or nanos is out of range (millis or nanos < 0, or nanos >= 1E6)
 *          HYTHREAD_ILLEGAL_MONITOR_STATE - the current thread does not own the monitor
 *          0                              - the monitor has been waited on, notified, and reobtained
 *          HYTHREAD_INTERRUPTED           - the thread was interrupted while waiting
 *          HYTHREAD_PRIORITY_INTERRUPTED  - if the thread was priority interrupted while waiting, or while re-obtaining the monitor
 *          HYTHREAD_TIMED_OUT             - the timeout expired
 * 
 * @see hythread_monitor_wait, hythread_monitor_wait_interruptable, hythread_monitor_enter
 * @see hythread_interrupt, hythread_priority_interrupt
 */
static IDATA
monitor_wait (hythread_monitor_t monitor, I_64 millis, IDATA nanos,
              IDATA interruptable)
{
  hythread_t self = MACRO_SELF ();
  IDATA count = -1;
  UDATA flags;
  UDATA interrupted = 0, notified = 0, priorityinterrupted = 0;
  UDATA timedOut = 0;

  ASSERT (monitor);
  ASSERT (FREE_TAG != monitor->count);

  if (monitor->owner != self)
    {
      ASSERT_DEBUG (0);
      return HYTHREAD_ILLEGAL_MONITOR_STATE;
    }

  if ((millis < 0) || (nanos < 0) || (nanos >= 1000000))
    {
      ASSERT_DEBUG (0);
      return HYTHREAD_INVALID_ARGUMENT;
    }

  count = monitor->count;
  flags = monitor->flags;

  THREAD_LOCK (self, self, CALLER_MONITOR_WAIT1);
  ASSERT (0 == self->monitor);

  /*
   * Before we wait, check if we've already been either interrupted or pri interrupted
   */
  if (interruptable && (self->flags & HYTHREAD_FLAG_INTERRUPTED))
    {
      self->flags &= ~HYTHREAD_FLAG_INTERRUPTED;
      THREAD_UNLOCK (self, self);
      return HYTHREAD_INTERRUPTED;
    }

  if (interruptable && (self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED))
    {
      self->flags &= ~HYTHREAD_FLAG_PRIORITY_INTERRUPTED;
      THREAD_UNLOCK (self, self);
      return HYTHREAD_PRIORITY_INTERRUPTED;
    }

  self->flags |=
    (HYTHREAD_FLAG_WAITING |
     (interruptable ? HYTHREAD_FLAG_INTERRUPTABLE : 0));
  if (millis || nanos)
    {
      self->flags |= HYTHREAD_FLAG_TIMER_SET;
    }
  self->monitor = monitor;
  THREAD_UNLOCK (self, self);

  ASSERT (self->flags & HYTHREAD_FLAG_WAITING);
  monitor->owner = NULL;
  monitor->count = 0;

  MONITOR_LOCK (self, monitor, CALLER_MONITOR_WAIT);
  if (HYTHREAD_MONITOR_SPINLOCK_EXCEEDED ==
      hythread_spinlock_swapState (monitor,
                                   HYTHREAD_MONITOR_SPINLOCK_UNOWNED))
    {
      unblock_spinlock_threads (self, monitor);
    }

  enqueue_thread (&monitor->waiting, self);

  if (millis || nanos)
    {
      IDATA boundedMillis = BOUNDED_I64_TO_IDATA (millis);

      COND_WAIT_IF_TIMEDOUT (self->condition, monitor->mutex, boundedMillis,
                             nanos)
      {

        THREAD_LOCK (self, self, CALLER_MONITOR_WAIT2);
        interrupted = interruptable
          && ((self->flags & HYTHREAD_FLAG_INTERRUPTED) != 0);
        priorityinterrupted = interruptable
          && ((self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED) != 0);
        notified = self->flags & HYTHREAD_FLAG_NOTIFIED;
        if (!(interrupted || priorityinterrupted || notified))
          {
            timedOut = 1;
          }
        break;
      }
      else
      {

        THREAD_LOCK (self, self, CALLER_MONITOR_WAIT2);
        interrupted = interruptable
          && ((self->flags & HYTHREAD_FLAG_INTERRUPTED) != 0);
        priorityinterrupted = interruptable
          && ((self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED) != 0);
        notified = self->flags & HYTHREAD_FLAG_NOTIFIED;
        if (interrupted || priorityinterrupted || notified)
          {
            break;
          }
        /* must have been spurious */
        ASSERT_DEBUG (0);
        THREAD_UNLOCK (self, self);
      }
      COND_WAIT_TIMED_LOOP ();
    }
  else
    {
      /*
       * WAIT UNTIL NOTIFIED
       */

      COND_WAIT (self->condition, monitor->mutex);

      THREAD_LOCK (self, self, CALLER_MONITOR_WAIT2);
      interrupted = interruptable
        && ((self->flags & HYTHREAD_FLAG_INTERRUPTED) != 0);
      priorityinterrupted = interruptable
        && ((self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED) != 0);
      notified = self->flags & HYTHREAD_FLAG_NOTIFIED;
      if (interrupted || priorityinterrupted || notified)
        {
          break;
        }
      /* must have been spurious */
      ASSERT_DEBUG (0);
      THREAD_UNLOCK (self, self);
      COND_WAIT_LOOP ();
    }

  /* DONE WAITING AT THIS POINT */

  /* we have to remove self from the wait queue */
  remove_from_queue (&monitor->waiting, self);

  MONITOR_UNLOCK (self, monitor);

  /* at this point, this thread should already be locked */
  ASSERT (notified || interrupted || priorityinterrupted || timedOut);
  ASSERT (!interrupted || interruptable);       /* if we were interrupted, then we'd better have been interruptable */

  self->flags &=
    ~(HYTHREAD_FLAG_WAITING | HYTHREAD_FLAG_NOTIFIED |
      HYTHREAD_FLAG_PRIORITY_INTERRUPTED | HYTHREAD_FLAG_INTERRUPTABLE |
      HYTHREAD_FLAG_TIMER_SET);

  if (interrupted && !(notified || priorityinterrupted))
    self->flags &= ~HYTHREAD_FLAG_INTERRUPTED;

  /* 
   * Is there an interruptServer thread out there
   * trying to interrupt us? Its services are 
   * no longer required.
   */
  if (self->interrupter)
    {
      ASSERT (interrupted || priorityinterrupted);
      THREAD_LOCK (self, self->interrupter, CALLER_MONITOR_WAIT2);
      self->interrupter->flags |= HYTHREAD_FLAG_CANCELED;
      THREAD_UNLOCK (self, self->interrupter);
      self->interrupter = NULL;
    }

  THREAD_UNLOCK (self, self);

  monitor_enter_three_tier (self, monitor);

  monitor->count = count;

  ASSERT (monitor->owner == self);
  ASSERT (monitor->count == count);
  ASSERT (monitor->count >= 1);
  ASSERT (0 == self->monitor);
  ASSERT (!(monitor->flags & HYTHREAD_FLAG_WAITING));
  ASSERT (!(monitor->flags & HYTHREAD_FLAG_TIMER_SET));
  ASSERT (!(monitor->flags & HYTHREAD_FLAG_BLOCKED));
  ASSERT (!(monitor->flags & HYTHREAD_FLAG_NOTIFIED));
  ASSERT (!(monitor->flags & HYTHREAD_FLAG_INTERRUPTABLE));
  ASSERT (NULL == self->next);

  if (priorityinterrupted)
    return HYTHREAD_PRIORITY_INTERRUPTED;
  if (notified)
    return 0;
  if (interrupted)
    return HYTHREAD_INTERRUPTED;
  if (timedOut)
    return HYTHREAD_TIMED_OUT;
  ASSERT (0);
  return 0;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION interrupt_thread
/*
 * Interrupt a thread.
 *
 * If the thread is currently blocked (e.g. waiting on monitor_wait) 
 * resume the thread and return from the blocking function with
 * HYTHREAD_INTERRUPTED or HYTHREAD_PRIORITY_INTERRUPTED
 * 
 * If it can't be resumed (it's not in an interruptable state)
 * then just set the appropriate interrupt flag.
 * 
 * @param[in] thread thread to be interrupted
 * @param[in] interruptFlag indicated whether to priority interrupt or just normally interrupt.
 * @return none
 */
static void
interrupt_thread (hythread_t thread, UDATA interruptFlag)
{
  UDATA currFlags, newFlags;
  hythread_t self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (thread);

  GLOBAL_LOCK (self, CALLER_INTERRUPT_THREAD);
  THREAD_LOCK (self, thread, CALLER_INTERRUPT_THREAD);
  if (thread->flags & interruptFlag)
    {
      THREAD_UNLOCK (self, thread);
      GLOBAL_UNLOCK (self);
      return;
    }

  currFlags = thread->flags;
  newFlags = currFlags | interruptFlag;
  if (currFlags & HYTHREAD_FLAG_INTERRUPTABLE)
    {
      if (currFlags & (HYTHREAD_FLAG_SLEEPING | HYTHREAD_FLAG_PARKED))
        {
          COND_NOTIFY_ALL (thread->condition);
        }
      else if (currFlags & HYTHREAD_FLAG_WAITING)
        {
          if (interrupt_waiting_thread (self, thread))
            {
              newFlags |= HYTHREAD_FLAG_BLOCKED;
            }
        }
    }

  thread->flags = newFlags;
  THREAD_UNLOCK (self, thread);
  GLOBAL_UNLOCK (self);

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION interrupt_waiting_thread
/*
 * Interrupt a waiting thread.
 * 
 * @param[in] self current thread
 * @param[in] threadToInterrupt
 * @return 1 if the thread was immediately interrupted<br>
 * 0 if the thread will be interrupted asap by a special thread.
 * @note: Assumes caller has locked the global mutex
 */
static IDATA
interrupt_waiting_thread (hythread_t self, hythread_t threadToInterrupt)
{

  IDATA retVal = 0;
  hythread_monitor_t monitor;

  ASSERT (self);
  ASSERT (threadToInterrupt);
  ASSERT (self != threadToInterrupt);
  ASSERT (threadToInterrupt->flags & HYTHREAD_FLAG_INTERRUPTABLE);
  ASSERT (threadToInterrupt->monitor);
  ASSERT (NULL == threadToInterrupt->interrupter);

#if !defined(ALWAYS_SPAWN_THREAD_TO_INTERRUPT)
  /*
   * If we can enter the monitor without blocking, we don't need the
   * interruptServer thread
   */
  monitor = threadToInterrupt->monitor;
  if (hythread_monitor_try_enter_using_threadId (monitor, self) == 0)
    {
      ASSERT (monitor->owner == self);
      COND_NOTIFY_ALL (threadToInterrupt->condition);
      hythread_monitor_exit_using_threadId (monitor, self);
      retVal = 1;
    }
  else
#endif

    {
      /*
       * spawn a thread to do it for us, because it's possible that
       * having this thread lock the waiting thread's monitor may
       * cause deadlock
       */
      create_thread (&threadToInterrupt->interrupter, 0,
                     HYTHREAD_PRIORITY_NORMAL, 0, interruptServer,
                     (void *) threadToInterrupt, GLOBAL_IS_LOCKED);
    }
  return retVal;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION interruptServer
/*
 * Interrupt a thread waiting on a monitor.
 *  
 * This function serves as the entry point for a 
 * thread whose sole purpose is to interrupt another
 * thread.
 * 
 * @param[in] entryArg pointer to the thread to interrupt (non-NULL)
 * @return 0
 */
static I_32 HYTHREAD_PROC
interruptServer (void *entryArg)
{
  hythread_t self = MACRO_SELF ();
  hythread_t threadToInterrupt = (hythread_t) entryArg;
  hythread_monitor_t monitor;

  ASSERT (threadToInterrupt);
  ASSERT (self);

  GLOBAL_LOCK (self, CALLER_INTERRUPT_SERVER);

  /*
   * Did the thread to interrupt die or come out of wait already?
   * If it did, it cancelled this thread (set our CANCELED bit)
   */
  if (self->flags & HYTHREAD_FLAG_CANCELED)
    {
      GLOBAL_UNLOCK (self);
      hythread_exit (NULL);     /* this should not return */
    }

  THREAD_LOCK (self, threadToInterrupt, CALLER_INTERRUPT_SERVER);

  if (threadToInterrupt->interrupter != self)
    {
      THREAD_UNLOCK (self, threadToInterrupt);
      GLOBAL_UNLOCK (self);
      hythread_exit (NULL);     /* this should not return */
    }

  monitor = threadToInterrupt->monitor;
  ASSERT (monitor);
  ASSERT (threadToInterrupt->flags & HYTHREAD_FLAG_WAITING);

  hythread_monitor_pin (monitor, self);
  THREAD_UNLOCK (self, threadToInterrupt);
  GLOBAL_UNLOCK (self);

  /* try to take the monitor so that we can notify the thread to interrupt */
  hythread_monitor_enter (monitor);

  GLOBAL_LOCK (self, CALLER_INTERRUPT_SERVER);
  hythread_monitor_unpin (monitor, self);

  /* Did the thread to interrupt die or come out of wait already? */
  if (self->flags & HYTHREAD_FLAG_CANCELED)
    {
      GLOBAL_UNLOCK (self);
      hythread_exit (monitor);  /* this should not return */
      ASSERT (0);
    }

  THREAD_LOCK (self, threadToInterrupt, CALLER_INTERRUPT_SERVER);
  if ((threadToInterrupt->interrupter == self)
      && (threadToInterrupt->flags & HYTHREAD_FLAG_WAITING))
    {
      notify_thread (threadToInterrupt, DONT_SET_NOTIFIED_FLAG);
    }
  threadToInterrupt->interrupter = NULL;
  ASSERT (threadToInterrupt->flags & HYTHREAD_FLAG_INTERRUPTED);
  THREAD_UNLOCK (self, threadToInterrupt);

  GLOBAL_UNLOCK (self);
  hythread_exit (monitor);

  ASSERT (0);
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_exit_using_threadId
/**
 * Exit a monitor.
 * 
 * This is a slightly faster version of hythread_monitor_exit because
 * the hythread_t for the current thread doesn't have to be looked up
 * 
 * @param[in] monitor a monitor to be exited
 * @param[in] threadId hythread_t for the current thread
 * @return 0 on success<br>
 * HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor
 * 
 * @see hythread_monitor_exit, hythread_monitor_enter, hythread_monitor_enter_using_threadId
 */
IDATA VMCALL
hythread_monitor_exit_using_threadId (hythread_monitor_t monitor,
                                      hythread_t threadId)
{
  ASSERT (threadId == MACRO_SELF ());
  ASSERT (monitor);
  ASSERT (FREE_TAG != monitor->count);

  if (monitor->owner != threadId)
    {
      ASSERT_DEBUG (0);
      return HYTHREAD_ILLEGAL_MONITOR_STATE;
    }

  return monitor_exit (threadId, monitor);

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_enter_using_threadId
/**
 * Enter a monitor.
 * 
 * This is a slightly faster version of hythread_monitor_enter because
 * the hythread_t for the current thread doesn't have to be looked up
 *
 * @param[in] monitor a monitor to be entered
 * @param[in] threadId hythread_t for the current thread
 * @return 0 on success<br>
 * 				 HYTHREAD_PRIORITY_INTERRUPTED if the thread was priority interrupted while blocked
 * 
 * @see hythread_monitor_enter, hythread_monitor_exit, hythread_monitor_exit_using_threadId
 *
 */
IDATA VMCALL
hythread_monitor_enter_using_threadId (hythread_monitor_t monitor,
                                       hythread_t threadId)
{
  ASSERT (threadId != 0);
  ASSERT (threadId == MACRO_SELF ());
  ASSERT (monitor);
  ASSERT (FREE_TAG != monitor->count);

  if (monitor->owner == threadId)
    {
      ASSERT (monitor->count >= 1);
      monitor->count++;

      if (IS_JLM_ENABLED (threadId))
        {
          ASSERT (monitor->tracing);
          monitor->tracing->recursive_count++;
          monitor->tracing->enter_count++;
        }                       /* if (IS_JLM_ENABLED(threadId)) */

      return 0;
    }
  return monitor_enter (threadId, monitor);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_try_enter_using_threadId
/** 
 * Attempt to enter a monitor without blocking.
 * 
 * If the thread must block before it enters the monitor this function
 * returns immediately with a negative value to indicate failure.<br>
 *  
 * This is a slightly faster version of hythread_monitor_try_enter because
 * the current thread's hythread_t doesn't have to be looked up.
 * 
 * @param[in] monitor a monitor
 * @param[in] threadId the current thread
 * @return  0 on success or negative value on failure
 *
 * @see hythread_monitor_try_enter
 *
 */
IDATA VMCALL
hythread_monitor_try_enter_using_threadId (hythread_monitor_t monitor,
                                           hythread_t threadId)
{

  ASSERT (threadId != 0);
  ASSERT (threadId == MACRO_SELF ());
  ASSERT (FREE_TAG != monitor->count);

  /* Are we already the owner? */
  if (monitor->owner == threadId)
    {
      ASSERT (monitor->count >= 1);
      monitor->count++;

      if (IS_JLM_ENABLED (threadId))
        {
          monitor->tracing->recursive_count++;
          monitor->tracing->enter_count++;
        }                       /* if (IS_JLM_ENABLED(threadId)) */

      return 0;
    }

  if (hythread_spinlock_acquire (threadId, monitor) == 0)

    {
      ASSERT (NULL == monitor->owner);
      ASSERT (0 == monitor->count);

      monitor->owner = threadId;
      monitor->count = 1;

      if (IS_JLM_ENABLED (threadId))
        {
          monitor->tracing->enter_count++;

        }                       /* if (IS_JLM_ENABLED(threadId)) */

      return 0;
    }

  return -1;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_probe

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION destroy_thread
/*
 * Destroy the resources associated with the thread.
 * 
 * If the thread is not already dead, the function fails.
 *
 * @param[in] thread thread to be destroyed
 * @param[in] globalAlreadyLocked indicated whether the thread library global mutex is already locked 
 * @return 0 on success or negative value on failure.
 */
static IDATA
destroy_thread (hythread_t thread, int globalAlreadyLocked)
{

  hythread_t self = MACRO_SELF ();
  hythread_library_t lib = self->library;

  ASSERT (thread);
  ASSERT (lib);

  THREAD_LOCK (self, thread, CALLER_DESTROY);
  if ((thread->flags & HYTHREAD_FLAG_DEAD) == 0)
    {
      THREAD_UNLOCK (self, thread);
      return -1;
    }
  THREAD_UNLOCK (self, thread);

  COND_DESTROY (thread->condition);

  MUTEX_DESTROY (thread->mutex);

#if defined(WIN32)
  if (thread->flags & HYTHREAD_FLAG_ATTACHED)
    {
      CloseHandle (thread->handle);
    }
#endif

  free_thread (thread, globalAlreadyLocked);
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_jlm_thread_init

/*
 * Initialize and clear a thread's JLM tracing information. 
 * 
 * Tracing information for the thread is allocated if not already allocated
 * The library's thread tracing pool is initialized if not already initialized.
 * 
 * @param[in] thread thread to be initialized
 * @return none
 *
 */
void VMCALL
hythread_jlm_thread_init (hythread_t thread)
{
  hythread_library_t library = thread->library;

  ASSERT (thread);
  ASSERT (library);

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_jlm_thread_clear

/*
 * Clear (reset) a thread's JLM tracing structure.
 * 
 * Assumes the thread's tracing structure has already been allocated.
 *
 * @param[in] thread thread to be initialized (non-NULL)
 * @return none
 *
 */
void VMCALL
hythread_jlm_thread_clear (hythread_t thread)
{
  ASSERT (thread);

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_jlm_monitor_init

/*
 * Initialize and clear a monitor's JLM tracing information. 
 * 
 * Tracing information for the monitor is allocated if not already allocated
 * The library's monitor tracing pool is initialized if not already initialized.
 * 
 * @param[in] monitor monitor to be initialized
 * @return none
 *
 */
void VMCALL
hythread_jlm_monitor_init (hythread_monitor_t monitor)
{
  hythread_t self = MACRO_SELF ();
  hythread_library_t library;
  ASSERT (self);
  ASSERT (monitor);
  library = self->library;
  ASSERT (library);

  if (library->monitor_tracing_pool == NULL)
    {
      library->monitor_tracing_pool =
        pool_new (sizeof (HyThreadMonitorTracing), 0, 0, 0, thread_malloc,
                  thread_free, NULL);
    }

  if (monitor->tracing == NULL)
    {
      /* cannot have been set, so set it now */
      monitor->tracing = pool_newElement (library->monitor_tracing_pool);
    }

  hythread_jlm_monitor_clear (monitor);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_jlm_monitor_clear

/*
 * Clear (reset) a monitor's JLM tracing structure.
 * 
 * Assumes the monitor's tracing structure has already been allocated.
 *
 * @param[in] monitor a monitor to be initialized
 * @return none
 */
void VMCALL
hythread_jlm_monitor_clear (hythread_monitor_t monitor)
{
  ASSERT (monitor);
  ASSERT (monitor->tracing);
  memset (monitor->tracing, 0, sizeof (*monitor->tracing));
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION init_monitor
/*
 * Re-initialize the 'simple' fields of a monitor
 * that has been initialized previously, but is now
 * being re-used. 
 *
 * @param[in] monitor monitor to be initialized
 * @return 0 on success or negative value on failure.
 * @see hythread_monitor_init_with_name
 * 
 */
static UDATA
init_monitor (hythread_monitor_t monitor, UDATA flags)
{
  ASSERT (monitor);
  monitor->count = 0;
  monitor->owner = NULL;
  monitor->waiting = NULL;
  monitor->flags = flags;
  monitor->userData = 0;
  monitor->name = 0;
  monitor->pinCount = 0;

  monitor->proDeflationCount = 0;
  monitor->antiDeflationCount = 0;

  monitor->blocking = NULL;
  monitor->spinlockState = HYTHREAD_MONITOR_SPINLOCK_UNOWNED;
  monitor->lockingWord = 0;
  /* these numbers are taken from the GC spinlock. They probably need to be tuned more (dynamically?) */
  /* note that every spinCount must be > 0! */

  monitor->spinCount1 = 256;
  monitor->spinCount2 = 32;
  monitor->spinCount3 = 45;

  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION getCurrentCycles
/*
 * Return the cycle count on the current processor. 
 * 
 * Units will be platform dependent. 
 * @todo This will be implmented in builder
 */
static hytime_t
getCurrentCycles (void)
{
  return 0;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_lib_get_flags

/** 
 * Get threading library global flags.
 * 
 * Returns the flags for the threading library associated with the current thread.
 * 
 * @note: assumes caller has global lock
 * 
 * @see hythread_lib_clear_flags, hythread_lib_set_flags, hythread_lib_lock
 * @return current flags value
 */
UDATA VMCALL
hythread_lib_get_flags ()
{
  hythread_t self;
  self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (self->library);

  return self->library->flags;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_lib_set_flags

/**
 * Set threading library global flags.
 * 
 * Sets the flags for the threading library associated with the current thread.
 *
 * @param[in] flags flags to be set (bit vector: 1 means set the flag, 0 means ignore)
 * @return old flags values
 * @see hythread_lib_clear_flags, hythread_lib_get_flags
 *
 */
UDATA VMCALL
hythread_lib_set_flags (UDATA flags)
{
  hythread_t self;
  UDATA oldFlags;
  self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (self->library);

  GLOBAL_LOCK (self, CALLER_LIB_SET_FLAGS);
  oldFlags = self->library->flags;
  self->library->flags |= flags;
  GLOBAL_UNLOCK (self);

  return oldFlags;

}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_lib_clear_flags

/** 
 * Clear specified threading library global flags.
 *
 * @see hythread_lib_set_flags, hythread_lib_get_flags
 * @param[in] flags flags to be cleared (bit vector: 1 means clear the flag, 0 means ignore)
 * @return old flags values
 */
UDATA VMCALL
hythread_lib_clear_flags (UDATA flags)
{
  hythread_t self;
  UDATA oldFlags;
  self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (self->library);

  GLOBAL_LOCK (self, CALLER_LIB_CLEAR_FLAGS);
  oldFlags = self->library->flags;
  self->library->flags &= ~flags;
  GLOBAL_UNLOCK (self);

  return oldFlags;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_monitor_init_with_name
/**
 * Acquire and initialize a new monitor from the threading library.
 *
 * @param[out] handle pointer to a hythread_monitor_t to be set to point to the new monitor
 * @param[in] flags initial flag values for the monitor
 * @param[in] name pointer to a C string with a description of how the monitor will be used (may be NULL)<br>
 * If non-NULL, the C string must be valid for the entire life of the monitor
 * 
 * @return  0 on success or negative value on failure
 * 
 * @see hythread_monitor_destroy
 * 
 */
IDATA VMCALL
hythread_monitor_init_with_name (hythread_monitor_t * handle, UDATA flags,
                                 const char *name)
{
  ASSERT (handle);

  if (hythread_monitor_init (handle, flags) == 0)
    {
      (*handle)->name = name;
      return 0;
    }

  return -1;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_jlm_gc_lock_init

/*
 * Initialize pools and tracing structures for JLM tracing.
 * 
 * Can be called multiple times.
 * 
 * @return none
 */
void VMCALL
hythread_jlm_gc_lock_init ()
{
  hythread_t self = MACRO_SELF ();
  hythread_library_t library;
  ASSERT (self);
  library = self->library;
  ASSERT (library);

  /* If no monitor_tracing pool yet, create it */
  if (library->monitor_tracing_pool == NULL)
    {
      library->monitor_tracing_pool =
        pool_new (sizeof (HyThreadMonitorTracing), 0, 0, 0, thread_malloc,
                  thread_free, NULL);
    }

  /* If no GC lock tracing pool yet, create it */
  if (library->gc_lock_tracing == NULL)
    {
      library->gc_lock_tracing =
        pool_newElement (library->monitor_tracing_pool);
    }

  /* Init the tracing structure */
  memset (library->gc_lock_tracing, 0, sizeof (*library->gc_lock_tracing));
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_jlm_get_gc_lock_tracing

/*
 * Return tracing info.
 *
 * @return pointer to GC lock tracing structure. 0 of not yet initialized
 */
HyThreadMonitorTracing *VMCALL
hythread_jlm_get_gc_lock_tracing ()
{
  hythread_t self = MACRO_SELF ();
  ASSERT (self);
  ASSERT (self->library);
  return self->library->gc_lock_tracing;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_lib_lock
/**
 * Acquire the threading library's global lock.
 * 
 * @note This must not be called recursively by a thread that already owns the global lock.
 * @param[in] self hythread_t for the current thread
 * @return none
 * 
 * @see hythread_lib_unlock
 */
void VMCALL
hythread_lib_lock (hythread_t self)
{
  ASSERT (self);
  GLOBAL_LOCK (self, CALLER_GLOBAL_LOCK);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_lib_unlock
/**
 * Release the threading library's global lock.
 * 
 * @note This must be called only by the thread that currently has the global lock locked. 
 * @param[in] self hythread_t for the current thread
 * @return none
 * 
 * @see hythread_lib_lock
 */
void VMCALL
hythread_lib_unlock (hythread_t self)
{
  ASSERT (self);
  GLOBAL_UNLOCK (self);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_park
/**
 * 'Park' the current thread. 
 * 
 * Stop the current thread from executing until it is unparked, interrupted, or the specified timeout elapses.
 * 
 * Unlike wait or sleep, the interrupted flag is NOT cleared by this API.
 *
 * @param[in] millis
 * @param[in] nanos 
 * 
 * @return 0 if the thread is unparked
 * HYTHREAD_INTERRUPTED if the thread was interrupted while parked<br>
 * HYTHREAD_PRIORITY_INTERRUPTED if the thread was priority interrupted while parked<br>
 * HYTHREAD_TIMED_OUT if the timeout expired<br>
 *
 * @see hythread_unpark
 */
IDATA VMCALL
hythread_park (I_64 millis, IDATA nanos)
{
  IDATA rc = 0;
  hythread_t self = MACRO_SELF ();
  ASSERT (self);

  THREAD_LOCK (self, self, CALLER_PARK);

  if (self->flags & HYTHREAD_FLAG_UNPARKED)
    {
      self->flags &= ~HYTHREAD_FLAG_UNPARKED;
    }
  else if (self->flags & HYTHREAD_FLAG_INTERRUPTED)
    {
      rc = HYTHREAD_INTERRUPTED;
    }
  else if (self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED)
    {
      rc = HYTHREAD_PRIORITY_INTERRUPTED;
    }
  else
    {
      self->flags |= HYTHREAD_FLAG_PARKED | HYTHREAD_FLAG_INTERRUPTABLE;

      if (millis || nanos)
        {
          IDATA boundedMillis = BOUNDED_I64_TO_IDATA (millis);

          self->flags |= HYTHREAD_FLAG_TIMER_SET;

          COND_WAIT_IF_TIMEDOUT (self->condition, self->mutex, boundedMillis,
                                 nanos)
          {
            rc = HYTHREAD_TIMED_OUT;
            break;
          }
          else
        if (self->flags & HYTHREAD_FLAG_UNPARKED)
          {
            self->flags &= ~HYTHREAD_FLAG_UNPARKED;
            break;
          }
        else if (self->flags & HYTHREAD_FLAG_INTERRUPTED)
          {
            rc = HYTHREAD_INTERRUPTED;
            break;
          }
        else if (self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED)
          {
            rc = HYTHREAD_PRIORITY_INTERRUPTED;
            break;
          }
          COND_WAIT_TIMED_LOOP ();
        }
      else
        {
          COND_WAIT (self->condition, self->mutex);
          if (self->flags & HYTHREAD_FLAG_UNPARKED)
            {
              self->flags &= ~HYTHREAD_FLAG_UNPARKED;
              break;
            }
          else if (self->flags & HYTHREAD_FLAG_INTERRUPTED)
            {
              rc = HYTHREAD_INTERRUPTED;
              break;
            }
          else if (self->flags & HYTHREAD_FLAG_PRIORITY_INTERRUPTED)
            {
              rc = HYTHREAD_PRIORITY_INTERRUPTED;
              break;
            }
          COND_WAIT_LOOP ();
        }
    }

  self->flags &=
    ~(HYTHREAD_FLAG_PARKED | HYTHREAD_FLAG_INTERRUPTABLE |
      HYTHREAD_FLAG_TIMER_SET);

  THREAD_UNLOCK (self, self);

  return rc;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_unpark
/**
 * 'Unpark' the specified thread. 
 * 
 * If the thread is parked, it will return from park.
 * If the thread is not parked, its 'UNPARKED' flag will be set, and it will return immediately the next time it is parked.
 *
 * Note that unparks are not counted. Unparking a thread once is the same as unparking it n times.
 * 
 * @see hythread_park
 */
void VMCALL
hythread_unpark (hythread_t thread)
{
  hythread_t self = MACRO_SELF ();

  ASSERT (self);
  ASSERT (thread);

  /* TODO: is GLOBAL_LOCK/GLOBAl_UNLOCK required here? */

  GLOBAL_LOCK (self, CALLER_UNPARK_THREAD);
  THREAD_LOCK (self, thread, CALLER_UNPARK_THREAD);

  thread->flags |= HYTHREAD_FLAG_UNPARKED;

  if (thread->flags & HYTHREAD_FLAG_PARKED)
    {
      COND_NOTIFY_ALL (thread->condition);
    }

  THREAD_UNLOCK (self, thread);
  GLOBAL_UNLOCK (self);
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_tls_alloc_with_finalizer
/**
 * Allocate a thread local storage (TLS) key.
 * 
 * Create and return a new, unique key for thread local storage.  
 * 
 * @note The hande returned will be >=0, so it is safe to test the handle against 0 to see if it's been
 * allocated yet.
 * 
 * @param[out] handle pointer to a key to be initialized with a key value
 * @param[in] a finalizer function which will be invoked when a thread is detached or terminates if the thread's TLS entry for this key is non-NULL
 * @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated)
 * 
 * @see hythread_tls_free, hythread_tls_set
 */
IDATA VMCALL
hythread_tls_alloc_with_finalizer (hythread_tls_key_t * handle,
                                   hythread_tls_finalizer_t finalizer)
{
  IDATA index;
  hythread_library_t lib = GLOBAL_DATA (default_library);
  ASSERT (lib);

  *handle = 0;

  MUTEX_ENTER (lib->tls_mutex);

  for (index = 0; index < HYTHREAD_MAX_TLS_KEYS; index++)
    {
      if (lib->tls_finalizers[index] == NULL)
        {
          *handle = index + 1;
          lib->tls_finalizers[index] = finalizer;
          break;
        }
    }

  MUTEX_EXIT (lib->tls_mutex);

  return index < HYTHREAD_MAX_TLS_KEYS ? 0 : -1;
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION tls_finalize
/*
 * Run finalizers on any non-NULL TLS values for the current thread
 *
 * @param[in] thread current thread
 * @return none
 */
static void
tls_finalize (hythread_t thread)
{
  IDATA index;
  hythread_library_t lib = thread->library;

  for (index = 0; index < HYTHREAD_MAX_TLS_KEYS; index++)
    {
      if (thread->tls[index] != NULL)
        {
          void *value;
          hythread_tls_finalizer_t finalizer;

          /* read the value and finalizer together under mutex to be sure that they belong together */
          MUTEX_ENTER (lib->tls_mutex);
          value = thread->tls[index];
          finalizer = lib->tls_finalizers[index];
          MUTEX_EXIT (lib->tls_mutex);

          if (value)
            {
              finalizer (value);
            }
        }
    }
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION tls_null_finalizer
static void HYTHREAD_PROC
tls_null_finalizer (void *entry)
{
  /* do nothing */
}

#undef CDEV_CURRENT_FUNCTION

#define CDEV_CURRENT_FUNCTION hythread_current_stack_free
/**
 * Return the remaining useable bytes of the current thread's OS stack.
 *
 * @return OS stack free size in bytes, 0 if it cannot be determined.
 */
UDATA VMCALL
hythread_current_stack_free(void)
{
#if defined(WIN32)
  MEMORY_BASIC_INFORMATION memInfo;
  SYSTEM_INFO sysInfo;
  UDATA stackFree;
  UDATA guardPageSize;

  GetSystemInfo(&sysInfo);
  VirtualQuery(&memInfo, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
  stackFree = ((UDATA) &memInfo - (UDATA) memInfo.AllocationBase) & ~sizeof(UDATA);

  /* By observation, Win32 reserves 3 pages at the low end of the stack for guard pages, so omit them */

  guardPageSize = 3 * (UDATA) sysInfo.dwPageSize;
  return (stackFree < guardPageSize) ? 0 : stackFree - guardPageSize;
#else
  return 0;
#endif
}
