Date: Fri, 24 Jan 2003 03:30:21 +0600 From: Max Khon <fjoe@iclub.nsu.ru> To: Greg Lewis <glewis@eyesbeyond.com> Cc: freebsd-java@freebsd.org Subject: Re: /usr/local/include/utils.h Message-ID: <20030124033021.A38610@iclub.nsu.ru> In-Reply-To: <20030124044501.B76567@misty.eyesbeyond.com>; from glewis@eyesbeyond.com on Fri, Jan 24, 2003 at 04:45:01AM %2B1030 References: <20030123194719.B25462@iclub.nsu.ru> <20030124044501.B76567@misty.eyesbeyond.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
hi, there!
On Fri, Jan 24, 2003 at 04:45:01AM +1030, Greg Lewis wrote:
> > Attached patch should fix problem with utils.h (which is taken from
> > /usr/local/include instead of local jdk source)
>
> Thanks Max! I'll squeeze this in before patchset 8.
I have another (not thoroughly tested) patch to make
-DWITH_NATIVE_THREADS compile on post-4.7 system
A replacement for j2sdk1.3.1/src/solaris/hpi/native_threads/src/threads_bsd.c
attached. It will not compile on 4.7-RELEASE and earlier, probably
some #ifdef munging should be added but I haven't bumped __FreeBSD_version
after pthreads API modifications. Probably 470101 could be used
to filter out most pre-4.7 installations and it will safely work
for 4.8-RELEASE and later (including 5.0-RELEASE and later).
I haven't looked at PR posted today that fixes something related
to native threads (by the way is it really necessary to use
native threads for hotspot?) -- it's hard to read .uue
and probably will not have enough spare time to fix problems with
native threads my patch may introduce but I will be glad to
hear work/doesn't work reports and do submit this file so it
can be tested and probably integrated to patchset8 by someone else.
/fjoe
[-- Attachment #2 --]
/*
* BSDI $Id: threads_bsd.c,v 1.12 2002/02/07 05:19:54 glewis Exp $
*
* from @(#)threads_solaris.c 1.3 98/09/16 * * Copyright 1994-1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
/*
* Implementation of HPI that can not be expressed with POSIX threads.
*/
#include "hpi_impl.h"
#include "monitor_md.h"
#include "threads_md.h"
#include "np.h"
#include <pthread.h>
#include <pthread_np.h>
#if defined(__FreeBSD__)
#include <assert.h>
#undef pthread_attr_default
#undef pthread_mutexattr_default
#undef pthread_condattr_default
#include "pthread_private.h"
#endif
#include <string.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/sysctl.h>
/*
* Forward declarations.
*/
/* Private functions used to implement native threading. --billh */
#ifdef DEBUG_BSD_NATIVE_THREADS
void dumpThreadLogStates(pthread_t);
void dumpThreadStates();
#endif
/*
* Suspend a thread. Used to implement java.lang.Thread.suspend(),
* which is deprecated.
*/
int
np_suspend(sys_thread_t *tid)
{
return pthread_suspend_np(tid->sys_thread);
}
/*
* Resume a suspended thread. Used to implement java.lang.Thread.resume(),
* which is deprecated.
*/
int
np_continue(sys_thread_t *tid)
{
return pthread_resume_np(tid->sys_thread);
}
/*
* If there is any initialization is required by the non-POSIX parts.
*/
void np_initialize_thread(sys_thread_t *tid)
{
return;
}
/*
* Get the stack start address, and max stack size for the current thread.
*/
int
np_stackinfo(void **addr, long *sizep)
{
pthread_attr_t attr;
size_t size;
if ((errno = pthread_attr_init(&attr)))
return SYS_ERR;
if ((errno = pthread_attr_get_np(pthread_self(), &attr)))
goto err;
if ((errno = pthread_attr_getstackaddr(&attr, addr)))
goto err;
if ((errno = pthread_attr_getstacksize(&attr, &size)))
goto err;
*sizep = size;
pthread_attr_destroy(&attr);
return SYS_OK;
err:
pthread_attr_destroy(&attr);
return SYS_ERR;
}
/*
* We appear to use this code to suspend threads and get snapshots of
* their state from the profiler. If that's the case, then it ought
* to suffice to use pthread_suspend_np() and pthread_resume_np().
*/
void
np_profiler_init(sys_thread_t *tid)
{
/*
We should probably attach the newly allocated pthread's thread
structure to the JVM's threading abstraction here, or maybe do
nothing () ? --billh
*/
}
int
np_profiler_suspend(sys_thread_t *tid)
{
if (errno = pthread_suspend_np(tid->sys_thread))
return SYS_ERR;
return SYS_OK;
}
int
np_profiler_continue(sys_thread_t *tid)
{
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)
{
/*
This function didn't show up any where in a grep of all the sources,
nor do any of the other non-posix implementations (Linux, Solaris) have
a function body more complicated than the single statement "return TRUE;".
Do this for the FreeBSD implementation too, since this is a silly
function anyways. --billh
*/
return TRUE;
}
int
np_initialize()
{
return SYS_OK;
}
static void
record_thread_regs()
{
struct pthread *self = pthread_self();
sys_thread_t *tid = ThreadQueue;
int i;
for (i = 0; i < ActiveThreadCount && tid != NULL; i++, tid = tid->next) {
struct pthread *thread = tid->sys_thread;
if (thread == 0) {
/*
* 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;
continue;
}
tid->sp = thread->stack;
/* Potential race here if the stack isn't setup before GC. --billh */
/*
* The thread that calls this function will alway be the JVM GC thread,
* so skip over it in the list of threads.
*/
if (thread != self && (thread->flags & PTHREAD_FLAGS_PRIVATE) == 0) {
register_t *regbase;
#ifdef DEBUG_BSD_NATIVE_THREADS
/*
* Got search candidate..
*/
if (thread->state != PS_SUSPENDED)
dumpThreadLogStates(thread);
#endif
regbase = (register_t*) &thread->ctx.jb[0];
tid->regs[0] = regbase[6]; /* eax */
tid->regs[1] = 0; /* ecx (missing) */
tid->regs[2] = 0; /* edx (missing) */
tid->regs[3] = regbase[1]; /* ebx */
tid->regs[4] = regbase[3]; /* ebp */
tid->regs[5] = regbase[4]; /* esi */
tid->regs[6] = regbase[5]; /* edi */
#ifdef DEBUG_BSD_NATIVE_THREADS
dumpThreadStates();
#endif
}
}
#ifdef DEBUG_BSD_NATIVE_THREADS
fprintf(stderr, "\n\n\nCalling GC thread\n\n\n"); fflush(stderr);
#endif
}
/*
* 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.
*/
int
np_single(void)
{
sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
pthread_suspend_all_np();
record_thread_regs();
return SYS_OK;
}
/*
* Continue threads suspended earlier. But clear their context
* recorded in sys_thread structure first.
*/
void
np_multi(void)
{
sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
pthread_resume_all_np();
}
#ifdef DEBUG_BSD_NATIVE_THREADS
/* pthreads hackery begins --billh */
char SignalList [][16]
=
{
"PS_RUNNING",
"PS_SIGTHREAD",
"PS_MUTEX_WAIT",
"PS_COND_WAIT",
"PS_FDLR_WAIT",
"PS_FDLW_WAIT",
"PS_FDR_WAIT",
"PS_FDW_WAIT",
"PS_FILE_WAIT",
"PS_POLL_WAIT",
"PS_SELECT_WAIT",
"PS_SLEEP_WAIT",
"PS_WAIT_WAIT",
"PS_SIGSUSPEND",
"PS_SIGWAIT",
"PS_SPINBLOCK",
"PS_JOIN",
"PS_SUSPENDED",
"PS_DEAD",
"PS_DEADLOCK",
"PS_STATE_MAX",
"boundless"
};
char *getThreadStateString(enum pthread_state threadState)
{
if (threadState < SATAN)
return SignalList[threadState];
else
return SignalList[SATAN-1];
}
void dumpThreadStates()
{
int threadCount = 0;
struct pthread *thread;
struct pthread *self = pthread_self();
_thread_kern_sig_defer();
TAILQ_FOREACH(thread, &_thread_list, tle) {
if (thread != self) { /* special case this --billh */
printf("\tthread %d\t%s\n",
threadCount,
getThreadStateString(thread->state));
if (thread->state != PS_SUSPENDED)
dumpThreadLogStates(thread);
} else {
printf("\tgc thread %d\t%s\n",
threadCount,
getThreadStateString(thread->state))
}
++threadCount;
}
_thread_kern_sig_undefer();
printf("\n");
}
/*
[A snippet from Dan Eichen's email on the subject]
You can also look at src/gnu/usr.bin/binutils/gdb/freebsd-uthread.c.
It knows how to iterate through all the threads and pull out
(and even set) thread contexts.
All the threads are stored in a TAILQ called _thread_list. There
is one thread that is private to the threads library (uthread_gc.c)
and is marked with thread->flags & PTHREAD_FLAGS_PRIVATE. I don't
think you want to include that thread in whatever you are doing,
but that's up to you to decide.
[end]
1) Write the code to extract the x86's registers from the jmp_buf
and ucontext_t.
--billh
*/
void dumpThreadLogStates(pthread_t thread)
{
int i;
for(i=0; i < STATE_LOG_SIZE; ++i)
{
printf("\t\t%s, %s\n",
getThreadStateString (thread->state_log[i].state),
getSuspendStateString(thread->suspended)
);
printf("\t\tState change fname = %s, lineno = %d, state = %d\n",
thread->state_log[i].fname,
thread->state_log[i].lineno,
thread->state_log[i].state);
if (thread->state_log[i].state == PS_SUSPENDED)
{
printf("\t\t***\n");
return;
}
}
printf("\t\t***XXX\n");
}
#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030124033021.A38610>
