⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread-impl.c

📁 kaffe是一个java虚拟机的源代码。里面包含了一些java例程和标准的java包。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * thread-impl.c - pthread based ThreadInterface implementation * * Copyright (c) 1998 *      Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include <pthread.h>#include <semaphore.h>#include <sched.h>#include "config.h"#include "config-std.h"#include "config-signal.h"#include "java_lang_Throwable.h"#include "gtypes.h"#include "thread.h"#include "gc.h"#include "jni.h"#include "locks.h"#define	DBG(X,Y)/* these are required for handling exceptions */#include "exception.h"#if defined(INTERPRETER)#define DEFINEFRAME()           /* Does nothing */#define EXCEPTIONPROTO          int sig#define EXCEPTIONFRAME(f, c)    /* Does nothing */#define EXCEPTIONFRAMEPTR       0#elif defined(TRANSLATOR)#define DEFINEFRAME()           exceptionFrame frame#define EXCEPTIONFRAMEPTR       &frame#endif /* TRANSLATOR *//* Some systems need special setups for the exception handling */#if !defined(EXCEPTIONSTART)#define EXCEPTIONSTART()#endif#if !defined(EXCEPTIONEND)#define EXCEPTIONEND()#endif#if defined(DEBUG)char stat_act[]   = { ' ', 'a' };char stat_susp[]  = { ' ', 's', ' ', 'r', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };char stat_block[] = { ' ', 'T', 'm', ' ', 'c', ' ', ' ', ' ', 't', ' ', ' ' };#endif/*********************************************************************** * typedefs & defines */#include <bits/local_lim.h>/* * This is the configurable section. Note that SCHED_FIFO is the only * schedule policy which conforms to the "old" Java thread model (with * stringent priorities), but it usually isn't available on desktop * OSes (or imposes certain restrictions, e.g. root privileges). */#define SCHEDULE_POLICY     SCHED_OTHER/* our upper create limit, to ensure we don't blow the system */#define MAX_SYS_THREADS     _POSIX_THREAD_THREADS_MAX - 1/* our upper limit for cached threads (0 = no caching at all) */#define MAX_CACHED_THREADS  MAX_SYS_THREADS - 3/* * Now it starts to get hackish - we have to pick some signals * for suspend/resume (enter/exitCritSect) which don't interfere * with pthread implementations. Note that we can't rely on when * a suspend signal is delivered, and it's therefore not safe * to mulitplex a sinle signal for both suspend & resume purposes */#if !defined(__SIGRTMIN) || (__SIGRTMAX - __SIGRTMIN < 3)#define          SIG_SUSPEND   SIGURG#define          SIG_RESUME    SIGTSTP#define          SIG_DUMP      SIGXCPU/* * Sneak these signal in from the thread library. */#define		 PSIG_RESTART	SIGUSR1#define		 PSIG_CANCEL	SIGUSR2#else#define          SIG_SUSPEND   SIGUSR1#define          SIG_RESUME    SIGUSR2#define          SIG_DUMP      SIGXCPU/* * Sneak these signal in from the thread library. */#define		 PSIG_RESTART	(__SIGRTMIN)#define		 PSIG_CANCEL	(__SIGRTMIN+1)#endif/*********************************************************************** * global data *//* We keep a list of all active threads, so that we can enumerate them */nativeThread     *activeThreads;/* We don't throw away threads when their user func terminates, but suspend * and cache them for later re-use */nativeThread     *cache;/* The notorious first thread, which has to be handled differently because * it isn't created explicitly */nativeThread     *firstThread;/* Number of active non-daemon threads (the last terminating nonDaemon * causes the process to shut down */int              nonDaemons;/* Number of system threads (either running (activeThreads) or * blocked (cache). We need this to implement our own barrier, since * many kernel thread systems don't behave graceful on exceeding their limit */int              nSysThreads;/* number of currently cached threads */int              nCached;/* map the Java priority levels to whatever the pthreads impl gives us */int              priorities[java_lang_Thread_MAX_PRIORITY];/* thread-specific-data key to retrieve 'nativeData' */pthread_key_t    ntKey;/* our lock to protect list manipulation/iteration */static iLock*    tLock;/* a hint to avoid unnecessary pthread_creates (with pending exits) */volatile int     pendingExits;/* level of critical sections (0 = none) */int              critSection;/* helper semaphore to signal completion of critical section enter/exit */sem_t            critSem;sigset_t         suspendSet;/* an optional deadlock watchdog thread (not in the activeThread list), * activated by DEBUG topic vm_thread */pthread_t        deadlockWatchdog;void suspend_signal_handler ( int sig );void resume_signal_handler ( int sig );static void tDispose ( nativeThread* nt );static void* (*thread_malloc)(size_t);static void (*thread_free)(void*);extern void nullException(int);#define LOCKSLOT  int iLockRoot#define TLOCK(_nt) do {            \  (_nt)->blockState |= BS_THREAD;  \  lockStaticMutex(&tLock);         \} while (0)#define TUNLOCK(_nt) do {          \  unlockStaticMutex(&tLock);       \  (_nt)->blockState &= ~BS_THREAD; \} while (0)/*********************************************************************** * internal functions *//* * On demand debug signal to dump the current thread state(s) (requested * by a external "kill -s <SIG_DUMP> <proc-id>" */voiddump_signal_handler ( int sig ){  tDump();}/* * dump a thread list, marking the supposed to be current thread */voidtDumpList ( nativeThread *cur, nativeThread* list ){  int             i;  char            a1, a2, a3;  nativeThread    *t;  for ( t=list, i=0; t; t=t->next, i++ ){	/* the supposed to be current thread? */	a1 = (t == cur) ? '*' : ' ';	/* the current thread from a stack point-of view? */	a2 = (((uintp)&i > (uintp)t->stackMin) &&		  ((uintp)&i < (uintp)t->stackMax)) ? 'S' : ' ';	/* the first one? */	a3 = (t == firstThread) ? '1' : ' ';	DBG( vm_thread, ("%4d: %c%c%c %c%c%c   %p [tid: %4d, java: %p]  "					 "stack: [%p..%p..%p]\n",					 i, a1, a2, a3,					 stat_act[t->active], stat_susp[t->suspendState], stat_block[t->blockState],					 t, t->tid, t->thread,					 t->stackMin, t->stackCur, t->stackMax));  }}/* * dump the state of the threading system */voidtDump (void){  DBG_ACTION( vm_thread, {	nativeThread     *cur = pthread_getspecific( ntKey);	void             *lock   = tLock;	void             *holder = tLock->holder;	void             *mux    = tLock->mux;	void             *muxNat = tLock->mux ? unhand(tLock->mux)->PrivateInfo : 0;	void             *cv     = tLock->cv;	void             *cvNat  = tLock->cv ? unhand(tLock->cv)->PrivateInfo : 0;	TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */	DBG( vm_thread,("\n======================== thread dump =========================\n"));	DBG( vm_thread, ("state:  nonDaemons: %d, critSection: %d\n",					 nonDaemons, critSection));	DBG( vm_thread, ("tLock:       %p [holder: %p, mux: %p (native: %p), cv: %p (native: %p)]\n",					 lock, holder, mux, muxNat, cv, cvNat));	DBG( vm_thread, ("active threads:\n"));	tDumpList( cur, activeThreads);	DBG( vm_thread, ("\ncached threads:\n"));	tDumpList( cur, cache);	DBG( vm_thread, ("====================== end thread dump =======================\n"));	TUNLOCK( cur); /* ------------------------------------------------------ tLock */  });}staticvoid*tWatchdogRun (void* p){  nativeThread *t;  int life;  while ( nonDaemons ) {	life = 0;	for ( t=activeThreads; t != NULL; t = t->next ){	  /*	   * if we have a single thread that is not blocked at all, is in a	   * timeout wait, and is not suspended, we are still safe (even though	   * the timeout value might effectively be a deadlock)	   */	  if ( (!t->blockState || (t->blockState == BS_CV_TO)) && !t->suspendState ){		life = 1;		break;	  }	}	if ( !life ) {	  DBG( vm_thread, ("deadlock\n"));	  tDump();	  ABORT();	}	usleep( 5000);  }  return 0;}voidtStartDeadlockWatchdog (void){  pthread_attr_t attr;  struct sched_param sp;  sp.sched_priority = priorities[0];  /* looow */  pthread_attr_init( &attr);  pthread_attr_setschedparam( &attr, &sp);  pthread_attr_setstacksize( &attr, 4096);  pthread_create( &deadlockWatchdog, &attr, tWatchdogRun, 0);}/*********************************************************************** * thread system initialization *//* * static init of signal handlers */voidtInitSignalHandlers (void){  struct sigaction sigSuspend, sigResume, sigSegv, sigDump;  unsigned int flags = 0;#if defined(SA_RESTART)  flags |= SA_RESTART;#endif  sigSuspend.sa_flags = flags;  sigSuspend.sa_handler = suspend_signal_handler;  sigemptyset( &sigSuspend.sa_mask);  sigaddset( &sigSuspend.sa_mask, SIG_SUSPEND);  sigaddset( &sigSuspend.sa_mask, SIG_RESUME);  sigaddset( &sigSuspend.sa_mask, PSIG_RESTART);  sigaddset( &sigSuspend.sa_mask, PSIG_CANCEL);  sigaddset( &sigSuspend.sa_mask, SIGSTOP);  sigaddset( &sigSuspend.sa_mask, SIGCONT);  sigaddset( &sigSuspend.sa_mask, SIGWINCH);  sigaction( SIG_SUSPEND, &sigSuspend, NULL);  sigResume.sa_flags = flags;  sigResume.sa_handler = resume_signal_handler;  sigResume.sa_mask = sigSuspend.sa_mask;  sigaction( SIG_RESUME, &sigResume, NULL);#if defined(SIG_DUMP)  sigDump.sa_flags = flags;  sigDump.sa_handler = dump_signal_handler;  sigemptyset( &sigDump.sa_mask);  sigaction( SIG_DUMP, &sigDump, NULL);#endif  sigSegv.sa_flags = flags;#if defined(SA_SIGINFO)  sigSegv.sa_flags |= SA_SIGINFO;#endif#if defined(SA_NOMASK)  sigSegv.sa_flags |= SA_NOMASK;#endif  sigSegv.sa_handler = (void(*)(int)) nullException;  sigemptyset( &sigSegv.sa_mask);  sigaction( SIGSEGV, &sigSegv, NULL);}/* * static init set up of Java-to-pthread priority mapping (pthread prioritiy levels * are implementation dependent) */staticvoidtMapPriorities (void){  int     d, min, max, n, i;  float   r;  min = sched_get_priority_min( SCHEDULE_POLICY);  max = sched_get_priority_max( SCHEDULE_POLICY);  d = max - min;  n = sizeof(priorities) / sizeof(priorities[0]);  r = (float)d / (float)n;  for ( i=0; i<n; i++ ) {	priorities[i] = (int)(i*r + 0.5) + min;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -