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

📄 bjthread.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1998 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 BeOS native threads and * was derived from oskit-pthreads/pjthread.c. * * Please address BeOS-related questions to alanlb@vt.edu. */#include "debug.h"#include "jthread.h"#include <sys/wait.h>#include <sys/time.h>#include <signal.h>/* thread status */#define THREAD_NEWBORN                	0#define THREAD_RUNNING                  1#define THREAD_DYING                    2#define THREAD_DEAD                     3/* * We use this as a stop signal instead of SIGSTOP, because an apparent * bug in R4 prevents a custom SIGSTOP handler from ever being called. */#define STOP_SIGNAL			SIGUSR2/* * 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);		/* run when all non-daemons die */static struct jthread* liveThreads;	/* list of all live threads */static sem_id threadLock;		/* static lock to protect liveThreads */static int map_Java_priority(int jprio);static void remove_thread(jthread_t tid);static void mark_thread_dead(void);void dumpLiveThreads(int);static void deathcallback(int sig);	/* runs when STOPped and stop is OK *//* * the following variables are set by jthread_init, and show how the * threading system is parameterized. */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 *//* * This is used to track the id of the main thread, so that we can * prevent it from exiting while there are daemon threads still * running.  otherwise, the environ ptr would become invalid, and * any remaining non-daemon thread that called getenv() either directly * or indirectly via, say, gethostbyname(), would fail with a * NullPointerException. * * This scenario revealed itself with the UDPTest program in the * regression suite. */static thread_id		the_main_thread;/* * This is where the cookies are kept */per_thread_info_t*		per_thread_info;static area_id			pti_area;/* * This is used to prevent multiple STOP_SIGNALs from being sent to the * daemon threads during final shutdown. */static int32			isShuttingDown = 0;/* * Helpers */#define THREAD_NAME(jtid)	nameThread(jtid->jlThread)/*============================================================================ * * Functions related to interrupt handling * *//* * Suspend all threads */void jthread_suspendall(void){	/* Unimplemented */}/* * Unsuspend all threads */voidjthread_unsuspendall(void){	/* Unimplemented */}/* * acquire spinlock */void jthread_spinon(void *arg){	int32* lock = arg;	int32  prev;	if (NULL != lock) {		do {			prev = atomic_or(lock, 1);		} while (1 == prev);	}}/* * release spinlock */void jthread_spinoff(void *arg){	int32* lock = arg;	if (NULL != lock) {		atomic_and(lock, 0);	}}/*============================================================================ * * Functions related to the stack * *//* * determine the interesting stack range for a conservative gc */intjthread_extract_stack(jthread_t jtid, void **from, unsigned *len){	if (NULL == jtid) {		return(0);	}	*from = jtid->stack_bottom;	*len = jtid->stack_top - jtid->stack_bottom;	return(1);}/* * determine whether an address lies on your current stack frame */intjthread_on_current_stack(void *bp){	int dummy = 0;	jthread_t currentJThread = GET_JTHREAD();	return(bp >= (void*)&dummy && bp < currentJThread->stack_top);}       /* * See if there is enough room on the stack. */intjthread_stackcheck(int need){	int dummy = 0;	if (0 == need) {		return(1);	}	else {		jthread_t currentJThread = GET_JTHREAD();		return(((void*)&dummy - currentJThread->stack_bottom) >= need);	}}/*============================================================================ * * Functions dealing with thread contexts and the garbage collection interface * *//* * free a thread context */void    jthread_destroy(jthread_t tid){	status_t status;	assert(tid);	DBG(JTHREAD, dprintf("destroying %s\n", THREAD_NAME(tid));)	atomic_and(&tid->stop_allowed, 0);	wait_for_thread(tid->native_thread, &status);	atomic_or(&tid->stop_allowed, 1);	deallocator(tid);}/* * find a native BeOS thread's cookie * (Maps BeOS threads 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;	acquire_sem(threadLock);        for (tid = liveThreads; tid != NULL; tid = tid->nextlive) {                func(tid->jlThread);        }	release_sem(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 * */static intmap_Java_priority(int prio){	double range = max_priority - min_priority;	double diff = prio - min_priority;	if (0 == range) {		return(B_NORMAL_PRIORITY);	}	else {		return(B_LOW_PRIORITY +			(double)(B_URGENT_DISPLAY_PRIORITY-B_LOW_PRIORITY) *				(diff / range));	}}/* * Initialize the threading system. */jthread_t jthread_init(	int preemptive,	int maxpr,	int minpr,	void *(*_allocator)(size_t), 	void (*_deallocator)(void*),	void (*_destructor1)(void*),	void (*_onstop)(void),	void (*_ondeadlock)(void))		/* ignored for now */{	thread_id	pmain;	jthread_t	jtid;	void*		pti_addr;	thread_info	tinfo;	max_priority = maxpr;	min_priority = minpr;	allocator = _allocator;	deallocator = _deallocator;	onstop = _onstop;	destructor1 = _destructor1;	/*	 * Prepare the area used for the cookies, etc.	 */	pti_area = create_area("Kaffe cookies", &pti_addr,			B_ANY_ADDRESS, PTI_AREA_SIZE,			B_LAZY_LOCK, B_READ_AREA|B_WRITE_AREA);	assert(pti_area >= B_OK);	memset(pti_addr, PTI_AREA_SIZE, 0);	per_thread_info = (per_thread_info_t*)pti_addr;	threadLock = create_sem(1, "Kaffe threadLock");	pmain = find_thread(NULL);	rename_thread(pmain, "Kaffe main thread");	/*	 * Record the id of the main thread, for use by jthread_exit	 */	the_main_thread = pmain;        jtid = allocator(sizeof (*jtid));        SET_JTHREAD(jtid);	jtid->native_thread = pmain;	/*	 * Determine the top and bottom addrs of this thread's stack	 */	get_thread_info(pmain, &tinfo);	jtid->stack_top = tinfo.stack_end;	jtid->stack_bottom = tinfo.stack_base;	/*	 * In case of unnatural death (induced by receiving a STOP_SIGNAL),	 * we install the appropriate signal handler.	 */	signal(STOP_SIGNAL, deathcallback);	jtid->stop_allowed = 1;	jtid->stop_pending = 0;        jtid->nextlive = liveThreads;        liveThreads = jtid;	jtid->status = THREAD_RUNNING;        talive++;	DBG(JTHREAD, dprintf("main thread has id %x\n", jtid->native_thread);)	return (jtid);}/* * Create the first thread - actually bind the first thread to the java * context. */jthread_tjthread_createfirst(size_t mainThreadStackSize, 		    unsigned char prio, 		    void* jlThread){        jthread_t jtid; 	jtid = GET_JTHREAD();	assert(jtid != NULL);	assert(jtid->native_thread != 0);	assert(jtid->status == THREAD_RUNNING);	jtid->jlThread = jlThread;	SET_COOKIE(jtid->jlThread);	signal(STOP_SIGNAL, deathcallback);	jtid->stop_allowed = 1;	jtid->stop_pending = 0;	jthread_setpriority(jtid, prio);	rename_thread(jtid->native_thread, "Kaffe main thread");	return (jtid);}/* * set a function to be run when all non-daemon threads have exited */voidjthread_atexit(void (*f)(void)){	runOnExit = f;}/* * disallow cancellation */void jthread_disable_stop(void){	jthread_t currentJThread = GET_JTHREAD();	if (NULL != currentJThread) {		atomic_and(&currentJThread->stop_allowed, 0);	}}/* * reallow cancellation and stop if cancellation pending

⌨️ 快捷键说明

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