$OpenBSD: patch-j2se_src_solaris_hpi_native_threads_src_threads_bsd_c,v 1.1 2007/09/06 15:46:19 kurt Exp $
--- j2se/src/solaris/hpi/native_threads/src/threads_bsd.c.orig	Sun Jul 29 22:30:33 2007
+++ j2se/src/solaris/hpi/native_threads/src/threads_bsd.c	Mon Jul 30 09:15:23 2007
@@ -25,85 +25,45 @@
 
 /*
  * Implementation of HPI that can not be expressed with POSIX threads.
- * Note that even if you are building with USE_PTHREADS, we have to
- * explicitly undef it here because pthread.h and thread.h can not be
- * included in the same file, and this file needs only thread.h.
  */
-#undef USE_PTHREADS
 
 #include "hpi_impl.h"
 #include "monitor_md.h"
 #include "threads_md.h"
 #include "np.h"
 
-#include <thread.h>
-#include <sys/lwp.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#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
+
+
+#include <time.h>
+#include <string.h>
 #include <signal.h>
 #include <sys/signal.h>
 #include <sys/resource.h>
-#include <sys/procfs.h>
 #include <stdlib.h>
 #include <string.h>
-#include <fcntl.h>
 #include <errno.h>
 
-#include <sys/syscall.h>
-extern int syscall(int, ...);
-
-
 /*
- * Forward declarations.
- */
-static int  procfd;
-static void stop_lwps();
-static void clear_onproc_flags();
-static void restart_lwps();
-static void MakeProcName(register char *procname, register pid_t pid);
-static void GC_msec_sleep(int n);
-
-
-/*
- * Make sure that we link against a verion of libthread that has at least
- * the bug fixes and the interface for getting the stack from threads that
- * aren't on LWPs.  Otherwise we should exit with some informative message.
- */
-extern ulong_t __gettsp(thread_t);
-
-static const char * gettspMessage = 
-"You must install a Bsd patch to run the native threads version of the\n"
-"Java runtime.  The green threads version will work without this patch.\n"
-"Please check the native threads release notes for more information.\n"
-"\n"
-"If you are embedding the VM in a native application, please make sure that\n"
-"the native application is linked with libthread.so (-lthread).\n"
-"\n"
-"Exiting.\n";
-
-static void
-checkForCorrectLibthread()
-{
-    if (&__gettsp == 0) {
-	fprintf(stderr, gettspMessage);
-	exit(1);
-    }
-}
-#ifdef __GNUC__
-static void checkForCorrectLibthread() __attribute__((constructor));
-#else
-#pragma init(checkForCorrectLibthread)
-#endif
-
-#pragma weak __gettsp
-
-
-/*
  * Suspend said thread.  Used to implement java.lang.Thread.suspend(),
  * which is deprecated.
  */
 int
 np_suspend(sys_thread_t *tid)
 {
-    return thr_suspend(tid->sys_thread);
+    return pthread_suspend_np(tid->sys_thread);
 }
 
 
@@ -114,7 +74,7 @@ np_suspend(sys_thread_t *tid)
 int
 np_continue(sys_thread_t *tid)
 {
-    return thr_continue(tid->sys_thread);
+    return pthread_resume_np(tid->sys_thread);
 }
 
 /*
@@ -127,26 +87,65 @@ void np_initialize_thread(sys_thread_t *tid)
 
 
 /*
+ * Internal helper function to get stack information about specified thread.
+ */
+#ifdef __OpenBSD__
+static int
+get_stackinfo(pthread_t tid, void **addr, long *sizep)
+{
+    stack_t ss;
+
+    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. */
+    }
+}
+#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);
+}
+#endif
+
+
+/*
  * Get the stack start address, and max stack size for the current thread.
  */
 int
 np_stackinfo(void **addr, long *size)
 {
-    stack_t stkseg;
-    
-    if (thr_stksegment(&stkseg) == 0) {
-	*addr = (void *)(stkseg.ss_sp);
-	if (thr_main()) {
-	    struct rlimit r;
-	    getrlimit(RLIMIT_STACK, &r);
-	    *size = (long)r.rlim_cur;
-	} else {
-	    *size = (long)(stkseg.ss_size);
-	}
-	return SYS_OK;
-    } else {
-	return SYS_ERR; /* thr_stksegment failed. */
-    }    
+#ifdef __OpenBSD__
+    return(get_stackinfo(pthread_self(), addr, size));
+#else
+    pthread_attr_t attr;
+    int    ret = SYS_ERR;
+
+    if (pthread_attr_init(&attr) == 0) {
+        ret = get_stackinfo(pthread_self(), attr, addr, size);
+        pthread_attr_destroy(&attr);
+    }
+
+    return (ret);
+#endif
 }
 
 /*
@@ -155,150 +154,45 @@ np_stackinfo(void **addr, long *size)
 void
 np_profiler_init(sys_thread_t *tid)
 {
-    tid->lwp_id = _lwp_self();
 }
 
 int
 np_profiler_suspend(sys_thread_t *tid)
 {
-    return _lwp_suspend(tid->lwp_id);
+    if (errno = pthread_suspend_np(tid->sys_thread))
+	return SYS_ERR;
+    return SYS_OK;
 }
 
 int
 np_profiler_continue(sys_thread_t *tid)
 {
-    return _lwp_continue(tid->lwp_id);
+    if (errno = pthread_resume_np(tid->sys_thread))
+	return SYS_ERR;
+    return SYS_OK;
 }
 
+/*
+ * Instead of picking over saved registers, we sum a chunk of the stack.
+ */
 bool_t
 np_profiler_thread_is_running(sys_thread_t *tid)
 {
-    unsigned long sum = 0;
-    int i;
-    prstatus_t lwpstatus;
-    int lwpfd;
-    int res;
-
-    lwpfd = syscall(SYS_ioctl, procfd, PIOCOPENLWP, &(tid->lwp_id));
-    sysAssert(lwpfd >= 0);
-
- retry:
-    res = syscall(SYS_ioctl, lwpfd, PIOCSTATUS, &lwpstatus);
-    sysAssert(res >= 0);
-
-    if (!(lwpstatus.pr_flags & PR_STOPPED)) {
-        GC_msec_sleep(1);
-	goto retry;
-    }
-
-    close(lwpfd);
-
-#if   defined(sparc)
-    sum += lwpstatus.pr_reg[R_SP];
-    sum += lwpstatus.pr_reg[R_PC];
-
-    sum += lwpstatus.pr_reg[R_G1];
-    sum += lwpstatus.pr_reg[R_G2];
-    sum += lwpstatus.pr_reg[R_G3];
-    sum += lwpstatus.pr_reg[R_G4];
-    
-    sum += lwpstatus.pr_reg[R_O0];
-    sum += lwpstatus.pr_reg[R_O1];
-    sum += lwpstatus.pr_reg[R_O2];
-    sum += lwpstatus.pr_reg[R_O3];
-    sum += lwpstatus.pr_reg[R_O4];
-    sum += lwpstatus.pr_reg[R_O5];
-
-    sum += lwpstatus.pr_reg[R_I0];
-    sum += lwpstatus.pr_reg[R_I1];
-    sum += lwpstatus.pr_reg[R_I2];
-    sum += lwpstatus.pr_reg[R_I3];
-    sum += lwpstatus.pr_reg[R_I4];
-    sum += lwpstatus.pr_reg[R_I5];
-    sum += lwpstatus.pr_reg[R_I6];
-    sum += lwpstatus.pr_reg[R_I7];
-
-    sum += lwpstatus.pr_reg[R_L0];
-    sum += lwpstatus.pr_reg[R_L1];
-    sum += lwpstatus.pr_reg[R_L2];
-    sum += lwpstatus.pr_reg[R_L3];
-    sum += lwpstatus.pr_reg[R_L4];
-    sum += lwpstatus.pr_reg[R_L5];
-    sum += lwpstatus.pr_reg[R_L6];
-    sum += lwpstatus.pr_reg[R_L7];
-#elif defined(amd64)
-    sum += lwpstatus.pr_reg[REG_RIP];
-    sum += lwpstatus.pr_reg[REG_RSP];
-
-    sum += lwpstatus.pr_reg[REG_RAX];
-    sum += lwpstatus.pr_reg[REG_RCX];
-    sum += lwpstatus.pr_reg[REG_RDX];
-    sum += lwpstatus.pr_reg[REG_RBX];
-    sum += lwpstatus.pr_reg[REG_RBP];
-    sum += lwpstatus.pr_reg[REG_RSI];
-    sum += lwpstatus.pr_reg[REG_RDI];
-
-    sum += lwpstatus.pr_reg[REG_R8];
-    sum += lwpstatus.pr_reg[REG_R9];
-    sum += lwpstatus.pr_reg[REG_R10];
-    sum += lwpstatus.pr_reg[REG_R11];
-    sum += lwpstatus.pr_reg[REG_R12];
-    sum += lwpstatus.pr_reg[REG_R13];
-    sum += lwpstatus.pr_reg[REG_R14];
-    sum += lwpstatus.pr_reg[REG_R15];
-#elif defined(i386)
-    sum += lwpstatus.pr_reg[EIP];
-    sum += lwpstatus.pr_reg[UESP];
-
-    sum += lwpstatus.pr_reg[EAX];
-    sum += lwpstatus.pr_reg[ECX];
-    sum += lwpstatus.pr_reg[EDX];
-    sum += lwpstatus.pr_reg[EBX];
-    sum += lwpstatus.pr_reg[EBP];
-    sum += lwpstatus.pr_reg[ESI];
-    sum += lwpstatus.pr_reg[EDI];
-#endif
-
-    if (tid->last_sum == sum) {
-        return FALSE;
-    }
-    tid->last_sum = sum;
-
     return TRUE;
 }
 
 
-/*
- * If building for Bsd native threads, open up the /proc file
- * descriptor to be used when doing GC. The open is done at JVM start-up so
- * as to reserve this fd, to prevent GC stall due to exhausted fds. This fd
- * will never be closed, and will alwyas be present.
- */
 int
 np_initialize()
 {
-    char procname[32];
-    MakeProcName(procname, getpid());
-    if ((procfd = open(procname, O_RDONLY, 0)) < 0) {
-	VM_CALL(jio_fprintf)(stderr, "Cannot open %s for GC", procname);
-	return SYS_ERR;
-    }
     return SYS_OK;
 }
 
-static void
-MakeProcName(register char *procname, register pid_t pid)
-{
-    register char * s;
- 
-    (void) strcpy(procname, "/proc/00000");
-    s = procname + strlen(procname);
-    while (pid) {
-        *--s = pid%10 + '0';
-        pid /= 10;
-    }
-}
 
+/* prototypes */
+
+static void record_thread_regs();
+
 /*
  * Suspend all other threads, and record their contexts (register
  * set or stack pointer) into the sys_thread structure, so that a
@@ -307,13 +201,11 @@ MakeProcName(register char *procname, register pid_t p
 int
 np_single(void)
 {
-    int ret;
-
     sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
 
-    stop_lwps();
-    ret = SYS_OK;
-    return ret;
+    pthread_suspend_all_np();
+    record_thread_regs();
+    return SYS_OK;
 }
 
 /*
@@ -324,343 +216,60 @@ void
 np_multi(void)
 {
     sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
-    clear_onproc_flags();
-    restart_lwps();
+    pthread_resume_all_np();
 }
 
-/* /proc solution to stop and restrt lwps */
-/* make sure gc is run as a bound thread */
-/* make sure signals are turned off for gc thread */
-/* what about new lwps getting created in the meantime? */
-
-#define MAX_LWPS 1024
-
-static prstatus_t Mystatus;
-static id_t lwpid_list_buf[MAX_LWPS];
-static id_t oldlwpid_list_buf[MAX_LWPS];
-static sys_thread_t *onproct_list_buf[MAX_LWPS];
-static id_t *lwpid_list = lwpid_list_buf;
-static id_t *oldlwpid_list = oldlwpid_list_buf;
-static sys_thread_t **onproct_list = onproct_list_buf;
-static int lwpid_list_len;
-static int oldlwpid_list_len;
-static int onproct_ix = 0;
-static int gcprio;
-static sigset_t gcmask;
-
-static void
-clear_onproc_flags()
-{
-    int i;
-
-    for (i = 0; i < onproct_ix; i++) {
-        ((sys_thread_t *)(onproct_list[i]))->onproc = FALSE;
-    }
-    onproct_ix = 0;
-}
-
-
-/* Sleep for n milliseconds, n < 1000	*/
-static void
-GC_msec_sleep(int n)
-{
-    struct timespec ts;
-                            
-    ts.tv_sec = 0;
-    ts.tv_nsec = 1000000*n;
-    if (syscall(SYS_nanosleep, &ts, 0) < 0) {
-	VM_CALL(jio_fprintf)(stderr, "%d\n", errno);
-    }
-}
-
 /*
- * Assumes stacks grow down from high to low memory. True on sparc and Intel.
+ * 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
  */
-#define VALID_SP(sp, bottom, top) \
-       (((uintptr_t)(sp)) < ((uintptr_t)(bottom)) && ((uintptr_t)(sp)) > ((uintptr_t)(top)))
-
 static void
-record_lwp_regs(prstatus_t lwpstatus)
+record_thread_regs()
 {
+    void *addr;
+    long sz;
+
     sys_thread_t *tid;
     int i;
-#if   defined(sparc)
-    register uintptr_t sp = lwpstatus.pr_reg[R_SP];
-#elif defined(amd64)
-    register uintptr_t sp = lwpstatus.pr_reg[REG_RSP];
-#elif defined(i386)
-    register uintptr_t sp = lwpstatus.pr_reg[UESP];
-#endif
+    int sp;
 
-    tid = ThreadQueue;
-    for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
-	if (VALID_SP(sp, tid->stack_bottom, tid->stack_top)) {
-	    long *regs = tid->regs;
-	    tid->sp = sp;
-	    /*
-	     * The code below relies on N_TRACED_REGS being set
-	     * correctly for each platform.  If you change the
-	     * number of registers being watched, you should update
-	     * the define for N_TRACED_REGS
-	     */
-#if   defined(sparc)
-	    regs[0] = lwpstatus.pr_reg[R_G1];
-	    regs[1] = lwpstatus.pr_reg[R_G2];
-	    regs[2] = lwpstatus.pr_reg[R_G3];
-	    regs[3] = lwpstatus.pr_reg[R_G4];
-	    
-	    regs[4] = lwpstatus.pr_reg[R_O0];
-	    regs[5] = lwpstatus.pr_reg[R_O1];
-	    regs[6] = lwpstatus.pr_reg[R_O2];
-	    regs[7] = lwpstatus.pr_reg[R_O3];
-	    regs[8] = lwpstatus.pr_reg[R_O4];
-	    regs[9] = lwpstatus.pr_reg[R_O5];
-	    regs[10] = lwpstatus.pr_reg[R_O6];
-	    regs[11] = lwpstatus.pr_reg[R_O7];
-#elif defined(amd64)
-	    regs[0] = lwpstatus.pr_reg[REG_RAX];
-	    regs[1] = lwpstatus.pr_reg[REG_RCX];
-	    regs[2] = lwpstatus.pr_reg[REG_RDX];
-	    regs[3] = lwpstatus.pr_reg[REG_RBX];
-	    regs[4] = lwpstatus.pr_reg[REG_RBP];
-	    regs[5] = lwpstatus.pr_reg[REG_RSI];
-	    regs[6] = lwpstatus.pr_reg[REG_RDI];
-	    regs[7] = lwpstatus.pr_reg[REG_R8];
-	    regs[8] = lwpstatus.pr_reg[REG_R9];
-	    regs[9] = lwpstatus.pr_reg[REG_R10];
-	    regs[10]= lwpstatus.pr_reg[REG_R11];
-	    regs[11]= lwpstatus.pr_reg[REG_R12];
-	    regs[12]= lwpstatus.pr_reg[REG_R13];
-	    regs[13]= lwpstatus.pr_reg[REG_R14];
-	    regs[14]= lwpstatus.pr_reg[REG_R15];
-#elif defined(i386)
-	    regs[0] = lwpstatus.pr_reg[EAX];
-	    regs[1] = lwpstatus.pr_reg[ECX];
-	    regs[2] = lwpstatus.pr_reg[EDX];
-	    regs[3] = lwpstatus.pr_reg[EBX];
-	    regs[4] = lwpstatus.pr_reg[EBP];
-	    regs[5] = lwpstatus.pr_reg[ESI];
-	    regs[6] = lwpstatus.pr_reg[EDI];
+#ifndef __OpenBSD__
+    pthread_attr_t attr;
+    int attr_inited;
+    attr_inited = pthread_attr_init(&attr) == 0;
 #endif
-	    
-	    if (tid->onproc != TRUE) {
-	    	tid->onproc = TRUE;
-	    	onproct_list[onproct_ix++] = tid;
-	    }
-	    break;
-	}
-        tid = tid->next;
-    }
-}
 
-static void
-record_thread_regs()
-{
-    sys_thread_t *tid;
-    int i;
-
     tid = ThreadQueue;
     for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
-	if (tid->onproc != TRUE) {
-	    int i;
+	int i;
 
-	    if (tid->sys_thread != 0) {
-		/* if thread has already been initialized */
-		tid->sp = __gettsp(tid->sys_thread);
-	    } 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.
-		 */
+	if (tid->sys_thread != 0) {
+#ifdef __OpenBSD__
+	    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;
-	    }
-
- 	    /*
- 	     * Clear out the registers since they are no longer live
- 	     * and we don't want to garbage collector to think they are.
- 	     */
-
- 	    for (i = 0; i < N_TRACED_REGS; i++)
- 		tid->regs[i] = 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;
 	}
+
 	tid = tid->next;
     }
-}
-
-static void
-wait_stopped_lwps(void)
-{
-    int i, lwpfd;
-    prstatus_t lwpstatus;
-
-    for (i = 0; i < (int) Mystatus.pr_nlwp; i++) {
-	/* if its  not me */
-	if (lwpid_list[i] != _lwp_self()) {
-
-	    /* open the lwp and check the status */
-	    if ((lwpfd = syscall(SYS_ioctl, procfd, PIOCOPENLWP, 
-	        &lwpid_list[i])) < 0) {
-#ifdef MY_DEBUG
-	        VM_CALL(jio_fprintf)(stderr, "lwpid %d was not found in process\n", 
-		 	    lwpid_list[i]);
+#ifndef __OpenBSD__
+    if (attr_inited)
+        pthread_attr_destroy(&attr);
 #endif
-                continue;
-            }
-	    memset(&lwpstatus, 0, sizeof(lwpstatus));
-	    while (1) {
-		if (syscall(SYS_ioctl,lwpfd, PIOCSTATUS, &lwpstatus)<0) {
-		    sysAssert(0);
-#ifdef MY_DEBUG
-		    VM_CALL(jio_fprintf)(stderr, "PIOCSTATUS failed for lwp %d",
-			        lwpid_list[i]);
-#endif
-	    	    break;
-	        }
-	        if (lwpstatus.pr_flags & PR_STOPPED) {
-	   	    record_lwp_regs(lwpstatus);
-	   	    break;
-	        }
-	        GC_msec_sleep(1);
-            }
-
-	    close (lwpfd);
-	} /* end of if-me */
-    } /* end of for */
 }
 
-static void
-suspend_lwps()
-{
-    int i;
-    /* pioopen all the lwps and stop them - except the one I am running on */
-    for (i = 0; i < (int) Mystatus.pr_nlwp; i++) {
-
-	/* open and stop the lwp if its not me */
-	if (lwpid_list[i] != _lwp_self()) {
-	 
-	    /* PIOCSTOP doesn't work without a writable		*/
-	    /* descriptor.  And that makes the process		*/
-	    /* undebuggable.					*/
-	    if (_lwp_suspend(lwpid_list[i]) < 0) {
-                        /* Could happen if the lwp exited */
-		lwpid_list[i] = _lwp_self();
-		continue;
-	    }
-        }
-    }
-}
-
-static void
-print_lwps()
-{
-#ifdef MY_DEBUG
-    /* print all the lwps in the process */
-    VM_CALL(jio_fprintf)(stdout, "lwpids ");
-    for (i = 0; i < (int) Mystatus.pr_nlwp; i++) {
-        if (i == 0) {
-            VM_CALL(jio_fprintf)(stdout, "%d", lwpid_list[0]);
-        } else if (i != Mystatus.pr_nlwp - 1) {
-            VM_CALL(jio_fprintf)(stdout, ", %d", lwpid_list[i]);
-        } else {
-            VM_CALL(jio_fprintf)(stdout, " and %d", lwpid_list[i]);
-	}
-    }
-#endif
-}
-
-/* routine to iteratively stop all lwps */
-static void
-stop_lwps()
-{
-    int i;
-    sigset_t set;
-    boolean_t changed;
-
-    /* mask all signals */
-    (void) sigfillset(&set);
-    syscall(SYS_sigprocmask, SIG_SETMASK, &set, &gcmask); 
-
-    /* run at highest prio so I cannot be preempted */
-    thr_getprio(thr_self(), &gcprio); 
-    thr_setprio(thr_self(), 2147483647);  /* #define INT_MAX 2147483647 */
-
-    oldlwpid_list_len = 0;
-
-    while(1) {
-	changed = B_FALSE;
-
-	/* Get the # of lwps in the process */
-	memset(&Mystatus, 0, sizeof(Mystatus));
-	syscall(SYS_ioctl, procfd, PIOCSTATUS, &Mystatus);
-
-#ifdef MY_DEBUG
-	VM_CALL(jio_fprintf)(stdout, "Number of lwps in the process is %d\n", 
-		    Mystatus.pr_nlwp);
-	VM_CALL(jio_fprintf)(stdout, "My lwp id is %d\n", _lwp_self());
-#endif
-	lwpid_list_len = Mystatus.pr_nlwp;
-	if (syscall(SYS_ioctl, procfd, PIOCLWPIDS, lwpid_list) == -1) {
-#ifdef MY_DEBUG
- 	    VM_CALL(jio_fprintf)(stderr, "Can't read proc's lwpid list");
-#endif
-	    return;
-	}
-
-	print_lwps();
-
-	/* suspend all the lwps */
-	suspend_lwps();
-
-	/* make sure all the lwps have actually stopped */
-	wait_stopped_lwps();
-
-	/* make sure the list has not changed while you were not looking
-	   else start all over again */
-	if (lwpid_list_len != oldlwpid_list_len) changed = B_TRUE;
-	else  {
-	    for (i=0; i<lwpid_list_len; ++i) {
-	        if (lwpid_list[i] != oldlwpid_list[i]) {
-		    changed = B_TRUE; break; 
-		}
-	    }
-	} 
-	if (!changed) break;
-
-	{
-	    id_t *tmplwpid_list = oldlwpid_list;
-	    oldlwpid_list = lwpid_list; oldlwpid_list_len = lwpid_list_len;
-	    lwpid_list = 0; lwpid_list_len = 0;
-	    lwpid_list = tmplwpid_list;
-	}
-    }
-
-    /* record regs for threads that were not on LWPs */
-    record_thread_regs();
-
-    return;
-}
-
-
-/* Restart all lwps in process.  */
-static void
-restart_lwps()
-{
-    int i;
-
-    for (i = 0; i < Mystatus.pr_nlwp; i++) {
-	if (lwpid_list[i] == _lwp_self()) continue;
-        if (_lwp_continue(lwpid_list[i]) < 0) {
-#ifdef MY_DEBUG
-            VM_CALL(jio_fprintf)(stderr, "Failed to restart lwp %d\n",lwpid_list[i]);
-#endif
-        }
-    }
-
-    /* restore the old priority of the thread */
-    thr_setprio(thr_self(), gcprio); 
-    /* restore the oldmask */
-    syscall(SYS_sigprocmask, SIG_SETMASK, &gcmask, NULL); 
-
-    print_lwps();
-}
