- correct UnguardOnExecutionViolation which helped find a W^X
kernel bug on i386 - fix undefined symbols in libhpi.so noted by stu@
This commit is contained in:
parent
dae9c229a7
commit
ec59431b2a
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.44 2013/03/11 10:50:09 espie Exp $
|
||||
# $OpenBSD: Makefile,v 1.45 2013/03/19 19:26:45 kurt Exp $
|
||||
|
||||
SHARED_ONLY= Yes
|
||||
ONLY_FOR_ARCHS= amd64 i386
|
||||
@ -10,9 +10,9 @@ UPDATE= 32
|
||||
BUILD= b27
|
||||
PKGNAME= jdk-${VERSION}
|
||||
PKGNAME-main= jdk-${VERSION}
|
||||
REVISION-main= 1
|
||||
REVISION-main= 2
|
||||
PKGNAME-jre= jre-${VERSION}
|
||||
REVISION-jre= 1
|
||||
REVISION-jre= 2
|
||||
|
||||
# see jaxp/jaxp.properties & jaxws/jaxws.properties
|
||||
# in ${WRKDIR} for names and download locations of extra distfiles
|
||||
|
@ -0,0 +1,41 @@
|
||||
$OpenBSD: patch-hotspot_src_os_cpu_bsd_x86_vm_os_bsd_x86_cpp,v 1.1 2013/03/19 19:26:45 kurt Exp $
|
||||
--- hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp.orig Mon Feb 4 13:08:55 2013
|
||||
+++ hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Mon Feb 4 22:00:10 2013
|
||||
@@ -226,7 +226,6 @@
|
||||
# define context_esi sc_esi
|
||||
# define context_edi sc_edi
|
||||
# define context_eflags sc_eflags
|
||||
-# define context_trapno sc_trapno
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -394,6 +393,9 @@ frame os::current_frame() {
|
||||
|
||||
// From IA32 System Programming Guide
|
||||
enum {
|
||||
+#ifdef __OpenBSD__
|
||||
+ trap_protection_fault = 0x4,
|
||||
+#endif
|
||||
trap_page_fault = 0xE
|
||||
};
|
||||
|
||||
@@ -649,7 +651,11 @@ JVM_handle_bsd_signal(int sig,
|
||||
// Furthermore, a false-positive should be harmless.
|
||||
if (UnguardOnExecutionViolation > 0 &&
|
||||
(sig == SIGSEGV || sig == SIGBUS) &&
|
||||
+#ifdef __OpenBSD__
|
||||
+ uc->context_trapno == trap_protection_fault) {
|
||||
+#else
|
||||
uc->context_trapno == trap_page_fault) {
|
||||
+#endif
|
||||
int page_size = os::vm_page_size();
|
||||
address addr = (address) info->si_addr;
|
||||
address pc = os::Bsd::ucontext_get_pc(uc);
|
||||
@@ -1062,6 +1068,7 @@ void os::print_context(outputStream *st, void *context
|
||||
st->cr();
|
||||
st->print( "EIP=" INTPTR_FORMAT, uc->context_eip);
|
||||
st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_eflags);
|
||||
+ st->print(", TRAPNO=" INTPTR_FORMAT, uc->context_trapno);
|
||||
#endif // AMD64
|
||||
st->cr();
|
||||
st->cr();
|
@ -0,0 +1,12 @@
|
||||
$OpenBSD: patch-jdk_src_solaris_hpi_native_threads_include_threads_md_h,v 1.1 2013/03/19 19:26:45 kurt Exp $
|
||||
--- jdk/src/solaris/hpi/native_threads/include/threads_md.h.orig Sun Mar 10 12:10:32 2013
|
||||
+++ jdk/src/solaris/hpi/native_threads/include/threads_md.h Sun Mar 10 12:11:55 2013
|
||||
@@ -174,7 +174,7 @@ struct sys_thread {
|
||||
struct sys_thread *nextBlocked;
|
||||
#ifdef USE_PTHREADS
|
||||
int suspend_count;
|
||||
-#ifdef __linux__
|
||||
+#if defined(__linux__) || defined(__OpenBSD__)
|
||||
sem_t sem_suspended;
|
||||
sem_t sem_ready_to_suspend;
|
||||
sem_t sem_selfsuspend;
|
@ -0,0 +1,683 @@
|
||||
$OpenBSD: patch-jdk_src_solaris_hpi_native_threads_src_threads_bsd_c,v 1.1 2013/03/19 19:26:45 kurt Exp $
|
||||
--- jdk/src/solaris/hpi/native_threads/src/threads_bsd.c.orig Sun Mar 10 13:02:26 2013
|
||||
+++ jdk/src/solaris/hpi/native_threads/src/threads_bsd.c Sun Mar 10 12:58:07 2013
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -23,381 +23,387 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
-#ifdef __APPLE__
|
||||
+/*
|
||||
+ * Implementation of notposix.h on Linux.
|
||||
+ */
|
||||
|
||||
-/* We need the mach API, which must be be included before any other system includes.
|
||||
- * Additionally, java and mach both define thread_state_t, so temporarily redefine it. */
|
||||
-#define thread_state_t mach_thread_state_t
|
||||
-#include <mach/mach.h>
|
||||
-#undef thread_state_t
|
||||
+#include <pthread.h>
|
||||
+#include <signal.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <time.h>
|
||||
|
||||
-#endif
|
||||
-
|
||||
#include "hpi_impl.h"
|
||||
#include "monitor_md.h"
|
||||
#include "threads_md.h"
|
||||
#include "np.h"
|
||||
|
||||
-#include <sys/types.h>
|
||||
-#include <sys/sysctl.h>
|
||||
+#undef LOG_THREADS
|
||||
|
||||
-#include <pthread.h>
|
||||
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
-#include <pthread_np.h>
|
||||
-#endif
|
||||
-#ifdef __NetBSD__
|
||||
-#include <errno.h>
|
||||
-#define pthread_attr_get_np(a, b) 0
|
||||
-#define pthread_suspend_all_np() 0
|
||||
-#define pthread_resume_all_np() 0
|
||||
-#endif
|
||||
+/* Global lock used when calling np_suspend and np_resume */
|
||||
+static pthread_mutex_t sr_lock;
|
||||
|
||||
-#include <time.h>
|
||||
-#include <string.h>
|
||||
-#include <signal.h>
|
||||
-#include <sys/signal.h>
|
||||
-#include <sys/resource.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <errno.h>
|
||||
+/* Semaphore used to acknowledge when the handler has received HANDLER_SIG */
|
||||
+static sem_t sr_sem;
|
||||
|
||||
-/*
|
||||
- * Suspend said thread. Used to implement java.lang.Thread.suspend(),
|
||||
- * which is deprecated.
|
||||
- */
|
||||
-int
|
||||
-np_suspend(sys_thread_t *tid)
|
||||
+/* The tid of the thread being suspended/resumed */
|
||||
+static sys_thread_t *sr_tid;
|
||||
+
|
||||
+int sr_sigsusp;
|
||||
+int sr_sigresu;
|
||||
+
|
||||
+static void prtsigset(char *s, sigset_t *set)
|
||||
{
|
||||
-#ifdef __APPLE__
|
||||
- if (thread_suspend(pthread_mach_thread_np(tid->sys_thread)) == KERN_SUCCESS)
|
||||
- return SYS_OK;
|
||||
- else
|
||||
- return SYS_ERR;
|
||||
-#else
|
||||
- return pthread_suspend_np(tid->sys_thread);
|
||||
-#endif
|
||||
+ int sig;
|
||||
+ dprintf(2, "%s:", s);
|
||||
+ for (sig = 1; sig < _NSIG; sig++) {
|
||||
+ if (sigismember(set, sig)) {
|
||||
+ dprintf(2, " %d", sig);
|
||||
+ }
|
||||
+ }
|
||||
+ dprintf(2, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
- * Resume a suspended thread. Used to implement java.lang.Thread.resume(),
|
||||
- * which is deprecated.
|
||||
+ * Handler function invoked when a thread's execution is suspended
|
||||
+ * We have to be careful that only async-safe functions are
|
||||
+ * called here. I'm not even sure if calling sysThreadSelf is safe so
|
||||
+ * we temporarily stash SP in a global variable instead.
|
||||
*/
|
||||
-int
|
||||
-np_continue(sys_thread_t *tid)
|
||||
-{
|
||||
-#ifdef __APPLE__
|
||||
- if (thread_resume(pthread_mach_thread_np(tid->sys_thread)) == KERN_SUCCESS)
|
||||
- return SYS_OK;
|
||||
- else
|
||||
- return SYS_ERR;
|
||||
+static void
|
||||
+#ifdef SA_SIGINFO
|
||||
+susp_handler(int sig, siginfo_t* info, void* arg)
|
||||
#else
|
||||
- return pthread_resume_np(tid->sys_thread);
|
||||
+susp_handler(int sig)
|
||||
#endif
|
||||
+{
|
||||
+ sys_thread_t *tid = sr_tid;
|
||||
+ sigset_t set;
|
||||
+ /* Save the current SP */
|
||||
+ tid->sp = &tid;
|
||||
+ sem_post(&sr_sem);
|
||||
+ sigfillset(&set);
|
||||
+ sigdelset(&set,(sr_sigresu));
|
||||
+ /* block until we receive resume signal. */
|
||||
+ sigsuspend(&set);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * If there is any initialization is required by the non-POSIX parts.
|
||||
- */
|
||||
-void np_initialize_thread(sys_thread_t *tid)
|
||||
+static void
|
||||
+#ifdef SA_SIGINFO
|
||||
+resu_handler(int sig, siginfo_t* info, void* arg)
|
||||
+#else
|
||||
+resu_handler(int sig)
|
||||
+#endif
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
-
|
||||
/*
|
||||
- * Internal helper function to get stack information about specified thread.
|
||||
+ * Initialize signal handlers for suspend and resume}.
|
||||
*/
|
||||
-#ifdef __APPLE__
|
||||
-static int
|
||||
-get_stackinfo(pthread_t tid, void **addr, long *sizep)
|
||||
+int
|
||||
+np_initialize()
|
||||
{
|
||||
- void *stacktop = pthread_get_stackaddr_np(tid);
|
||||
- *sizep = pthread_get_stacksize_np(tid);
|
||||
- *addr = stacktop - *sizep;
|
||||
+ struct sigaction act;
|
||||
+ char *s;
|
||||
+ int err;
|
||||
|
||||
- return (SYS_OK);
|
||||
-}
|
||||
-#elif defined(__OpenBSD__)
|
||||
-static int
|
||||
-get_stackinfo(pthread_t tid, void **addr, long *sizep)
|
||||
-{
|
||||
- stack_t ss;
|
||||
+ /* Signal numbers used to suspend and resume */
|
||||
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
|
||||
+#ifdef SIGUNUSED
|
||||
+ sr_sigsusp = SIGUNUSED;
|
||||
+#else
|
||||
+ sr_sigsusp = SIGLOST;
|
||||
+#endif
|
||||
+#ifdef SIGPWR
|
||||
+ sr_sigresu = SIGPWR;
|
||||
+#else
|
||||
+ sr_sigresu = SIGXFSZ;
|
||||
+#endif
|
||||
+#else
|
||||
+ sr_sigsusp = SIGXCPU;
|
||||
+ sr_sigresu = SIGXFSZ;
|
||||
+#endif
|
||||
|
||||
- if (pthread_stackseg_np(tid, &ss) == 0) {
|
||||
- *addr = (void *)(ss.ss_sp) - ss.ss_size;
|
||||
- *sizep = (long)(ss.ss_size);
|
||||
- return SYS_OK;
|
||||
- } else {
|
||||
- return SYS_ERR; /* pthreads_stackseg_np failed. */
|
||||
+ /* Set up signal handler for suspend and resume */
|
||||
+#if defined(SA_SIGINFO) && !defined(__sparc__)
|
||||
+ act.sa_handler = 0;
|
||||
+ act.sa_sigaction = susp_handler;
|
||||
+#else
|
||||
+ act.sa_handler = (__sighandler_t) susp_handler;
|
||||
+#endif
|
||||
+#ifdef SA_SIGINFO
|
||||
+ act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
+#else
|
||||
+ act.sa_flags = SA_RESTART;
|
||||
+#endif
|
||||
+ sigfillset(&act.sa_mask);
|
||||
+ if (sigaction(sr_sigsusp, &act, 0) == -1) {
|
||||
+ return -1;
|
||||
}
|
||||
-}
|
||||
+#if defined(SA_SIGINFO) && !defined(__sparc__)
|
||||
+ act.sa_handler = 0;
|
||||
+ act.sa_sigaction = resu_handler;
|
||||
#else
|
||||
-static int
|
||||
-get_stackinfo(pthread_t tid, pthread_attr_t attr, void **addr, long *sizep)
|
||||
-{
|
||||
- size_t s;
|
||||
- void *p;
|
||||
- int ret = SYS_ERR;
|
||||
-
|
||||
- if (pthread_attr_get_np(tid, &attr) != 0)
|
||||
- goto err;
|
||||
- if (pthread_attr_getstackaddr(&attr, &p) != 0)
|
||||
- goto err;
|
||||
- if (pthread_attr_getstacksize(&attr, &s) != 0)
|
||||
- goto err;
|
||||
- *addr = p;
|
||||
- *sizep = s;
|
||||
- ret = SYS_OK;
|
||||
-err:
|
||||
-
|
||||
- return (ret);
|
||||
-}
|
||||
+ act.sa_handler = (__sighandler_t) resu_handler;
|
||||
#endif
|
||||
-
|
||||
-/*
|
||||
- * Get the stack start address, and max stack size for the current thread.
|
||||
- */
|
||||
-int
|
||||
-np_stackinfo(void **addr, long *size)
|
||||
-{
|
||||
-#if defined(__OpenBSD__) || defined(__APPLE__)
|
||||
- return(get_stackinfo(pthread_self(), addr, size));
|
||||
+#ifdef SA_SIGINFO
|
||||
+ act.sa_flags = SA_SIGINFO;
|
||||
#else
|
||||
- pthread_attr_t attr;
|
||||
- int ret = SYS_ERR;
|
||||
+ act.sa_flags = 0;
|
||||
+#endif
|
||||
+ sigfillset(&act.sa_mask);
|
||||
+ if (sigaction(sr_sigresu, &act, 0) == -1) {
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
- if (pthread_attr_init(&attr) == 0) {
|
||||
- ret = get_stackinfo(pthread_self(), attr, addr, size);
|
||||
- pthread_attr_destroy(&attr);
|
||||
+ /* Initialize semaphore used by np_{suspend/resume} */
|
||||
+ if (sem_init(&sr_sem, 0, 0) == -1) {
|
||||
+ return SYS_ERR;
|
||||
}
|
||||
|
||||
- return (ret);
|
||||
-#endif
|
||||
-}
|
||||
+ /* Initialize mutex used by np_{suspend/resume} */
|
||||
+ err = mutexInit(&sr_lock);
|
||||
+ sysAssert(err == 0);
|
||||
|
||||
-/*
|
||||
- * On Bsd when doing CPU profiling, the threads are bound.
|
||||
- */
|
||||
-void
|
||||
-np_profiler_init(sys_thread_t *tid)
|
||||
-{
|
||||
+ return SYS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
-np_profiler_suspend(sys_thread_t *tid)
|
||||
+np_initial_suspend(sys_thread_t* tid)
|
||||
{
|
||||
- return np_suspend(tid);
|
||||
-}
|
||||
+ int count;
|
||||
|
||||
-int
|
||||
-np_profiler_continue(sys_thread_t *tid)
|
||||
-{
|
||||
- return np_continue(tid);
|
||||
-}
|
||||
+ tid->selfsuspended = (tid == sysThreadSelf());
|
||||
+ sysAssert(tid->selfsuspended);
|
||||
|
||||
-bool_t
|
||||
-np_profiler_thread_is_running(sys_thread_t *tid)
|
||||
-{
|
||||
- return TRUE;
|
||||
+ count = tid->suspend_count++;
|
||||
+ sysAssert(count == 0);
|
||||
+
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2,
|
||||
+ "[Initial self-suspend [tid = %ld, sys_thread = %ld]\n",
|
||||
+ pthread_self(), tid->sys_thread);
|
||||
+#endif
|
||||
+
|
||||
+ /* Order should not matter but doing the post first should be faster */
|
||||
+ sem_post(&tid->sem_suspended);
|
||||
+ do {
|
||||
+ sem_wait(&tid->sem_selfsuspend);
|
||||
+ } while (tid->selfsuspended); /* paranoid */
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
-np_initialize()
|
||||
+np_suspend(sys_thread_t *tid)
|
||||
{
|
||||
- return SYS_OK;
|
||||
-}
|
||||
+ int count, ret = 0;
|
||||
|
||||
-/* prototypes */
|
||||
+ int err = mutexLock(&sr_lock);
|
||||
+ sysAssert(err == 0);
|
||||
|
||||
-static void record_thread_regs();
|
||||
+ tid->selfsuspended = (tid == sysThreadSelf());
|
||||
|
||||
-/*
|
||||
- * Suspend all other threads, and record their contexts (register
|
||||
- * set or stack pointer) into the sys_thread structure, so that a
|
||||
- * garbage collect can be run.
|
||||
- */
|
||||
-#ifdef __APPLE__
|
||||
-int
|
||||
-np_single(void)
|
||||
-{
|
||||
- sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
|
||||
+ count = tid->suspend_count++;
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2, "[Suspending fromtid = %ld, tid = %ld, pid = %d, count = %d]\n",
|
||||
+ pthread_self(), tid->sys_thread, tid->lwp_id, count);
|
||||
+#endif
|
||||
+ if (count == 0) {
|
||||
+ if (tid->selfsuspended) {
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2,
|
||||
+ "[Self-suspending [tid = %ld, sys_thread = %ld]\n",
|
||||
+ pthread_self(), tid->sys_thread);
|
||||
+#endif
|
||||
+ mutexUnlock(&sr_lock);
|
||||
+ do {
|
||||
+ sem_wait(&tid->sem_selfsuspend);
|
||||
+ } while (tid->selfsuspended);
|
||||
+ /* [jk] What is the correct return value here?
|
||||
+ There was no error, but when we return the thread
|
||||
+ has already been resumed. */
|
||||
+ return SYS_OK;
|
||||
|
||||
- /* Iterate over all the threads in the task, suspending each one.
|
||||
- * We have to loop until no new threads appear, and all are suspended */
|
||||
- mach_port_t self = pthread_mach_thread_np(pthread_self());
|
||||
+ } else {
|
||||
+ sr_tid = tid;
|
||||
+ ret = pthread_kill(tid->sys_thread, sr_sigsusp);
|
||||
+ if (ret == 0) {
|
||||
+ sem_wait(&sr_sem);
|
||||
+ }
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2,
|
||||
+ "[Suspended fromtid = %ld, pthread_kill(%ld, %d) = %d]\n",
|
||||
+ pthread_self(), tid->sys_thread, sr_sigsusp, ret);
|
||||
+#endif
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ err = mutexUnlock(&sr_lock);
|
||||
+ sysAssert(err == 0);
|
||||
|
||||
- mach_msg_type_number_t cur_count, prev_count, i, j, k;
|
||||
- thread_act_array_t cur_list, prev_list;
|
||||
- bool_t changes;
|
||||
+ return ret == 0 ? SYS_OK : SYS_ERR;
|
||||
+}
|
||||
|
||||
- changes = TRUE;
|
||||
- cur_count = prev_count = 0;
|
||||
- cur_list = prev_list = NULL;
|
||||
- do {
|
||||
- /* Get a list of all threads */
|
||||
- if (task_threads(self, &cur_list, &cur_count) != KERN_SUCCESS)
|
||||
- return SYS_ERR;
|
||||
+int
|
||||
+np_continue(sys_thread_t *tid)
|
||||
+{
|
||||
+ int count, ret = 0;
|
||||
|
||||
- /* For each thread, check if it was previously suspended. If it
|
||||
- * was not, suspend it now, and set the changes flag to 'true' */
|
||||
- changes = FALSE;
|
||||
- for (i = 0; i < cur_count; i++) {
|
||||
- mach_msg_type_number_t j;
|
||||
- bool_t found = FALSE;
|
||||
+ int err = mutexLock(&sr_lock);
|
||||
+ sysAssert(err == 0);
|
||||
|
||||
- /* Check the previous thread list */
|
||||
- for (j = 0; j < prev_count; j++) {
|
||||
- if (prev_list[j] == cur_list[i]) {
|
||||
- found = TRUE;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* If the thread wasn't previously suspended, suspend it now and set the change flag */
|
||||
- if (found) {
|
||||
- /* Don't suspend ourselves! */
|
||||
- if (cur_list[i] != self)
|
||||
- thread_suspend(cur_list[i]);
|
||||
- changes = TRUE;
|
||||
- }
|
||||
+ count = --tid->suspend_count;
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2, "[Resuming fromtid = %ld, tid = %ld, pid = %d, count = %d]\n",
|
||||
+ pthread_self(), tid->sys_thread, tid->lwp_id, count);
|
||||
+#endif
|
||||
+ if (count == 0) {
|
||||
+ if (tid->selfsuspended) {
|
||||
+ tid->selfsuspended = 0;
|
||||
+ sem_post(&tid->sem_selfsuspend);
|
||||
+ } else {
|
||||
+ sr_tid = tid;
|
||||
+ ret = pthread_kill(tid->sys_thread, sr_sigresu);
|
||||
}
|
||||
-
|
||||
- /* Deallocate the previous list, if necessary */
|
||||
- for (k = 0; k < prev_count; k++)
|
||||
- mach_port_deallocate(self, prev_list[k]);
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2, "[Resumed fromtid = %ld, pthread_kill(%ld, %d) = %d]\n",
|
||||
+ pthread_self(), tid->sys_thread, sr_sigresu, ret);
|
||||
+#endif
|
||||
+ } else if (count < 0) {
|
||||
+ /* Ignore attempts to resume a thread that has not been suspended */
|
||||
+ tid->suspend_count = 0;
|
||||
+ }
|
||||
|
||||
- vm_deallocate(self, (vm_address_t)prev_list, sizeof(thread_t) * prev_count);
|
||||
+ err = mutexUnlock(&sr_lock);
|
||||
+ sysAssert(err == 0);
|
||||
|
||||
- /* Set up the 'new' list for the next loop iteration */
|
||||
- prev_list = cur_list;
|
||||
- prev_count = cur_count;
|
||||
- } while (changes);
|
||||
+ return ret == 0 ? SYS_OK : SYS_ERR;
|
||||
+}
|
||||
|
||||
- /* Deallocate the last-allocated list. */
|
||||
- for (i = 0; i < prev_count; i++)
|
||||
- mach_port_deallocate(self, prev_list[i]);
|
||||
+/*
|
||||
+ * Get the stack base and size.
|
||||
+ */
|
||||
+int
|
||||
+np_stackinfo(void **addr, long *size)
|
||||
+{
|
||||
+ /* For now assume stack is 2 meg, from internals.h. */
|
||||
+#define STACK_SIZE (2 * 1024 * 1024)
|
||||
+ void *p;
|
||||
+ char *sp = (char *)&p; /* rougly %esp */
|
||||
|
||||
- vm_deallocate(self, (vm_address_t)prev_list, sizeof(thread_t) * prev_count);
|
||||
+ *addr = (void *)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
|
||||
+ *size = STACK_SIZE;
|
||||
|
||||
- /* Record registers and return */
|
||||
- record_thread_regs();
|
||||
return SYS_OK;
|
||||
}
|
||||
-#else
|
||||
+
|
||||
+typedef unsigned long ulong_t;
|
||||
+#define VALID_SP(sp, bottom, top) \
|
||||
+ (((ulong_t)(sp)) < ((ulong_t)(bottom)) && ((ulong_t)(sp)) > ((ulong_t)(top)))
|
||||
+
|
||||
+/*
|
||||
+ * Go into single threaded mode for GC.
|
||||
+ */
|
||||
int
|
||||
-np_single(void)
|
||||
+np_single()
|
||||
{
|
||||
- sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
|
||||
+ sys_thread_t *tid;
|
||||
+ pthread_t me = pthread_self();
|
||||
+ int i;
|
||||
|
||||
- pthread_suspend_all_np();
|
||||
- record_thread_regs();
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2, "[Entering np_single: thread count = %d]\n", ActiveThreadCount);
|
||||
+#endif
|
||||
+ /* Stop all other threads. */
|
||||
+ tid = ThreadQueue;
|
||||
+ for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
|
||||
+ if ((tid->sys_thread != me) && (tid->state != SUSPENDED)) {
|
||||
+ np_suspend(tid);
|
||||
+ sysAssert(VALID_SP(tid->sp, tid->stack_bottom, tid->stack_top));
|
||||
+ tid->onproc = FALSE; /* REMIND: Might not need this */
|
||||
+ }
|
||||
+ tid = tid->next;
|
||||
+ }
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2, "[Leaving np_single]\n");
|
||||
+#endif
|
||||
return SYS_OK;
|
||||
}
|
||||
-#endif
|
||||
|
||||
/*
|
||||
- * Continue threads suspended earlier.
|
||||
+ * Per thread initialization.
|
||||
*/
|
||||
-#ifdef __APPLE__
|
||||
void
|
||||
-np_multi(void)
|
||||
+np_initialize_thread(sys_thread_t *tid)
|
||||
{
|
||||
- sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
|
||||
+ sigset_t set;
|
||||
|
||||
- mach_msg_type_number_t thr_count, i;
|
||||
- thread_act_array_t thr_list;
|
||||
- mach_port_t self;
|
||||
+ /* Block SIGQUIT so that it can be handled by the SIGQUIT handler thread */
|
||||
+ sigemptyset(&set);
|
||||
+ sigaddset(&set, SIGQUIT);
|
||||
+ pthread_sigmask(SIG_BLOCK, &set, 0);
|
||||
+ /* Set process id */
|
||||
+ tid->lwp_id = getpid();
|
||||
+ tid->suspend_count = 0;
|
||||
|
||||
- self = pthread_mach_thread_np(pthread_self());
|
||||
+ /* Semaphore used for self-suspension */
|
||||
+ sem_init(&tid->sem_selfsuspend, 0, 0);
|
||||
+ tid->selfsuspended = 0;
|
||||
|
||||
- /* Get a list of all threads. This has to succeed! */
|
||||
- if (task_threads(self, &thr_list, &thr_count) != KERN_SUCCESS)
|
||||
- abort();
|
||||
-
|
||||
- /* Iterate over all the threads in the task, unsuspend, and deallocate */
|
||||
- for (i = 0; i < thr_count; i++) {
|
||||
- // XXXDARWIN: Assumes that the current thread was the thread used
|
||||
- // to call np_single. Is that true?
|
||||
-
|
||||
- if (thr_list[i] != self)
|
||||
- thread_resume(thr_list[i]);
|
||||
-
|
||||
- mach_port_deallocate(self, thr_list[i]);
|
||||
- }
|
||||
-
|
||||
- vm_deallocate(self, (vm_address_t) thr_list, sizeof(thread_t) * thr_count);
|
||||
+#ifdef LOG_THREADS
|
||||
+ dprintf(2, "[Init thread, tid = %ld, pid = %d, base = %p, size = %lu]\n",
|
||||
+ pthread_self(), tid->lwp_id, tid->stack_bottom, tid->stack_size);
|
||||
+#endif
|
||||
}
|
||||
-#else
|
||||
+
|
||||
void
|
||||
-np_multi(void)
|
||||
+np_free_thread(sys_thread_t *tid)
|
||||
{
|
||||
- sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
|
||||
- pthread_resume_all_np();
|
||||
+ sem_destroy(&tid->sem_selfsuspend);
|
||||
}
|
||||
-#endif
|
||||
|
||||
/*
|
||||
- * BSDNOTE: Looking to linux implementation -- the only important register
|
||||
- * to set up is tid->sp (stack pointer) now. But it may change when
|
||||
- * FreeBSD and JVM will switch to KSEs. In this case we'll also need to
|
||||
- * care about ucontext I think.
|
||||
- *
|
||||
- * --phantom
|
||||
- *
|
||||
- * XXXBSD: There's a problem with this implemenation. Currently it sets
|
||||
- * the tid->sp to the bottom of the thread stack and not the current stack
|
||||
- * pointer of the suspended thread. Both solaris and linux use the current
|
||||
- * thread stack pointer. -- kurt
|
||||
- *
|
||||
- * Assumes stacks grow down from high to low memory. True on sparc and Intel.
|
||||
+ * Recover from single threaded mode after GC.
|
||||
*/
|
||||
-
|
||||
-static void
|
||||
-record_thread_regs()
|
||||
+void
|
||||
+np_multi()
|
||||
{
|
||||
- void *addr;
|
||||
- long sz;
|
||||
-
|
||||
- sys_thread_t *tid;
|
||||
int i;
|
||||
- int sp;
|
||||
+ sys_thread_t *tid;
|
||||
+ pthread_t me = pthread_self();
|
||||
|
||||
-#ifndef __OpenBSD__
|
||||
- pthread_attr_t attr;
|
||||
- int attr_inited;
|
||||
- attr_inited = pthread_attr_init(&attr) == 0;
|
||||
-#endif
|
||||
-
|
||||
tid = ThreadQueue;
|
||||
for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
|
||||
- if (tid->onproc != TRUE) {
|
||||
- int i;
|
||||
-
|
||||
- if (tid->sys_thread != 0) {
|
||||
- /* if thread has already been initialized */
|
||||
-#if defined(__OpenBSD__) || defined(__APPLE__)
|
||||
- if (get_stackinfo(tid->sys_thread, &addr, &sz) == SYS_OK)
|
||||
-#else
|
||||
- if (get_stackinfo(tid->sys_thread, attr, &addr, &sz) == SYS_OK)
|
||||
-#endif
|
||||
- tid->sp = addr;
|
||||
- else
|
||||
- tid->sp = 0;
|
||||
- } else {
|
||||
- /*
|
||||
- * thread is still in the process of being initalized.
|
||||
- * So GC should not care about this thread. Just
|
||||
- * set its sp to 0, and this will force GC to ignore it.
|
||||
- */
|
||||
- tid->sp = 0;
|
||||
- }
|
||||
+ if ((tid->sys_thread != me) && (tid->state != SUSPENDED)) {
|
||||
+ np_continue(tid);
|
||||
}
|
||||
tid = tid->next;
|
||||
}
|
||||
-#ifndef __OpenBSD__
|
||||
- if (attr_inited)
|
||||
- pthread_attr_destroy(&attr);
|
||||
-#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+np_profiler_init(sys_thread_t *tid)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+np_profiler_suspend(sys_thread_t *tid)
|
||||
+{
|
||||
+ return np_suspend(tid);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+np_profiler_continue(sys_thread_t *tid)
|
||||
+{
|
||||
+ return np_continue(tid);
|
||||
+}
|
||||
+
|
||||
+bool_t
|
||||
+np_profiler_thread_is_running(sys_thread_t *tid)
|
||||
+{
|
||||
+ return TRUE;
|
||||
}
|
Loading…
Reference in New Issue
Block a user