25 #define __STDC_LIMIT_MACROS
32 #if !defined(__DARWIN__)
33 #include <semaphore.h>
40 #include <sys/types.h>
62 #if defined(ENABLE_GC_CACAO)
66 #if defined(__DARWIN__)
75 # include <semaphore.h>
82 using namespace cacao;
84 #if defined(__DARWIN__)
95 static int sem_init(sem_t *sem,
int pshared,
int value)
100 sem->mutex =
new Mutex();
107 static int sem_post(sem_t *sem)
112 sem->mutex->unlock();
117 static int sem_wait(sem_t *sem)
121 while (sem->value == 0) {
122 sem->cond->wait(sem->mutex);
126 sem->mutex->unlock();
131 static int sem_destroy(sem_t *sem)
170 #if defined(HAVE___THREAD)
173 pthread_key_t thread_current_key;
179 #if defined(ENABLE_GC_CACAO)
181 static Mutex* mutex_gc;
187 #if defined(ENABLE_GC_CACAO)
189 static sem_t suspend_ack;
211 r = sem_init(sem, shared, value);
214 }
while (errno == EINTR);
216 vm_abort(
"sem_init failed: %s", strerror(errno));
242 }
while (errno == EINTR);
244 vm_abort(
"sem_wait failed: %s", strerror(errno));
269 vm_abort(
"sem_post failed: %s", strerror(errno));
281 #if defined(ENABLE_GC_CACAO)
282 void threads_stopworld(
void)
284 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
297 #if defined(__DARWIN__)
300 #elif defined(__CYGWIN__)
311 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
334 for (i = 0; i < count; i++)
351 #if defined(ENABLE_GC_CACAO)
352 void threads_startworld(
void)
354 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
361 #if defined(__DARWIN__)
364 #elif defined(__IRIX__)
365 threads_cast_irixresume();
366 #elif defined(__CYGWIN__)
377 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
400 for (i = 0; i < count; i++)
438 #if defined(__DARWIN__)
439 t->
impl.mach_thread = 0;
454 #if defined(ENABLE_INTRP)
455 t->_global_sp = NULL;
458 #if defined(ENABLE_GC_CACAO)
459 t->gc_critical =
false;
509 #if defined(ENABLE_GC_CACAO)
512 mutex_gc =
new Mutex();
516 #if !defined(HAVE___THREAD)
517 int result = pthread_key_create(&thread_current_key, NULL);
519 os::abort_errnum(result,
"threads_impl_preinit: pthread_key_create failed");
530 #if defined(ENABLE_GC_CACAO)
531 void threads_mutex_gc_lock(
void)
544 #if defined(ENABLE_GC_CACAO)
545 void threads_mutex_gc_unlock(
void)
566 result = pthread_attr_init(&attr);
571 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
574 os::abort_errnum(result,
"threads_impl_init: pthread_attr_setdetachstate failed");
606 #if defined(ENABLE_GC_BOEHM)
607 # if !defined(__DARWIN__)
608 struct GC_stack_base sb;
613 #if defined(ENABLE_INTRP)
614 u1 *intrp_thread_stack;
617 #if defined(ENABLE_INTRP)
625 intrp_thread_stack = NULL;
634 psem = startup->
psem;
642 #if defined(__DARWIN__)
643 t->
impl.mach_thread = mach_thread_self();
651 #if defined(ENABLE_GC_BOEHM)
652 # if defined(__DARWIN__)
658 result = GC_get_stack_base(&sb);
661 vm_abort(
"threads_startup_thread: GC_get_stack_base failed: result=%d", result);
663 GC_register_my_thread(&sb);
681 #if defined(ENABLE_INTRP)
695 if (
function == NULL) {
701 vm_abort(
"threads_startup_thread: run() method not found in class");
761 result = pthread_attr_init(&attr);
764 os::abort_errnum(result,
"threads_impl_thread_start: pthread_attr_init failed");
766 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
769 os::abort_errnum(result,
"threads_impl_thread_start: pthread_attr_setdetachstate failed");
776 os::abort_errnum(result,
"threads_impl_thread_start: pthread_attr_setstacksize failed");
783 os::abort_errnum(result,
"threads_impl_thread_start: pthread_create failed");
787 result = pthread_attr_destroy(&attr);
790 os::abort_errnum(result,
"threads_impl_thread_start: pthread_attr_destroy failed");
803 sem_destroy(&sem_first);
825 struct sched_param schedp;
828 pthread_getschedparam(tid, &policy, &schedp);
829 schedp.sched_priority = priority;
830 pthread_setschedparam(tid, policy, &schedp);
858 #if defined(ENABLE_JAVASE)
877 if (handler != NULL) {
887 utf8::uncaughtException,
888 utf8::java_lang_Thread_java_lang_Throwable__V,
984 #if defined(ENABLE_GC_CACAO)
994 #if defined(ENABLE_GC_CACAO)
1046 if (pthread_kill(thread->
impl.
tid, SIGUSR1) != 0)
1152 const struct timespec *tv2)
1154 return (tv1->tv_sec < tv2->tv_sec)
1156 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1174 struct timeval tvnow;
1175 struct timespec tsnow;
1179 if (gettimeofday(&tvnow, NULL) != 0)
1180 vm_abort(
"gettimeofday failed: %s\n", strerror(errno));
1184 tsnow.tv_sec = tvnow.tv_sec;
1185 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1213 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1265 struct timespec wakeupTime;
1294 if (!millis && !nanos)
1297 gettimeofday(&tv, NULL);
1298 s8 secs = tv.tv_sec + millis / 1000;
1299 if (secs > INT32_MAX)
1303 long nsec = tv.tv_usec * 1000 + (
s4) millis * 1000000 + nanos;
1304 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1305 if (tm->tv_sec < tv.tv_sec)
1307 tm->tv_nsec = nsec % 1000000000;
1358 struct timespec wakeupTime;
1385 if (millis == 0 && nanos == 0) {
1417 struct timespec wakeupTime;
1422 wakeupTime.tv_nsec = 0;
1423 wakeupTime.tv_sec = nanos / 1000;
1468 return reinterpret_cast<intptr_t
>(t->
impl.
tid);
1470 return static_cast<intptr_t
>(t->
impl.
tid);
void exceptions_throw_illegalargumentexception(void)
int32_t get_priority() const
#define GCMNEW(type, num)
methodinfo * class_resolveclassmethod(classinfo *c, Utf8String name, Utf8String desc, classinfo *referer, bool throwexception)
virtual java_handle_t * get_handle() const
void threads_thread_interrupt(threadobject *t)
bool threads_suspend_thread(threadobject *thread, SuspendReason reason)
Suspend the passed thread.
#define MSET(ptr, byte, type, num)
void thread_start(threadobject *t)
void signal()
Restarts one of the threads that are waiting on this condition variable.
static void abort_errno(const char *text,...)
Equal to abort_errnum, but uses errno to get the error number.
void threads_unpark(threadobject *t)
Unpark the specified thread.
intptr_t threads_get_tid(threadobject *t)
void thread_set_state_runnable(threadobject *t)
void threads_sem_post(sem_t *sem)
void exceptions_throw_interruptedexception(void)
void thread_set_state_timed_parked(threadobject *t)
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
bool lock_monitor_exit(java_handle_t *o)
Dummy implementation of a mutex.
java_handle_t * vm_call_method(methodinfo *m, java_handle_t *o,...)
static java_handle_t * get_thread_exception_handler(const java_lang_Thread &jlt)
void threads_impl_thread_clear(threadobject *t)
void threads_set_thread_priority(threadobject *t, int priority)
void threads_sem_init(sem_t *sem, bool shared, int value)
static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
#define DEBUGTHREADS(message, thread)
static bool threads_current_time_is_earlier_than(const struct timespec *tv)
static void abort_errnum(int errnum, const char *text,...)
Prints an error message, appends ":" plus the strerror-message of errnum and aborts the VM...
void vm_abort(const char *text,...)
void(* functionptr)(void)
cacao::detail::threadobject impl
java_handle_t * get_group() const
#define LLNI_class_get(obj, variable)
void lock_notify_all_object(java_handle_t *o)
static bool threads_timespec_earlier(const struct timespec *tv1, const struct timespec *tv2)
static ThreadList * get()
Provides access to singleton.
java_object_t * _exceptionptr
void wait_cond(Condition *cond)
static void * threads_startup_thread(void *arg)
void thread_end(threadobject *t)
static Mutex * stopworldlock
void thread_set_state_parked(threadobject *t)
void threads_impl_thread_start(threadobject *thread, functionptr f)
localref_table * _localref_table
void threads_wait_with_timeout_relative(threadobject *thread, s8 millis, s4 nanos)
SuspendReason suspend_reason
#define exceptions_get_and_clear_exception
static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
bool thread_is_interrupted(threadobject *t)
void thread_free(threadobject *t)
Dummy condition variable.
threadobject * thread_current
void threads_join_all_threads()
void broadcast()
Restarts all the threads that are waiting on the condition variable.
void threads_suspend_ack()
void thread_set_state_terminated(threadobject *t)
void set_group(java_handle_t *value)
Helper class used to implicitly acquire and release a mutex within a method scope.
bool thread_detach_current_thread(void)
Detaches the current thread from the VM.
static methodinfo * get_threadgroup_remove_method(classinfo *c)
java_handle_t * flc_object
void threads_impl_preinit()
void thread_set_interrupted(threadobject *t, bool interrupted)
static bool thread_is_attached(threadobject *t)
static java_handle_t * get_vmthread_handle(const java_lang_Thread &jlt)
static threadobject * thread_get_current()
Return the threadobject for the current thread.
void thread_set_state_timed_waiting(threadobject *t)
void threads_park(bool absolute, int64_t nanos)
Park the current thread for the specified amount of time or until a specified deadline.
void threads_impl_clear_heap_pointers(threadobject *t)
static Condition * cond_join
java_handle_t * exceptions_get_exception(void)
#define Signal_INTERRUPT_SYSTEM_CALL
void unlock()
Unlocks the given mutex object and checks for errors.
GNU Classpath java/lang/Thread.
void thread_set_state_waiting(threadobject *t)
stackframeinfo_t * _stackframeinfo
static classinfo * get_thread_class_from_object(java_handle_t *object)
bool lock_monitor_enter(java_handle_t *o)
void threads_sleep(int64_t millis, int32_t nanos)
void threads_sem_wait(sem_t *sem)
void wait(Mutex *mutex)
Waits for the condition variable.
void lock()
Locks the given mutex object and checks for errors.
void threads_impl_thread_reuse(threadobject *t)
void timedwait(Mutex *mutex, const timespec *abstime)
static void thread_set_current(threadobject *t)
Set the threadobject for the current thread.
static void threads_suspend_self()
Internal helper function which suspends the current thread.
bool threads_resume_thread(threadobject *thread, SuspendReason reason)
Resumes execution of the passed thread.