From owner-freebsd-java Thu Jan 23 13:32:22 2003 Delivered-To: freebsd-java@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8820E37B401 for ; Thu, 23 Jan 2003 13:32:12 -0800 (PST) Received: from mail.nsu.ru (mx.nsu.ru [193.124.215.71]) by mx1.FreeBSD.org (Postfix) with ESMTP id DB42443F13 for ; Thu, 23 Jan 2003 13:32:09 -0800 (PST) (envelope-from fjoe@iclub.nsu.ru) Received: from drweb by mail.nsu.ru with drweb-scanned (Exim 3.20 #1) id 18bovk-0002cp-00; Fri, 24 Jan 2003 03:30:36 +0600 Received: from iclub.nsu.ru ([193.124.215.97] ident=root) by mail.nsu.ru with esmtp (Exim 3.20 #1) id 18bovj-0002cB-00; Fri, 24 Jan 2003 03:30:35 +0600 Received: from iclub.nsu.ru (fjoe@localhost [127.0.0.1]) by iclub.nsu.ru (8.12.6/8.12.6) with ESMTP id h0NLUNRV039034; Fri, 24 Jan 2003 03:30:23 +0600 (NS) (envelope-from fjoe@iclub.nsu.ru) Received: (from fjoe@localhost) by iclub.nsu.ru (8.12.6/8.12.6/Submit) id h0NLUMDN039033; Fri, 24 Jan 2003 03:30:22 +0600 (NS) Date: Fri, 24 Jan 2003 03:30:21 +0600 From: Max Khon To: Greg Lewis Cc: freebsd-java@freebsd.org Subject: Re: /usr/local/include/utils.h Message-ID: <20030124033021.A38610@iclub.nsu.ru> References: <20030123194719.B25462@iclub.nsu.ru> <20030124044501.B76567@misty.eyesbeyond.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="rwEMma7ioTxnRzrJ" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20030124044501.B76567@misty.eyesbeyond.com>; from glewis@eyesbeyond.com on Fri, Jan 24, 2003 at 04:45:01AM +1030 X-Spam-Status: No, hits=-3.0 required=5.0 tests=IN_REP_TO,QUOTED_EMAIL_TEXT,REFERENCES,SPAM_PHRASE_00_01, USER_AGENT,USER_AGENT_MUTT version=2.43 X-Envelope-To: glewis@eyesbeyond.com, freebsd-java@freebsd.org Sender: owner-freebsd-java@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org --rwEMma7ioTxnRzrJ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --rwEMma7ioTxnRzrJ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="threads_bsd.c" /* * 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 #include #if defined(__FreeBSD__) #include #undef pthread_attr_default #undef pthread_mutexattr_default #undef pthread_condattr_default #include "pthread_private.h" #endif #include #include #include #include #include #include #include #include #include /* * 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 --rwEMma7ioTxnRzrJ-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-java" in the body of the message