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

📄 pjthread.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1998-2000 The University of Utah. * All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. * * Contributed by the Flux Research Group at the University of Utah. * Authors: Godmar Back, Leigh Stoller *//* * This file implements jthreads on top of OSKit pthreads. */#include "debug.h"#include "jthread.h"#include <sys/wait.h>#include <sys/time.h>#include <oskit/dev/dev.h>#include <signal.h>#ifdef CPU_INHERIT#include <jcpuinherit.h>#endif/* thread status */#define THREAD_NEWBORN                	0#define THREAD_RUNNING                  1#define THREAD_DYING                    2#define THREAD_DEAD                     3#define THREAD_STOPPED                  4 /* XXX only used in status dump! */#define THREAD_CONTINUE                 5 /* XXX only used in status dump! */#define THREAD_FLAG_DONTSTOP			1/* * Variables. * These should be kept static to ensure encapsulation. */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 */static struct jthread* liveThreads;	/* list of all live threads *//* static lock to protect liveThreads etc. */static pthread_mutex_t threadLock;static void remove_thread(jthread_t tid);static void mark_thread_dead(void);void dumpLiveThreads(int);/* * the following variables are set by jthread_init, and show how the * threading system is parametrized. */static void *(*allocator)(size_t); 	/* malloc */static void (*deallocator)(void*);	/* free */static void (*destructor1)(void*);	/* call when a thread exits */static void (*onstop)(void);		/* call when a thread is stopped */static int  max_priority;		/* maximum supported priority */static int  min_priority;		/* minimum supported priority */pthread_key_t	cookie_key;	/* key to map pthread -> Hjava_lang_Thread */pthread_key_t	jthread_key;	/* key to map pthread -> jthread *//* * Function declarations. *//*============================================================================ * * Functions related to interrupt handling * *//* * Handle the stop signal to effect a Thread.stop().  This handler is * called when that thread is killed. */static voidcatch_death(void){	jthread_t tid = GET_JTHREAD();	if (!(tid->flags & THREAD_FLAG_DONTSTOP)) {		onstop();		jthread_exit();	} else {		/* try {} catch(Error e) may save a dying thread.		 * We only mark a thread as dying between catching the		 * signal and calling the onstop handler		 */		tid->status = THREAD_DYING;	}}static void catch_int(void){    /* do nothing, we will get a spurious wakeup out of cond_wait or       sleep, and the java code will magically throw       InterruptedException */}#if !defined(SMP)/* * On the uniprocessor OSKit, stopping all threads as well as acquiring * a spinlock means to simply disable interrupts.  Simple enough. *//* * disable interrupts */void jthread_suspendall(void){	osenv_intr_disable();}/* * restore interrupts */voidjthread_unsuspendall(void){	osenv_intr_enable();}void /* ARGSUSED */jthread_spinon(void *arg){	osenv_intr_disable();}void /* ARGSUSED */jthread_spinoff(void *arg){	osenv_intr_enable();}#else /* SMP *//* * On the SMP OSKit, spinlocks will be spinlocks and Leigh will invent * a way to stop all processors */#error Not yet.#endif/* * These functions use the OSKit specific "pthread_getstate" extension * to obtain the current stack location & stack pointer. *//* * determine the interesting stack range for a conservative gc */intjthread_extract_stack(jthread_t jtid, void **from, unsigned *len){	struct pthread_state ps;	/*	 * Newborn/dead threads don't have a useful stack, and may not	 * have a native_thread.	 */	if ((jtid->status == THREAD_NEWBORN)	    || (jtid->status == THREAD_DEAD))		return 0;	if (oskit_pthread_getstate(jtid->native_thread, &ps)) {		 panic("jthread_extract_stack: oskit_pthread_getstate failed for jtid(%p)\n",		       jtid);	}	#if defined(STACK_GROWS_UP)#error FIXME#else	*from = (void *)ps.stackptr;	*len = ps.stackbase + ps.stacksize - ps.stackptr;	if (*len < 0 || *len > (256*1024)) {	    panic("(%d) oskit_pthread_getstate(%d) reported obscene numbers: "		  "base = 0x%x, sp = 0x%x\n", 		  pthread_self(),		  jtid->native_thread,		  ps.stackbase, ps.stackptr);	    exit(-1);	}#endifDBG(JTHREAD,	dprintf("extract_stack(%) base=%p size=%d sp=%p; from=%p len=%d\n", 		jtid->native_thread,		ps.stackbase, ps.stacksize, ps.stackptr, *from, *len);    )	return (1);}/* * determine whether an address lies on your current stack frame */intjthread_on_current_stack(void *bp){	struct pthread_state ps;	int rc;	rc = oskit_pthread_getstate(pthread_self(), &ps);	if (rc != 0)	{		panic("jthread_on_current_stack: oskit_pthread_getstate(pid %d) failed (rc=%#x)",		      pthread_self(), rc);	}        rc = (uint32)bp >= ps.stackbase && 	     (uint32)bp < ps.stackbase + ps.stacksize;DBG(JTHREAD,	dprintf("on current stack(%d) base=%p size=%d bp=%p %s\n",		pthread_self(),		ps.stackbase, ps.stacksize, bp, (rc ? "yes" : "no"));    )	return rc;}       /* * See if there is enough room on the stack. */intjthread_stackcheck(int need){	struct pthread_state ps;	int room;	pthread_t tid = pthread_self();	if (oskit_pthread_getstate(tid, &ps))		panic("jthread_stackcheck: oskit_pthread_getstate(%d)",		      (int)tid);	#if defined(STACK_GROWS_UP)#	error FIXME#else	room = (ps.stackptr - ps.stackbase);#endif	DBG(JTHREAD,	dprintf("stackcheck(%d) need=%d base=%p size=%d sp=%p room=%d\n",		(int)pthread_self(),		need, ps.stackbase, ps.stacksize, ps.stackptr, room);    )	return (room >= need);}/*============================================================================ * * Functions dealing with thread contexts and the garbage collection interface * *//* * free a thread context */void    jthread_destroy(jthread_t tid){	void *status;	assert(tid);DBG(JTHREAD, 	dprintf("destroying tid %d\n", tid->native_thread);	    )#ifdef newer_than_990722	/* We can't use join here because of a bug in main thread	 * initialization.  See the comment in jthread_exit.  This	 * doesn't need to be synchronous anyway?	 */	jthread_disable_stop();	pthread_join(tid->native_thread, &status);	jthread_enable_stop();#endif	deallocator(tid);}/* * find a native pthread's cookie * (Maps pthreads to java.lang.Threads) */void* jthread_getcookie(void* ntid){	struct jthread* tid;        for (tid = liveThreads; tid != NULL; tid = tid->nextlive) {		if ((void*)tid->native_thread == ntid) {			return (tid->jlThread);		}	}	return (0);}/* * iterate over all live threads */voidjthread_walkLiveThreads(void (*func)(void *jlThread)){        jthread_t tid;	pthread_mutex_lock(&threadLock);        for (tid = liveThreads; tid != NULL; tid = tid->nextlive) {                func(tid->jlThread);        }	pthread_mutex_unlock(&threadLock);}/*  * XXX this is supposed to count the number of stack frames  */intjthread_frames(jthread_t thrd){        return 0;}/*============================================================================ * * Functions for initialization and thread creation * *//* * Initialize the threading system. * * XXX: pthread_init() has already been called. */jthread_t jthread_init(int pre,	int maxpr, int minpr,	void *(*_allocator)(size_t), 	void (*_deallocator)(void*),	void (*_destructor1)(void*),	void (*_onstop)(void),	void (*_ondeadlock)(void))		/* ignored for now */{	pthread_t	pmain;	jthread_t	jtid;	struct sigaction act;	max_priority = maxpr;	min_priority = minpr;	allocator = _allocator;	deallocator = _deallocator;	onstop = _onstop;	destructor1 = _destructor1;	pmain = pthread_self();	/* establish SIG_STOP handler */	act.sa_handler = (void *)catch_death;	act.sa_flags = 0;	sigemptyset(&act.sa_mask);	sigaddset(&act.sa_mask, SIG_STOP);	sigaction(SIG_STOP, &act, 0);	act.sa_handler = (void *)catch_int;	act.sa_flags = 0;	sigemptyset(&act.sa_mask);	sigaddset(&act.sa_mask, SIG_INT);	sigaction(SIG_INT, &act, 0);	        /*         * XXX: ignore mapping of min/max priority for now and assume         * pthread priorities include java priorities.         */        pthread_key_create(&jthread_key, 0 /* destructor */);        pthread_key_create(&cookie_key, 0 /* destructor */);	pthread_mutex_init(&threadLock, (const pthread_mutexattr_t *)0);        jtid = allocator(sizeof (*jtid));        SET_JTHREAD(jtid);	jtid->native_thread = pmain;        jtid->nextlive = liveThreads;        liveThreads = jtid;	jtid->status = THREAD_RUNNING;        talive++;DBG(JTHREAD,	dprintf("main thread has id %d\n", jtid->native_thread);    )	return (jtid);}/* * Create an OSKit jthread context to go with the initial thread in the system. * (The initial thread is created in jthread_init, above. */jthread_tjthread_createfirst(size_t mainThreadStackSize, unsigned char prio, void* jlThread){        jthread_t jtid; 	jtid = GET_JTHREAD();	assert(jtid != NULL);	assert(jtid->native_thread != NULL);	assert(jtid->status == THREAD_RUNNING);	jtid->jlThread = jlThread;		/* Main thread should not yet have a jlThread associated with it. */	assert(pthread_getspecific(cookie_key) == NULL);

⌨️ 快捷键说明

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