[kaffe] CVS kaffe (robilad): Various warning fixes
Kaffe CVS
cvs-commits at kaffe.org
Tue May 3 13:47:47 PDT 2005
PatchSet 6436
Date: 2005/05/03 20:43:01
Author: robilad
Branch: HEAD
Tag: (none)
Log:
Various warning fixes
2005-05-03 Dalibor Topic <robilad at kaffe.org>
* include/jsyscall.h (SystemCallInterface): Changed prototypes to
use socklen_t where appropriate.
* kaffe/kaffevm/systems/unix-jthreads/syscalls.c,
kaffe/kaffevm/systems/unix-jthreads/jthread.c,
kaffe/kaffevm/systems/unix-pthreads/syscalls.c (jthreadedGetPeerName
jthreadedGetSockOpt, jthreadedGetSockName, jthreadedAccept,
jthreadedRecvfrom): Use socklen_t instead of int to fix compiler warnigs.
* kaffe/kaffevm/systems/oskit-pthreads/syscalls.c (oskit_pthread_getsockopt)
(oskit_pthread_getsockname, oskit_pthread_getpeername, oskit_pthread_accept,
(oskit_pthread_recvfrom): Use socklen_t instead of int to fix compiler warnigs.
* libraries/clib/net/PlainDatagramSocketImpl.c (
gnu_java_net_PlainDatagramSocketImpl_bind,
gnu_java_net_PlainDatagramSocketImpl_peek,
gnu_java_net_PlainDatagramSocketImpl_receive0,
gnu_java_net_PlainDatagramSocketImpl_socketGetOption,
gnu_java_net_PlainDatagramSocketImpl_getTTL): Use socklen_t where
appropriate.
* libraries/clib/net/PlainSocketImpl.c (
gnu_java_net_PlainSocketImpl_socketConnect,
gnu_java_net_PlainSocketImpl_socketBind,
gnu_java_net_PlainSocketImpl_socketAccept,
gnu_java_net_PlainSocketImpl_socketGetOption): Use socklen_t where
appropriate.
* libraries/javalib/java/security/AccessControlContext.java
(checkPermission): Improved exception messages.
Members:
ChangeLog:1.3964->1.3965
include/jsyscall.h:1.19->1.20
kaffe/kaffevm/systems/oskit-pthreads/syscalls.c:1.10->1.11
kaffe/kaffevm/systems/unix-jthreads/jthread.c:INITIAL->1.134
kaffe/kaffevm/systems/unix-jthreads/syscalls.c:1.16->1.17
kaffe/kaffevm/systems/unix-pthreads/syscalls.c:1.31->1.32
libraries/clib/net/PlainDatagramSocketImpl.c:INITIAL->1.52
libraries/clib/net/PlainSocketImpl.c:INITIAL->1.54
libraries/javalib/java/security/AccessControlContext.java:INITIAL->1.6
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3964 kaffe/ChangeLog:1.3965
--- kaffe/ChangeLog:1.3964 Sun May 1 12:43:36 2005
+++ kaffe/ChangeLog Tue May 3 20:43:01 2005
@@ -1,3 +1,36 @@
+2005-05-03 Dalibor Topic <robilad at kaffe.org>
+
+ * include/jsyscall.h (SystemCallInterface): Changed prototypes to
+ use socklen_t where appropriate.
+
+ * kaffe/kaffevm/systems/unix-jthreads/syscalls.c,
+ kaffe/kaffevm/systems/unix-jthreads/jthread.c,
+ kaffe/kaffevm/systems/unix-pthreads/syscalls.c (jthreadedGetPeerName
+ jthreadedGetSockOpt, jthreadedGetSockName, jthreadedAccept,
+ jthreadedRecvfrom): Use socklen_t instead of int to fix compiler warnigs.
+
+ * kaffe/kaffevm/systems/oskit-pthreads/syscalls.c (oskit_pthread_getsockopt)
+ (oskit_pthread_getsockname, oskit_pthread_getpeername, oskit_pthread_accept,
+ (oskit_pthread_recvfrom): Use socklen_t instead of int to fix compiler warnigs.
+
+ * libraries/clib/net/PlainDatagramSocketImpl.c (
+ gnu_java_net_PlainDatagramSocketImpl_bind,
+ gnu_java_net_PlainDatagramSocketImpl_peek,
+ gnu_java_net_PlainDatagramSocketImpl_receive0,
+ gnu_java_net_PlainDatagramSocketImpl_socketGetOption,
+ gnu_java_net_PlainDatagramSocketImpl_getTTL): Use socklen_t where
+ appropriate.
+
+ * libraries/clib/net/PlainSocketImpl.c (
+ gnu_java_net_PlainSocketImpl_socketConnect,
+ gnu_java_net_PlainSocketImpl_socketBind,
+ gnu_java_net_PlainSocketImpl_socketAccept,
+ gnu_java_net_PlainSocketImpl_socketGetOption): Use socklen_t where
+ appropriate.
+
+ * libraries/javalib/java/security/AccessControlContext.java
+ (checkPermission): Improved exception messages.
+
2005-05-01 Dalibor Topic <robilad at kaffe.org>
* kaffe/kaffevm/jit3/machine.c (finishInsnSequence): Fixed
Index: kaffe/include/jsyscall.h
diff -u kaffe/include/jsyscall.h:1.19 kaffe/include/jsyscall.h:1.20
--- kaffe/include/jsyscall.h:1.19 Tue Apr 5 12:58:29 2005
+++ kaffe/include/jsyscall.h Tue May 3 20:43:03 2005
@@ -72,17 +72,17 @@
int (*_connect)(int, struct sockaddr *, int, int timeout);
int (*_bind)(int, struct sockaddr *, int);
int (*_listen)(int, int);
- int (*_accept)(int, struct sockaddr *, int*, int, int *);
+ int (*_accept)(int, struct sockaddr *, socklen_t*, int, int *);
int (*_sockread)(int, void*, size_t, int, ssize_t *);
- int (*_recvfrom)(int, void *, size_t, int, struct sockaddr *, int *,
+ int (*_recvfrom)(int, void *, size_t, int, struct sockaddr *, socklen_t *,
int timeout, ssize_t *);
int (*_sockwrite)(int, const void *, size_t, ssize_t *);
int (*_sendto)(int, const void *, size_t, int, const struct sockaddr *,
int, ssize_t *);
int (*_setsockopt)(int, int, int, const void *, int);
- int (*_getsockopt)(int, int, int, void *, int *);
- int (*_getsockname)(int, struct sockaddr *, int *);
- int (*_getpeername)(int, struct sockaddr *, int *);
+ int (*_getsockopt)(int, int, int, void *, socklen_t *);
+ int (*_getsockname)(int, struct sockaddr *, socklen_t *);
+ int (*_getpeername)(int, struct sockaddr *, socklen_t *);
int (*_sockclose)(int);
int (*_gethostbyname)(const char *, struct hostent **);
int (*_gethostbyaddr)(const char *, size_t, int, struct hostent **);
Index: kaffe/kaffe/kaffevm/systems/oskit-pthreads/syscalls.c
diff -u kaffe/kaffe/kaffevm/systems/oskit-pthreads/syscalls.c:1.10 kaffe/kaffe/kaffevm/systems/oskit-pthreads/syscalls.c:1.11
--- kaffe/kaffe/kaffevm/systems/oskit-pthreads/syscalls.c:1.10 Sat Jul 26 17:28:35 2003
+++ kaffe/kaffe/kaffevm/systems/oskit-pthreads/syscalls.c Tue May 3 20:43:03 2005
@@ -215,7 +215,7 @@
static int
oskit_pthread_recvfrom(int a, void* b, size_t c, int d, struct sockaddr* e,
- int* f, int timeout, ssize_t *out)
+ socklen_t* f, int timeout, ssize_t *out)
{
WITH_TIMEOUT(timeout, ERR(*out = recvfrom(a, b, c, d, e, f)));
}
@@ -235,19 +235,19 @@
}
static int
-oskit_pthread_getsockopt(int a, int b, int c, void* d, int* e)
+oskit_pthread_getsockopt(int a, int b, int c, void* d, socklen_t* e)
{
return (getsockopt(a, b, c, d, e) == -1) ? errno : 0;
}
static int
-oskit_pthread_getsockname(int a, struct sockaddr* b, int* c)
+oskit_pthread_getsockname(int a, struct sockaddr* b, socklen_t* c)
{
return (getsockname(a, b, c) == -1) ? errno : 0;
}
static int
-oskit_pthread_getpeername(int a, struct sockaddr* b, int* c)
+oskit_pthread_getpeername(int a, struct sockaddr* b, socklen_t* c)
{
return (getpeername(a, b, c) == -1) ? errno : 0;
}
===================================================================
Checking out kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c
RCS: /home/cvs/kaffe/kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c,v
VERS: 1.134
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/jthread.c Tue May 3 20:47:47 2005
@@ -0,0 +1,3471 @@
+/*
+ * jthread.c
+ * Java thread package - derived from thread-internal.c
+ *
+ * Internal threading system support
+ *
+ * Copyright (c) 1996, 1997, 1998
+ * Transvirtual Technologies, Inc. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ *
+ * Written by Godmar Back <gback at cs.utah.edu> and
+ * Tim Wilkinson <tim at transvirtual.com>
+ */
+
+#include "config.h"
+#include "jthread.h"
+#include "jsignal.h"
+#include "xprofiler.h"
+#include "jqueue.h"
+/* For NOTIMEOUT */
+#include "jsyscall.h"
+/* For jlong */
+#include "kaffe/jni_md.h"
+/* For Hjava_lang_VMThread */
+#include "thread.h"
+#include "gc.h"
+
+/* Flags used for threading I/O calls */
+#define TH_READ 0
+#define TH_WRITE 1
+#define TH_ACCEPT TH_READ
+#define TH_CONNECT TH_WRITE
+
+/*
+ * If option DETECTDEADLOCK is given, detect deadlocks.
+ * A deadlock is defined as a situation where no thread is runnable and
+ * no threads is blocked on a timer, IO, or other external events.
+ *
+ * Undeffing this will save a few cycles, but kaffe will just hang if
+ * there is a deadlock.
+ */
+#define DETECTDEADLOCK
+
+#if defined(DETECTDEADLOCK)
+#define BLOCKED_ON_EXTERNAL(t) \
+ do { \
+ tblocked_on_external++; \
+ t->flags |= THREAD_FLAGS_BLOCKEDEXTERNAL; \
+ } while (0)
+
+#define CLEAR_BLOCKED_ON_EXTERNAL(t) \
+ do { \
+ if (t->flags & THREAD_FLAGS_BLOCKEDEXTERNAL) { \
+ tblocked_on_external--; \
+ t->flags &= ~THREAD_FLAGS_BLOCKEDEXTERNAL; \
+ } \
+ } while (0)
+
+/* number of threads blocked on external events */
+static int tblocked_on_external;
+
+#else /* !DETECTDEADLOCK */
+
+#define BLOCKED_ON_EXTERNAL(t)
+#define CLEAR_BLOCKED_ON_EXTERNAL(t)
+
+#endif
+
+/*
+ * Variables.
+ * These should be kept static to ensure encapsulation.
+ */
+static int preemptive = true; /* enable preemptive scheduling */
+static int talive; /* number of threads alive */
+static int tdaemon; /* number of daemons alive */
+static void (*runOnExit)(void); /* function to run when all non-daemon die */
+
+#define JTHREADQ(q) ((jthread *)(q)->element)
+static KaffePool *queuePool; /* pool of single-linked node */
+static KaffeNodeQueue**threadQhead; /* double-linked run queue */
+static KaffeNodeQueue**threadQtail;
+static KaffeNodeQueue* liveThreads; /* list of all live threads */
+static KaffeNodeQueue* alarmList; /* list of all threads on alarm queue */
+static KaffeNodeQueue* waitForList; /* list of all threads waiting for a child */
+
+static int maxFd = -1; /* highest known fd */
+static fd_set readsPending; /* fds we want to read from */
+static fd_set writesPending; /* fds we want to write to */
+static KaffeNodeQueue* readQ[FD_SETSIZE]; /* threads blocked on read */
+static KaffeNodeQueue* writeQ[FD_SETSIZE]; /* threads blocked on write */
+static jbool blockingFD[FD_SETSIZE]; /* file descriptor which should
+ really block */
+static jmutex threadLock; /* static lock to protect liveThreads etc. */
+static jmutex GClock;
+
+static int sigPending; /* flags that says whether a intr is pending */
+static int pendingSig[NSIG]; /* array that says which intrs are pending */
+static int sigPipe[2]; /* a pipe to ensure we don't lose our wakeup */
+static int bytesInPipe; /* total number of bytes written to pipe */
+static int wouldlosewakeup; /* a flag that says whether we're past the
+ point where we check for pending signals
+ before sleeping in select() */
+
+static int blockInts; /* counter that says whether irqs are blocked */
+static int needReschedule; /* is a change in the current thread required */
+
+/** This is the garbage collector to use to allocate thread data. */
+static Collector *threadCollector;
+
+/*
+ * the following variables are set by jthread_init, and show how the
+ * threading system is parametrized.
+ */
+static void (*destructor1)(void*); /* call when a thread exits */
+static void (*onstop)(void); /* call when a thread is stopped */
+static void (*ondeadlock)(void); /* call when we detect deadlock */
+static int max_priority; /* maximum supported priority */
+static int min_priority; /* minimum supported priority */
+
+jthread* currentJThread = NULL;
+static jthread* firstThread = NULL;
+
+/* Context switch related functions */
+#ifndef JTHREAD_CONTEXT_SAVE
+#define JTHREAD_CONTEXT_SAVE(buf) JTHREAD_SETJMP((buf))
+#endif
+#ifndef JTHREAD_CONTEXT_RESTORE
+#define JTHREAD_CONTEXT_RESTORE(buf, val) JTHREAD_LONGJMP((buf), (val))
+#endif
+
+/* The arguments to a signal handler */
+#ifndef SIGNAL_ARGS
+#define SIGNAL_ARGS(sig, sc) int sig
+#endif
+
+/* Get a signal context pointer from signal arguments */
+#ifndef GET_SIGNAL_CONTEXT_POINTER
+#define GET_SIGNAL_CONTEXT_POINTER(x) 0
+#endif
+
+/* A signal context pointer type, used in parameter lists/declarations */
+#ifndef SIGNAL_CONTEXT_POINTER
+#define SIGNAL_CONTEXT_POINTER(x) void *x
+#endif
+
+/* Get the PC from a signal context pointer */
+#ifndef SIGNAL_PC
+#define SIGNAL_PC(scp) 0
+#endif
+
+/*
+ * Function declarations.
+ * Again, keep these static to ensure encapsulation.
+ */
+static void handleInterrupt(int sig, SIGNAL_CONTEXT_POINTER(sc));
+static void interrupt(SIGNAL_ARGS(sig, sc));
+static void childDeath(void);
+static void handleIO(int);
+static void killThread(jthread *jtid);
+static void resumeThread(jthread* jtid);
+static void reschedule(void);
+static void restore_fds(void);
+static void restore_fds_and_exit(void);
+static void die(void);
+static int jthreadedFileDescriptor(int fd);
+static void intsDisable(void);
+static void intsRestore(void);
+static void addWaitQThread(jthread *jtid, KaffeNodeQueue **queue);
+static void cleanupWaitQ(jthread *jtid);
+
+/*
+ * macros to set and extract stack pointer from jmp_buf
+ * make sure SP_OFFSET has the correct value for your architecture!
+ */
+#define GET_SP(E) (((void**)(E))[SP_OFFSET])
+#define SET_SP(E, V) ((void**)(E))[SP_OFFSET] = (V)
+#define GET_FP(E) (((void**)(E))[FP_OFFSET])
+#define SET_FP(E, V) ((void**)(E))[FP_OFFSET] = (V)
+
+/*
+ * Macros to set and extract backing store pointer from jmp_buf
+ * (IA-64 specific)
+ */
+#if defined(__ia64__)
+#define BSP_OFFSET 17
+#define GET_BSP(E) (((void**)(E))[BSP_OFFSET])
+#define SET_BSP(E, V) ((void**)(E))[BSP_OFFSET] = (V)
+#endif
+
+/* Set the base pointer in a jmp_buf if we can (only a convenience) */
+#if defined(BP_OFFSET)
+#define SET_BP(E, V) ((void**)(E))[BP_OFFSET] = (V)
+#endif
+
+/* amount of stack space to be duplicated at stack creation time */
+#if !defined(STACK_COPY)
+#define STACK_COPY (32*4)
+#endif
+
+#if defined(HAVE_SYS_WAIT_H)
+#include <sys/wait.h>
+#endif
+
+/* Select an alarm system */
+#if defined(HAVE_SETITIMER) && defined(ITIMER_REAL)
+#define MALARM(_mt) \
+ { \
+ struct itimerval tm; \
+ tm.it_interval.tv_sec = 0; \
+ tm.it_interval.tv_usec = 0; \
+ tm.it_value.tv_sec = (_mt) / 1000; \
+ tm.it_value.tv_usec = ((_mt) % 1000) * 1000; \
+ setitimer(ITIMER_REAL, &tm, 0); \
+ }
+#elif defined(HAVE_ALARM)
+#define MALARM(_mt) alarm((int)(((_mt) + 999) / 1000))
+#endif
+
+/*============================================================================
+ *
+ * Functions related to list manipulation and interrupt handling
+ *
+ */
+
+/*
+ * Check whether a thread is on a given list
+ */
+static int
+isOnList(KaffeNodeQueue *list, jthread *t)
+{
+ for (; list != NULL; list = list->next) {
+ if (JTHREADQ(list) == t) {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+
+/*
+ * yield to another thread
+ */
+static inline void
+internalYield(void)
+{
+ int priority = currentJThread->priority;
+
+ if (threadQhead[priority] != 0 &&
+ threadQhead[priority] != threadQtail[priority])
+ {
+ /* Get the first thread and move it to the end */
+ KaffeNodeQueue *firstThreadNode = threadQhead[priority];
+ threadQhead[priority] = firstThreadNode->next;
+ threadQtail[priority]->next = firstThreadNode;
+ threadQtail[priority] = firstThreadNode;
+ firstThreadNode->next = 0;
+ needReschedule = true;
+ }
+}
+
+static void
+addToAlarmQ(jthread* jtid, jlong timeout)
+{
+ KaffeNodeQueue** tidp;
+ KaffeNodeQueue* node;
+ jlong ct;
+
+ assert(intsDisabled());
+
+ ct = currentTime();
+ if( (timeout + ct) > ct ) {
+ jtid->flags |= THREAD_FLAGS_ALARM;
+
+ /* Get absolute time */
+ jtid->time = timeout + ct;
+
+ /* Find place in alarm list and insert it */
+ for (tidp = &alarmList;
+ (*tidp) != 0;
+ tidp = &(*tidp)->next) {
+ if (JTHREADQ(*tidp)->time > jtid->time)
+ {
+ break;
+ }
+ }
+ node = KaffePoolNewNode(queuePool);
+ node->next = *tidp;
+ node->element = jtid;
+ *tidp = node;
+
+ /* If I'm head of alarm list, restart alarm */
+ if (tidp == &alarmList)
+ {
+ MALARM(timeout);
+ }
+ } else {
+ /* Huge timeout value, ignore it. */
+ }
+}
+
+static void
+removeFromAlarmQ(jthread* jtid)
+{
+ KaffeNodeQueue** tidp;
+
+ assert(intsDisabled());
+
+ jtid->flags &= ~THREAD_FLAGS_ALARM;
+
+ /* Find thread in alarm list and remove it */
+ for (tidp = &alarmList; (*tidp) != 0; tidp = &(*tidp)->next)
+ {
+ if (JTHREADQ(*tidp) == jtid)
+ {
+ KaffeNodeQueue *node = *tidp;
+
+ (*tidp) = node->next;
+ KaffePoolReleaseNode(queuePool, node);
+ break;
+ }
+ }
+}
+
+/*
+ * check whether interrupts are disabled
+ */
+int
+intsDisabled(void)
+{
+ return (blockInts > 0);
+}
+
+/*
+ * disable interrupts
+ *
+ * Instead of blocking signals, we increment a counter.
+ * If a signal comes in while the counter is non-zero, we set a pending flag
+ * and mark the signal as pending.
+ *
+ * intsDisable may be invoked recursively. (is that really a good idea? - gb)
+ */
+static inline void
+intsDisable(void)
+{
+ blockInts++;
+}
+
+static inline void
+processSignals(void)
+{
+ int i;
+ for (i = 1; i < NSIG; i++)
+ {
+ if (pendingSig[i])
+ {
+ pendingSig[i] = 0;
+ handleInterrupt(i, 0);
+ }
+ }
+ sigPending = 0;
+}
+
+/*
+ * restore interrupts
+ *
+ * If interrupts are about to be reenabled, execute the handlers for all
+ * signals that are pending.
+ */
+static inline void
+intsRestore(void)
+{
+ /* KAFFE_VMDEBUG */
+ assert(blockInts >= 1);
+
+ if (blockInts == 1) {
+ if (sigPending) {
+ processSignals();
+ }
+
+ /* reschedule if necessary */
+ if (needReschedule == true) {
+ reschedule();
+ }
+ }
+ blockInts--;
+}
+
+/*
+ * Prevent all other threads from running.
+ * In this uniprocessor implementation, this is simple.
+ */
+void
+jthread_suspendall(void)
+{
+ intsDisable();
+}
+
+/*
+ * Reallow other threads.
+ * In this uniprocessor implementation, this is simple.
+ */
+void
+jthread_unsuspendall(void)
+{
+ intsRestore();
+}
+
+/*
+ * Handle an asynchronous signal (i.e. a software interrupt).
+ *
+ * This is the handler given to registerAsyncSignalHandler().
+ *
+ * It is guaranteed that all asynchronous signals are delayed when
+ * this handler begins execution (see registerAsyncSignalHandler()).
+ * There are two ways for the asynchronous signals to get unblocked:
+ * (1) return from the function. The OS will unblock them. (2)
+ * explicitly unblock the signals. We must do this before performing
+ * a thread context switch as the target thread should (obviously) not
+ * be running with all signals blocked.
+ */
+static void
+interrupt(SIGNAL_ARGS(sig, sc))
+{
+ if( currentJThread->status != THREAD_SUSPENDED )
+ {
+#ifdef ENABLE_JVMPI
+ EXCEPTIONFRAME(jthread_current()->localData.topFrame, sc);
+#endif
+ }
+
+ /*
+ * If ints are blocked, this might indicate an inconsistent state of
+ * one of the thread queues (either alarmList or threadQhead/tail).
+ *
+ * Record this interrupt as pending so that the forthcoming
+ * intsRestore() (the intsRestore() in the interrupted thread)
+ * will handle it. Then return from the signal handler.
+ *
+ * Also mark the interrupt as pending if interrupts are not disabled,
+ * but the wouldlosewakeup flag is set. This is the case before
+ * we go in select/poll.
+ */
+ if (intsDisabled() || wouldlosewakeup) {
+ char c;
+ pendingSig[sig] = 1;
+ sigPending = 1;
+
+#if defined(KAFFE_XPROFILER)
+ /*
+ * Since the regular handler won't run with the sig context we
+ * need to do the hit here
+ */
+ if( sig == SIGVTALRM )
+ {
+ SIGNAL_CONTEXT_POINTER(scp) =
+ GET_SIGNAL_CONTEXT_POINTER(sc);
+
+ profileHit((char *)SIGNAL_PC(scp));
+ }
+#endif
+ /*
+ * There is a race condition in handleIO() between
+ * zeroing blockints and going into select().
+ * sigPipe+wouldlosewakeup is the hack that avoids
+ * that race condition. See handleIO().
+ *
+ * If we would lose the wakeup because we're about to go to
+ * sleep in select(), write into the sigPipe to ensure select
+ * returns.
+ */
+ /*
+ * Write a byte in the pipe if we get a signal if
+ * wouldlosewakeup is set.
+ * Do not write more than one byte, however.
+ */
+ if (wouldlosewakeup == 1) {
+ write(sigPipe[1], &c, 1);
+ bytesInPipe++;
+ wouldlosewakeup++;
+ }
+
+#if defined(KAFFE_SIGNAL_ONE_SHOT)
+ /*
+ * On some systems, signal handlers are a one-shot deal.
+ * Re-install the signal handler for those systems.
+ */
+ restoreAsyncSignalHandler(sig, interrupt);
+#endif
+
+ /*
+ * Returning from the signal handler should restore
+ * all signal state (if the OS is not broken).
+ */
+ return;
+ }
+
+ /*
+ * The interrupted code was not in a critical section,
+ * so we enter a critical section now. Note that we
+ * will *not* be interrupted between the blockInts
+ * check above and the intsDisable() below because
+ * the signal mask delays all asynchronous signals.
+ */
+
+ intsDisable();
+
+#if defined(KAFFE_SIGNAL_ONE_SHOT)
+ /* Re-enable signal if necessary */
+ restoreAsyncSignalHandler(sig, interrupt);
+#endif
+
+ /*
+ * Restore the signal state. This means unblock all
+ * asynchronous signals. We can now context switch to another
+ * thread as the signal state for the Kaffe process is clear
+ * in the eyes of the OS. Any asynchronous signals that come
+ * in because we just unblocked them will discover that
+ * blockInts > 0, and flag their arrival in the pendingSig[]
+ * array.
+ *
+ * We clear the signal's pending indicator before reallowing signals.
+ */
+ pendingSig[sig] = 0;
+ unblockAsyncSignals();
+
+ /*
+ * Handle the signal.
+ */
+ handleInterrupt(sig, (void*)GET_SIGNAL_CONTEXT_POINTER(sc));
+
+ /*
+ * Leave the critical section. This may or may not cause a
+ * reschedule. (Depends on the side-effects of
+ * handleInterrupt()).
+ */
+ intsRestore();
+}
+
+/*
+ * handle a SIGVTALRM alarm.
+ *
+ * If preemption is disabled, we have the current thread so that it is
+ * scheduled in a round-robin fashion with its peers who have the same
+ * priority.
+ */
+static void
+handleVtAlarm(int sig UNUSED, SIGNAL_CONTEXT_POINTER(sc UNUSED))
+{
+ static int c;
+
+#if defined(KAFFE_XPROFILER)
+ if( sc )
+ profileHit((char *)SIGNAL_PC(sc));
+#endif
+ if (preemptive) {
+ internalYield();
+ }
+
+ /*
+ * This is kind of ugly: some fds won't send us SIGIO.
+ * Example: the pseudo-tty driver in FreeBSD won't send a signal
+ * if we blocked on a write because the output buffer was full, and
+ * the output buffer became empty again.
+ *
+ * So we check periodically, every 0.2 seconds virtual time.
+ */
+ if (++c % 20 == 0) {
+ handleIO(false);
+ }
+}
+
+/*
+ * handle a SIGALRM alarm.
+ */
+static void
+alarmException(void)
+{
+ jthread* jtid;
+ jlong curTime;
+
+ /* Wake all the threads which need waking */
+ curTime = currentTime();
+ while (alarmList != 0 && JTHREADQ(alarmList)->time <= curTime) {
+ KaffeNodeQueue* node = alarmList;
+ /* Restart thread - this will tidy up the alarm and blocked
+ * queues.
+ */
+ jtid = JTHREADQ(node);
+ alarmList = node->next;
+ KaffePoolReleaseNode(queuePool, node);
+
+ resumeThread(jtid);
+ }
+
+ /* Restart alarm */
+ if (alarmList != 0) {
+ MALARM(JTHREADQ(alarmList)->time - curTime);
+ }
+}
+
+/*
+ * print thread flags in pretty form.
+ */
+static char*
+printflags(unsigned i)
+{
+ static char b[256]; /* plenty */
+ struct {
+ int flagvalue;
+ const char *flagname;
+ } flags[] = {
+ { THREAD_FLAGS_GENERAL, "GENERAL" },
+ { THREAD_FLAGS_NOSTACKALLOC, "NOSTACKALLOC" },
+ { THREAD_FLAGS_KILLED, "KILLED" },
+ { THREAD_FLAGS_ALARM, "ALARM" },
+ { THREAD_FLAGS_EXITING, "EXITING" },
+ { THREAD_FLAGS_DONTSTOP, "DONTSTOP" },
+ { THREAD_FLAGS_DYING, "DYING" },
+ { THREAD_FLAGS_BLOCKEDEXTERNAL, "BLOCKEDEXTERNAL" },
+ { THREAD_FLAGS_INTERRUPTED, "INTERRUPTED" },
+ { 0, NULL }
+ }, *f = flags;
+
+ b[0] = '\0';
+ while (f->flagname) {
+ if (i & f->flagvalue) {
+ strcat(b, f->flagname);
+ strcat(b, " ");
+ }
+ f++;
+ }
+ return b;
+}
+
+/*
+ * dump information about a thread to stderr
+ */
+void
+jthread_dumpthreadinfo(jthread_t tid)
+{
+ dprintf("tid %p, status %s flags %s\n", tid,
+ tid->status == THREAD_SUSPENDED ? "SUSPENDED" :
+ tid->status == THREAD_RUNNING ? "RUNNING" :
+ tid->status == THREAD_DEAD ? "DEAD" : "UNKNOWN!!!",
+ printflags(tid->flags));
+ if (tid->blockqueue != NULL) {
+ int i;
+
+ dprintf(" blocked");
+ if (isOnList(waitForList, tid)) {
+ dprintf(": waiting for children");
+ }
+#if 0
+ /* XXX FIXME: alarmList uses nextalarm, but isOnList iterates
+ * using nextQ
+ */
+ if (isOnList(alarmList, tid)) {
+ dprintf(": sleeping");
+ }
+#endif
+ for (i = 0; i < FD_SETSIZE; i++) {
+ if (isOnList(readQ[i], tid)) {
+ dprintf(": reading from fd %d ", i);
+ break;
+ }
+ if (isOnList(writeQ[i], tid)) {
+ dprintf(": writing to fd %d ", i);
+ break;
+ }
+ }
+
+#if 0
+ dprintf("@%p (%p->", tid->blockqueue,
+ t = *tid->blockqueue);
+ while (t && t->nextQ) {
+ t = t->nextQ;
+ dprintf("%p->", t);
+ }
+ dprintf("|) ");
+#endif
+ }
+}
+
+/*
+ * print info about a java thread (hopefully we'll get this to include more
+ * detail, such as the actual stack traces for each thread)
+ *
+ */
+static void
+dumpJavaThreadLocal(jthread_t thread, UNUSED void *p)
+{
+ Hjava_lang_VMThread *tid = (Hjava_lang_VMThread *)jthread_get_data(thread)->jlThread;
+ dprintf("`%s' ", nameThread(tid));
+ jthread_dumpthreadinfo(thread);
+ dprintf("\n");
+}
+
+static void
+dumpThreadsLocal(void)
+{
+ dprintf("Dumping live threads:\n");
+ jthread_walkLiveThreads(dumpJavaThreadLocal, NULL);
+}
+
+
+/*
+ * handle an interrupt.
+ *
+ * this function is either invoked from within a signal handler, or as the
+ * result of intsRestore.
+ */
+static void
+handleInterrupt(int sig, SIGNAL_CONTEXT_POINTER(sc))
+{
+ switch(sig) {
+ case SIGALRM:
+ alarmException();
+ break;
+
+ case SIGUSR1:
+ ondeadlock();
+ break;
+
+ case SIGUSR2:
+ dumpThreadsLocal();
+ break;
+
+#if defined(SIGVTALRM)
+ case SIGVTALRM:
+ handleVtAlarm(sig, sc);
+ break;
+#endif
+
+ case SIGCHLD:
+ childDeath();
+ break;
+
+ case SIGIO:
+ handleIO(false);
+ break;
+
+ default:
+ dprintf("unknown signal %d\n", sig);
+ exit(-1);
+ }
+}
+
+/*============================================================================
+ *
+ * Functions related to run queue manipulation
+ */
+
+
+/*
+ * Resume a thread running.
+ * This routine has to be called only from locations which ensure
+ * run / block queue consistency. There is no check for illegal resume
+ * conditions (like explicitly resuming an IO blocked thread).
+ */
+static void
+resumeThread(jthread* jtid)
+{
+ KaffeNodeQueue** ntid;
+
+DBG(JTHREAD, dprintf("resumeThread %p\n", jtid); );
+ intsDisable();
+
+ if (jtid->status != THREAD_RUNNING) {
+
+ CLEAR_BLOCKED_ON_EXTERNAL(jtid);
+
+ /* Remove from alarmQ if necessary */
+ if ((jtid->flags & THREAD_FLAGS_ALARM) != 0) {
+ removeFromAlarmQ(jtid);
+ }
+ /* Remove from lockQ if necessary */
+ if (jtid->blockqueue != 0) {
+ KaffeNodeQueue **queue;
+
+ for (queue= &jtid->blockqueue;
+ *queue != 0;
+ queue = &(*queue)->next)
+ {
+ for (ntid = (KaffeNodeQueue **)((*queue)->element);
+ *ntid != 0;
+ ntid = &(*ntid)->next)
+ {
+ if (JTHREADQ(*ntid) == jtid) {
+ KaffeNodeQueue *node = *ntid;
+
+ *ntid = node->next;
+ KaffePoolReleaseNode(queuePool, node);
+ break;
+ }
+ }
+ }
+ KaffePoolReleaseList(queuePool, jtid->blockqueue);
+ jtid->blockqueue = NULL;
+ }
+
+ jtid->status = THREAD_RUNNING;
+
+ /* Place thread on the end of its queue */
+ if (jtid->suspender != NULL) {
+ /* Need to wait for the suspender to resume them. */
+ }
+ else if (threadQhead[jtid->priority] == 0) {
+ threadQhead[jtid->priority] = KaffePoolNewNode(queuePool);
+ threadQhead[jtid->priority]->element = jtid;
+ threadQtail[jtid->priority] = threadQhead[jtid->priority];
+ if (jtid->priority > currentJThread->priority) {
+ needReschedule = true;
+ }
+ }
+ else {
+ KaffeNodeQueue *queue = KaffePoolNewNode(queuePool);
+
+ queue->element = jtid;
+ threadQtail[jtid->priority]->next = queue;
+ threadQtail[jtid->priority] = queue;
+ }
+ } else {
+DBG(JTHREAD, dprintf("Re-resuming %p\n", jtid); );
+ }
+ intsRestore();
+}
+
+/*
+ * Add a new waiting queue for this thread.
+ * Assert: ints must be disabled to avoid reschedule
+ * while we set up the waiting queues.
+ */
+static void
+addWaitQThread(jthread *jtid, KaffeNodeQueue **queue)
*** Patch too long, truncated ***
More information about the kaffe
mailing list