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

📄 thread-impl.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 4 页
字号:
	for ( t=activeThreads; t; t = t->next ) {	  if ( (t != cur) && (t->suspendState == 0) && (t->active) ) {		t->suspendState = SS_PENDING_SUSPEND;	  }	}#endif  }  unprotectThreadList(cur);  DBG( JTHREAD, dprintf("critical section (%d) established\n", critSection));}/** * Resume all temporarily suspended threads. Just take action if this * is the outmost exit */voidjthread_unsuspendall (void){  jthread_t	cur = jthread_current();  jthread_t	t;  if ( !jthreadInitialized || !critSection )	return;  if ( --critSection == 0 ){	  int val;	/* No need to sync, there's nobody else running. However it seems	 * we cannot use mutexes as they cause a deadlock when the world	 * is suspended.	 */	protectThreadList(cur);	repsem_getvalue(&critSem, &val);	assert(val == 0);#if !defined(KAFFE_BOEHM_GC)	for ( t=activeThreads; t; t = t->next ){	  int status;	  pthread_mutex_lock(&t->suspendLock);	  if ( (t->suspendState & (SS_PENDING_SUSPEND | SS_SUSPENDED)) != 0 )	    {	      	      DBG( JTHREAD, dprintf("signal resume: %p (sus: %d blk: %d)\n",				    t, t->suspendState, t->blockState));	      t->suspendState = SS_PENDING_RESUME;	      if ((t->blockState & (BS_SYSCALL|BS_CV|BS_CV_TO|BS_MUTEX)) == 0)		{		  DBG (JTHREADDETAIL, dprintf("  sending sigResume\n"));		  do		    {		      status = pthread_kill( t->tid, sigResume);		      if ( status )			{			  DBG( JTHREAD, dprintf("error sending RESUME signal to %p: %d\n", t, status));			}		  		      /* ack wait workaround, see jthread_suspendall remarks */		      repsem_wait( &critSem);		    }		  while (t->suspendState == SS_PENDING_RESUME);		}	      else		{		  DBG (JTHREADDETAIL, dprintf("  clearing suspendState\n"));		  t->suspendState = 0;		}	    }	  pthread_mutex_unlock(&t->suspendLock);	}#else	for ( t=activeThreads; t; t = t->next ){	  if ( t->suspendState & (SS_PENDING_SUSPEND | SS_SUSPENDED) ){		t->suspendState = 0;	  }	}	GC_enable();#endif	repsem_getvalue(&critSem, &val);	assert(val == 0);	  unprotectThreadList(cur);  }  DBG( JTHREAD, dprintf("exit crit section (%d)\n", critSection));}/******************************************************************************* * GC related stuff *//** * Walk stacks of all threads, except of the current one (doesn't * make much sense since that's the GC itself, and it's task is to * get rid of garbage, not to pin it down - besides the fact that * its stack is a moving target). * * The call chain looks like this * *  startGC *    Kaffe_ThreadInterface.GcWalkThreads == TwalkThreads *      walkMemory *        gcFunctions[..].walk == walkThread * */voidjthread_walkLiveThreads (void(*func)(jthread_t,void*), void *private){  jthread_t t;  DBG( JTHREAD, dprintf("start walking threads\n"));  for ( t = activeThreads; t != NULL; t = t->next) {	func(t, private);  }  DBG( JTHREAD, dprintf("end walking threads\n"));}voidjthread_walkLiveThreads_r (void(*func)(jthread_t, void *), void *private){  jthread_t cur = jthread_current();  protectThreadList(cur);  jthread_walkLiveThreads (func, private);  unprotectThreadList(cur);}intjthread_is_blocking (int fd){  int r;   r = fcntl(fd, F_GETFL, 0);  if (r < 0) {    perror("fcntl(F_GETFL)");    return 0;  }		    return (r & O_NONBLOCK) != 0;}voidjthread_set_blocking (int fd, int blocking){  int r;  /* This code has been copied from jthreadedFileDescriptor in     unix-jthreads/jthread.c  */  if (!blocking) {    /* Make non-blocking */    if ((r = fcntl(fd, F_GETFL, 0)) < 0) {      perror("F_GETFL");      return;    }        /*     * Apparently, this can fail, for instance when we stdout is      * redirected to /dev/null. (On FreeBSD)     */    fcntl(fd, F_SETFL, r | O_NONBLOCK #if defined(O_ASYNC)	  | O_ASYNC#elif defined(FASYNC)	  | FASYNC#endif	  );  } else {    /* clear nonblocking flag */    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);  }}/* * Get the current stack limit. * Adapted from kaffe/kaffevm/systems/unix-jthreads/jthread.h *//** * This function increments the pointer stored in "p" by "inc" bytes. *  * @param p Pointer to be incremented. * @param inc Amount of bytes to increment the pointer. */static inline void incrPointer(void **p, int inc){  *p = (void *)((uintp)*p + inc);}/** * This function is meant to relax stack boundaries so the virtual machine * may execute some task before the final abort. * * @param yes If it is true, it relaxes the boundaries. If false, it shortens * the stack. */void jthread_relaxstack(int yes){  if( yes )    {#if defined(STACK_GROWS_UP)      incrPointer(&jthread_current()->stackMax, STACKREDZONE);#else      incrPointer(&jthread_current()->stackMin, -STACKREDZONE);#endif    }  else    {#if defined(STACK_GROWS_UP)      incrPointer(&jthread_current()->stackMax, -STACKREDZONE);#else      incrPointer(&jthread_current()->stackMin, STACKREDZONE);#endif    }}/** * Test whether an address is on the stack of the calling thread. * * @param p the address to check * * @return true if address is on the stack * * Needed for locking and for exception handling. */bool jthread_on_current_stack(void* p){  jthread_t nt = jthread_current();DBG(JTHREADDETAIL, dprintf("on current stack: base=%p size=%ld bp=%p",                        nt->stackMin,                        (long)((char *)nt->stackMax - (char *)nt->stackMin),                        p); );  if (nt == 0 || (p > nt->stackMin && p < nt->stackMax)) {DBG(JTHREADDETAIL, dprintf(" yes\n"); );        return (true);  }  else {DBG(JTHREADDETAIL, dprintf(" no\n"); );        return (false);  }}/** * Lock a mutex which will be used for critical sections when entering * non-reentrant system code, for example. * * @param dummy unused pointer */void jthread_spinon(void *dummy UNUSED){  pthread_mutex_lock(&systemMutex);}/** * Unock a mutex used for critical sections when entering non-reentrant system * code. * * @param dummy unused pointer */void jthread_spinoff(void *dummy UNUSED){  pthread_mutex_unlock(&systemMutex);}/** * Sets a function to be run when all non-daemon threads have exited. * * @param func the function to be called when exiting. */void jthread_atexit(void (* func)(void)){  runOnExit = func;}int KaffePThread_getSuspendSignal(void){  return sigSuspend;}/** * Extract the range of the stack that's in use. *  * @param tid the thread whose stack is to be examined * @param from storage for the address of the start address * @param len storage for the size of the used range * * @return true if successful, otherwise false * * Needed by the garbage collector. */bool jthread_extract_stack(jthread_t tid, void** from, unsigned* len){  if (tid->active == 0) {    return false;  }  assert(tid->suspendState == SS_SUSPENDED);#if defined(STACK_GROWS_UP)  *from = tid->stackMin;  *len = (uintp)tid->stackCur - (uintp)tid->stackMin;#else  *from = tid->stackCur;  *len = (uintp)tid->stackMax - (uintp)tid->stackCur;#endif  return true;}/** * Returns the current native thread. * */jthread_t jthread_current(void)      {  if (!jthreadInitialized)    return NULL;  else {    void* specific = pthread_getspecific(ntKey);    if (specific != NULL)      return (jthread_t) specific;    else {      perror(NULL);      abort();   }  }}/** * Disable stopping the calling thread. * * Needed to avoid stopping a thread while it holds a lock. */void jthread_disable_stop(void){}/** * Enable stopping the calling thread. * * Needed to avoid stopping a thread while it holds a lock. */void jthread_enable_stop(void){}/**  * Stop a thread. *  * @param tid the thread to stop. */void jthread_stop(jthread_t tid UNUSED){}/** * Dump some information about a thread to stderr. * * @param tid the thread whose info is to be dumped. */void jthread_dumpthreadinfo(jthread_t tid UNUSED){}/** * Return the java.lang.Thread instance attached to a thread * * @param tid the native thread whose corresponding java thread *            is to be returned. * @return the java.lang.Thread instance. */threadData *jthread_get_data(jthread_t tid){        return (&tid->data);}/** * Check for room on stack. * * @param left number of bytes that are needed * * @return true if @left bytes are free, otherwise false  * * Needed by intrp in order to implement stack overflow checking. */bool jthread_stackcheck(int left){	int rc;#if defined(STACK_GROWS_UP)        rc = jthread_on_current_stack((char*)&rc + left);#else        rc = jthread_on_current_stack((char*)&rc - left);#endif	return (rc);}/** * Returns the upper bound of the stack of the calling thread. * * Needed by support.c in order to implement stack overflow checking.  */void* jthread_stacklimit(void){  jthread_t nt = jthread_current();#if defined(STACK_GROWS_UP)  return (void *)((uintp)nt->stackMax - STACKREDZONE);#else  return (void *)((uintp)nt->stackMin + STACKREDZONE);#endif}int jthread_on_condvar(jthread_t jt){	return (jt->blockState & (BS_CV|BS_CV_TO)) != 0;}int jthread_on_mutex(jthread_t jt){	return (jt->blockState & (BS_MUTEX)) != 0;}int jthread_get_status(jthread_t jt){  if (jt->status == THREAD_KILL)    return THREAD_DEAD;  return jt->status;}int jthread_has_run(jthread_t jt UNUSED){  return 1;}void jthread_clear_run(jthread_t jt UNUSED){}void jthread_suspend(jthread_t jt UNUSED, void *suspender UNUSED){	/* TODO */}void jthread_resume(jthread_t jt UNUSED, void *suspender UNUSED){	/* TODO */}jthread_t jthread_from_data(threadData *td, void *suspender UNUSED){  jthread_t cur = jthread_current();  jthread_t iterator;  protectThreadList(cur);  iterator = activeThreads;  while (iterator != NULL)    {      if (td == &iterator->data)	{	  unprotectThreadList(cur);	  /* Thread handles are garbage collected so the stack is protecting	   * us.	   */	  return iterator;	}      iterator = iterator->next;    }  unprotectThreadList(cur);  return NULL;}jlong jthread_get_usage(jthread_t jt UNUSED){	/* TODO */	return 0;}

⌨️ 快捷键说明

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