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

📄 bjthread.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
 */void jthread_enable_stop(void){	jthread_t currentJThread = GET_JTHREAD();	if (NULL != currentJThread) {		atomic_or(&currentJThread->stop_allowed, 1);		if (currentJThread->stop_pending) {			currentJThread->status = THREAD_DYING;			onstop();			jthread_exit();		}	}}/* * interrupt a thread */voidjthread_interrupt(jthread_t tid){	thread_info tinfo;	DBG(JTHREAD, dprintf("interrupting thread %p, %s\n",		tid, THREAD_NAME(tid));)	if (THREAD_DYING != tid->status && THREAD_DEAD != tid->status) {		get_thread_info(tid->native_thread, &tinfo);		if (B_THREAD_SUSPENDED != tinfo.state &&		    B_THREAD_RUNNING != tinfo.state) {			/*			 * This thread is asleep, waiting on I/O or			 * blocked on a semaphore, so resume_thread won't			 * work without a preceding suspend_thread, and			 * since these amount to signalling the targeted			 * thread, we need to snooze a bit, as described			 * in the Be Book section on the "snooze" function.			 */			suspend_thread(tid->native_thread);			snooze(1000);   /* microseconds */		}		/*		 * At this point, the targeted thread is either already		 * running, or is in a resumable state.		 */		resume_thread(tid->native_thread);	}}/* * cleanup handler for a given thread.  This handler is called when that * thread is killed (i.e., when it receives a STOP_SIGNAL). */static voiddeathcallback(int sig){	jthread_t currentJThread = GET_JTHREAD();	atomic_or(&currentJThread->stop_pending, 1);	if (0 == atomic_or(&currentJThread->stop_allowed, 0)) {		DBG(JTHREAD, dprintf("%s rejects the STOP request",			THREAD_NAME(currentJThread));)		return;	}	currentJThread->status = THREAD_DYING;	onstop();	mark_thread_dead();	/* by returning, we proceed with the STOP and exit that thread */}/* * start function for each thread.   * This function install the cleanup handler, sets jthread-specific  * data and calls the actual work function. */int32start_me_up(void *arg){	jthread_t   tid = (jthread_t)arg;	thread_info tinfo;	extern void initExceptions(void);	DBG(JTHREAD, dprintf("start_me_up: setting up for %s\n",		THREAD_NAME(tid));)	acquire_sem(threadLock);	/* GROSS HACK ALERT -- On R4, child threads don't inherit the	 * spawning thread's signal handlers!	 */	initExceptions();   /* from ../../exceptions.c */	/* END OF GROSS HACK	 */	signal(STOP_SIGNAL, deathcallback);	tid->stop_allowed = 1;	tid->stop_pending = 0;	/*	 * Determine the top and bottom addrs of this thread's stack	 */	get_thread_info(tid->native_thread, &tinfo);	tid->stack_top = tinfo.stack_end;	tid->stack_bottom = tinfo.stack_base;	SET_JTHREAD(tid);	SET_COOKIE(tid->jlThread);        tid->status = THREAD_RUNNING;	release_sem(threadLock);	DBG(JTHREAD, dprintf("start_me_up: calling t-func for %s\n",		THREAD_NAME(tid));)	tid->func(tid->jlThread);	DBG(JTHREAD, dprintf("start_me_up: thread %s returned\n", 		THREAD_NAME(tid));)	assert (tid->status != THREAD_DYING);	mark_thread_dead();	/* by returning, we exit this thread */	return (0);}/* * create a new jthread */jthread_tjthread_create(unsigned int pri, void (*func)(void *), int daemon,        void *jlThread, size_t threadStackSize){	thread_id ntid;	jthread_t tid;	/* 	 * Note that we create the thread in a joinable state, which is the	 * default.  Our finalizer will join the threads, allowing the	 * thread system to free its resources.	 */        tid = allocator(sizeof(*tid));        assert(tid != 0);	acquire_sem(threadLock);        tid->jlThread = jlThread;        tid->func = func;        tid->nextlive = liveThreads;        liveThreads = tid;        tid->status = THREAD_NEWBORN;	ntid = spawn_thread(start_me_up, nameThread(jlThread),				map_Java_priority(pri), tid);	tid->native_thread = ntid;        talive++;               if ((tid->daemon = daemon) != 0) {                tdaemon++;        }	release_sem(threadLock);	/* Check if we can safely save the per-thread info for	 * this thread.  Yes, I know the per-thread stuff is lame,	 * but let's get this working first, shall we?	 */	if (NULL == per_thread_info[ntid % MAX_THREADS].jtid) {		DBG(JTHREAD, dprintf("created thread %s, daemon=%d\n",			nameThread(jlThread), daemon);)		resume_thread(ntid);        	return (tid);	}	else {		DBG(JTHREAD, dprintf("can't create thread: "			"per-thread info table too small\n");)		kill_thread(ntid);   /* stillborn */		deallocator(tid);		return NULL;	}}/*============================================================================ * * Functions that are part of the user interface * *//*       * sleep for time milliseconds */     voidjthread_sleep(jlong time){	DBG(JTHREAD, dprintf("thread %s: sleeping for %g second(s)...",                THREAD_NAME(GET_JTHREAD()), (double)time/1000.0);)	/* snooze_until takes an arg in usecs */	snooze_until(system_time() + (time*1000L), B_SYSTEM_TIMEBASE);	DBG(JTHREAD, dprintf("OK, I'm awake!\n");)}/*  * Check whether a thread is alive. * * Note that threads executing their cleanup function are not (jthread-) alive. * (they're set to THREAD_DEAD) */intjthread_alive(jthread_t tid){	return tid && (tid->status == THREAD_NEWBORN || 		       tid->status == THREAD_RUNNING);}/* * Change thread priority. */voidjthread_setpriority(jthread_t jtid, int prio){	set_thread_priority(jtid->native_thread, map_Java_priority(prio));}/* * Stop a thread in its tracks. */voidjthread_stop(jthread_t jtid){	/* can I cancel myself safely??? */	/* NB: jthread_stop should never be invoked on the current thread */	DBG(JTHREAD, dprintf("stopping %s...\n", THREAD_NAME(jtid));)	send_signal(jtid->native_thread, STOP_SIGNAL);}static voidremove_thread(jthread_t tid){	jthread_t* ntid;	int found = 0;	DBG(JTHREAD, dprintf("Removing entry for thread %s\n",		THREAD_NAME(tid));)	acquire_sem(threadLock);	talive--;	if (tid->daemon) {		tdaemon--;	}	/* Remove thread from live list so it can be garbage collected */	for (ntid = &liveThreads; *ntid != 0; ntid = &(*ntid)->nextlive) 	{		if (tid == (*ntid)) {			found = 1;			(*ntid) = tid->nextlive;			break;		}	}	assert(found);	release_sem(threadLock);	/* If we only have daemons left, then we should exit. */	if (talive == tdaemon) {		/* Make sure this section doesn't get executed		 * more than once.		 */		if (isShuttingDown) {			return;		}		atomic_or(&isShuttingDown, 1);		DBG(JTHREAD, dprintf("%s: all done, closing shop\n",			THREAD_NAME(tid));)		if (runOnExit != 0) {		    runOnExit();		}		/* does that really make sense??? */		for (tid = liveThreads; tid != 0; tid = tid->nextlive) {			if (destructor1) {				(*destructor1)(tid->jlThread);			}			kill_thread(tid->native_thread);			DBG(JTHREAD, dprintf("killed %s\n", THREAD_NAME(tid));)		}		/* Shut down this thread */		DBG(JTHREAD, dprintf("%s: Goodbye!\n",			THREAD_NAME(GET_JTHREAD()));)		exit_thread(0);	} else {		if (destructor1) {			(*destructor1)(tid->jlThread);		}		/* This thread will now return to mark_thread_dead, and		 * then call exit_thread() from that function's caller.		 */	}}/* * mark the current thread as dead and remove it from the lists. */static voidmark_thread_dead(void){	jthread_t currentJThread = GET_JTHREAD();	assert (currentJThread->status != THREAD_DEAD);	currentJThread->status = THREAD_DEAD;	remove_thread(currentJThread);}/* * Have a thread exit. * Each thread exits only once. */voidjthread_exit(void){	jthread_t currentJThread = GET_JTHREAD();	DBG(JTHREAD, dprintf("jthread_exit called by %s\n",		THREAD_NAME(currentJThread));)	mark_thread_dead();	/*	 * If this is the main thread, wait for all other threads to finish.	 * At this point, the main jthread is no longer part of the	 * live list.	 */	if (the_main_thread == currentJThread->native_thread) {		while (talive > tdaemon) {	        jthread_t tid = NULL;			int32 rc;			acquire_sem(threadLock);	        for (tid = liveThreads; tid != NULL; tid = tid->nextlive) {				if (tid->daemon) break;			}			release_sem(threadLock);			if (NULL != tid) {				wait_for_thread(tid->native_thread, &rc);			}		}	}	/*	 * OK, now it's safe to exit	 */	DBG(JTHREAD, dprintf("%s: at the point of no return in jthread_exit\n",		THREAD_NAME(currentJThread));)	exit_thread(0);	while (1)		assert(!"This better not return.");}/* * Print info about a given jthread to stderr */void jthread_dumpthreadinfo(jthread_t tid){	dprintf("jthread %p native %ld status %s\n", 		tid, tid->native_thread,		tid->status == THREAD_NEWBORN ? "NEWBORN" :		tid->status == THREAD_RUNNING ? "RUNNING" :		tid->status == THREAD_DYING   ? "DYING"   :		tid->status == THREAD_DEAD    ? "DEAD"    : "???");}/* * dump info on all live threads */void/* ARGSUSED */dumpLiveThreads(int s){        jthread_t tid;        for (tid = liveThreads; tid != NULL; tid = tid->nextlive) {		jthread_dumpthreadinfo(tid);	}}/* * have main thread wait for all threads to finish */void jthread_exit_when_done(void){        while (talive > 1)		jthread_yield();	jthread_exit();}

⌨️ 快捷键说明

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