#ifndef __JV_POSIX_THREADS__
#define __JV_POSIX_THREADS__
#include <pthread.h>
#include <sched.h>
typedef struct _Jv_Thread_t
{
int flags;
pthread_t thread;
java::lang::Thread *thread_obj;
pthread_cond_t wait_cond;
pthread_mutex_t wait_mutex;
_Jv_Thread_t *next;
} _Jv_Thread_t;
typedef void _Jv_ThreadStartFunc (java::lang::Thread *);
typedef struct
{
_Jv_Thread_t *first;
} _Jv_ConditionVariable_t;
typedef struct
{
pthread_mutex_t mutex;
pthread_t owner;
int count;
} _Jv_Mutex_t;
inline int
_Jv_MutexCheckMonitor (_Jv_Mutex_t *mu)
{
return (mu->owner != pthread_self());
}
int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
jlong millis, jint nanos);
int _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu);
int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu);
inline void
_Jv_CondInit (_Jv_ConditionVariable_t *cv)
{
cv->first = 0;
}
#ifdef LOCK_DEBUG
# include <stdio.h>
#endif
inline void
_Jv_MutexInit (_Jv_Mutex_t *mu)
{
# ifdef LOCK_DEBUG
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init (&mu->mutex, &attr);
# else
pthread_mutex_init (&mu->mutex, 0);
# endif
mu->count = 0;
mu->owner = 0;
}
inline int
_Jv_MutexLock (_Jv_Mutex_t *mu)
{
pthread_t self = pthread_self ();
if (mu->owner == self)
{
mu->count++;
}
else
{
# ifdef LOCK_DEBUG
int result = pthread_mutex_lock (&mu->mutex);
if (0 != result)
{
fprintf(stderr, "Pthread_mutex_lock returned %d\n", result);
for (;;) {}
}
# else
pthread_mutex_lock (&mu->mutex);
# endif
mu->count = 1;
mu->owner = self;
}
return 0;
}
inline int
_Jv_MutexUnlock (_Jv_Mutex_t *mu)
{
if (_Jv_MutexCheckMonitor (mu))
{
# ifdef LOCK_DEBUG
fprintf(stderr, "_Jv_MutexUnlock: Not owner\n");
for (;;) {}
# endif
return 1;
}
mu->count--;
if (mu->count == 0)
{
mu->owner = 0;
# ifdef LOCK_DEBUG
int result = pthread_mutex_unlock (&mu->mutex);
if (0 != result)
{
fprintf(stderr, "Pthread_mutex_unlock returned %d\n", result);
for (;;) {}
}
# else
pthread_mutex_unlock (&mu->mutex);
# endif
}
return 0;
}
#ifndef LINUX_THREADS
#define _Jv_HaveMutexDestroy
inline void
_Jv_MutexDestroy (_Jv_Mutex_t *mu)
{
pthread_mutex_destroy (&mu->mutex);
}
#endif
void _Jv_InitThreads (void);
_Jv_Thread_t *_Jv_ThreadInitData (java::lang::Thread *thread);
void _Jv_ThreadDestroyData (_Jv_Thread_t *data);
inline java::lang::Thread *
_Jv_ThreadCurrent (void)
{
extern pthread_key_t _Jv_ThreadKey;
return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
}
#ifdef JV_HASH_SYNCHRONIZATION
#ifdef __ia64__
typedef size_t _Jv_ThreadId_t;
register size_t _Jv_self __asm__("r13");
inline _Jv_ThreadId_t
_Jv_ThreadSelf (void)
{
return _Jv_self;
}
#define JV_SELF_DEFINED
#endif
#ifdef __alpha__
typedef void *_Jv_ThreadId_t;
inline _Jv_ThreadId_t
_Jv_ThreadSelf (void)
{
return __builtin_thread_pointer ();
}
#define JV_SELF_DEFINED
#endif
#if defined(SLOW_PTHREAD_SELF)
#include "sysdep/locks.h"
typedef pthread_t _Jv_ThreadId_t;
# define LOG_THREAD_SPACING 12
# define SELF_CACHE_SIZE 1024
# define SC_INDEX(sp) (((unsigned long)(sp) >> 19) & (SELF_CACHE_SIZE-1))
# define SC_CLEAR_MIN (-16) // When starting a new thread, we clear
# define SC_CLEAR_MAX 0 // all self cache entries between
# define BAD_HIGH_SP_VALUE ((size_t)(-1))
extern volatile
struct self_cache_entry {
size_t high_sp_bits; pthread_t self; } _Jv_self_cache[];
void _Jv_Self_Cache_Init();
_Jv_ThreadId_t
_Jv_ThreadSelf_out_of_line(volatile self_cache_entry *sce,
size_t high_sp_bits);
inline _Jv_ThreadId_t
_Jv_ThreadSelf (void)
{
int dummy;
size_t sp = (size_t)(&dummy);
unsigned h = SC_INDEX(sp);
volatile self_cache_entry *sce = _Jv_self_cache + h;
pthread_t candidate_self = sce -> self; read_barrier();
if (sce -> high_sp_bits == sp >> LOG_THREAD_SPACING)
{
return candidate_self;
}
else
return _Jv_ThreadSelf_out_of_line(sce, sp >> LOG_THREAD_SPACING);
}
#define JV_SELF_DEFINED
#endif
#ifndef JV_SELF_DEFINED
typedef pthread_t _Jv_ThreadId_t;
inline _Jv_ThreadId_t
_Jv_ThreadSelf (void)
{
return pthread_self();
}
#endif
#endif
inline _Jv_Thread_t *
_Jv_ThreadCurrentData (void)
{
extern pthread_key_t _Jv_ThreadDataKey;
return (_Jv_Thread_t *) pthread_getspecific (_Jv_ThreadDataKey);
}
inline void
_Jv_ThreadYield (void)
{
#ifdef HAVE_SCHED_YIELD
sched_yield ();
#endif
}
void _Jv_ThreadRegister (_Jv_Thread_t *data);
void _Jv_ThreadUnRegister ();
void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio);
void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
_Jv_ThreadStartFunc *meth);
void _Jv_ThreadWait (void);
void _Jv_ThreadInterrupt (_Jv_Thread_t *data);
#endif