- 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:
kurt 2013-03-19 19:26:45 +00:00
parent dae9c229a7
commit ec59431b2a
4 changed files with 739 additions and 3 deletions

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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;
}