[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