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

📄 win32_threads.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
        GC_push_all_stack(sp, thread->stack_base);      else {        WARN("Thread stack pointer 0x%lx out of range, pushing everything\n",	     (unsigned long)sp);        GC_push_all_stack(stack_min, thread->stack_base);      }    }  }  if (!found_me) ABORT("Collecting from unknown thread.");}void GC_get_next_stack(char *start, char **lo, char **hi){    int i;#   define ADDR_LIMIT (char *)(-1L)    char * current_min = ADDR_LIMIT;    LONG my_max = GC_get_max_thread_index();      for (i = 0; i <= my_max; i++) {    	char * s = (char *)thread_table[i].stack_base;	if (0 != s && s > start && s < current_min) {	    current_min = s;	}    }    *hi = current_min;    if (current_min == ADDR_LIMIT) {    	*lo = ADDR_LIMIT;	return;    }    *lo = GC_get_stack_min(current_min);    if (*lo < start) *lo = start;}#if !defined(CYGWIN32)#if !defined(MSWINCE) && defined(GC_DLL)/* We register threads from DllMain */GC_API HANDLE WINAPI GC_CreateThread(    LPSECURITY_ATTRIBUTES lpThreadAttributes,     DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,     LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ){    return CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress,                        lpParameter, dwCreationFlags, lpThreadId);}#else /* defined(MSWINCE) || !defined(GC_DLL))  *//* We have no DllMain to take care of new threads.  Thus we	*//* must properly intercept thread creation.			*/typedef struct {    LPTHREAD_START_ROUTINE start;    LPVOID param;} thread_args;static DWORD WINAPI thread_start(LPVOID arg);GC_API HANDLE WINAPI GC_CreateThread(    LPSECURITY_ATTRIBUTES lpThreadAttributes,     DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,     LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ){    HANDLE thread_h = NULL;    thread_args *args;    if (!GC_is_initialized) GC_init();    		/* make sure GC is initialized (i.e. main thread is attached) */        args = GC_malloc_uncollectable(sizeof(thread_args)); 	/* Handed off to and deallocated by child thread.	*/    if (0 == args) {	SetLastError(ERROR_NOT_ENOUGH_MEMORY);        return NULL;    }    /* set up thread arguments */    	args -> start = lpStartAddress;    	args -> param = lpParameter;    thread_h = CreateThread(lpThreadAttributes,    			    dwStackSize, thread_start,    			    args, dwCreationFlags,    			    lpThreadId);    return thread_h;}static DWORD WINAPI thread_start(LPVOID arg){    DWORD ret = 0;    thread_args *args = (thread_args *)arg;    GC_new_thread();    /* Clear the thread entry even if we exit with an exception.	*/    /* This is probably pointless, since an uncaught exception is	*/    /* supposed to result in the process being killed.			*/#ifndef __GNUC__    __try {#endif /* __GNUC__ */	ret = args->start (args->param);#ifndef __GNUC__    } __finally {#endif /* __GNUC__ */	GC_free(args);	GC_delete_thread(GetCurrentThreadId());#ifndef __GNUC__    }#endif /* __GNUC__ */    return ret;}#endif /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))  */#endif /* !CYGWIN32 */#ifdef MSWINCEtypedef struct {    HINSTANCE hInstance;    HINSTANCE hPrevInstance;    LPWSTR lpCmdLine;    int nShowCmd;} main_thread_args;DWORD WINAPI main_thread_start(LPVOID arg);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,		   LPWSTR lpCmdLine, int nShowCmd){    DWORD exit_code = 1;    main_thread_args args = {	hInstance, hPrevInstance, lpCmdLine, nShowCmd    };    HANDLE thread_h;    DWORD thread_id;    /* initialize everything */    GC_init();    /* start the main thread */    thread_h = GC_CreateThread(	NULL, 0, main_thread_start, &args, 0, &thread_id);    if (thread_h != NULL)    {	WaitForSingleObject (thread_h, INFINITE);	GetExitCodeThread (thread_h, &exit_code);	CloseHandle (thread_h);    }    GC_deinit();    DeleteCriticalSection(&GC_allocate_ml);    return (int) exit_code;}DWORD WINAPI main_thread_start(LPVOID arg){    main_thread_args * args = (main_thread_args *) arg;    return (DWORD) GC_WinMain (args->hInstance, args->hPrevInstance,			       args->lpCmdLine, args->nShowCmd);}# else /* !MSWINCE *//* Called by GC_init() - we hold the allocation lock.	*/void GC_thr_init() {    if (GC_thr_initialized) return;    GC_main_thread = GetCurrentThreadId();    GC_thr_initialized = TRUE;    /* Add the initial thread, so we can stop it.	*/    GC_new_thread();}#ifdef CYGWIN32struct start_info {    void *(*start_routine)(void *);    void *arg;    GC_bool detached;};int GC_pthread_join(pthread_t pthread_id, void **retval) {    int result;    int i;    GC_thread me;#   if DEBUG_CYGWIN_THREADS      GC_printf3("thread 0x%x(0x%x) is joining thread 0x%x.\n",		 (int)pthread_self(), GetCurrentThreadId(), (int)pthread_id);#   endif    /* Thread being joined might not have registered itself yet. */    /* After the join,thread id may have been recycled.		 */    /* FIXME: It would be better if this worked more like	 */    /* pthread_support.c.					 */    while ((me = GC_lookup_thread(pthread_id)) == 0) Sleep(10);    result = pthread_join(pthread_id, retval);    GC_delete_gc_thread(me);#   if DEBUG_CYGWIN_THREADS      GC_printf3("thread 0x%x(0x%x) completed join with thread 0x%x.\n",		 (int)pthread_self(), GetCurrentThreadId(), (int)pthread_id);#   endif    return result;}/* Cygwin-pthreads calls CreateThread internally, but it's not * easily interceptible by us.. *   so intercept pthread_create instead */intGC_pthread_create(pthread_t *new_thread,		  const pthread_attr_t *attr,                  void *(*start_routine)(void *), void *arg) {    int result;    struct start_info * si;    if (!GC_is_initialized) GC_init();    		/* make sure GC is initialized (i.e. main thread is attached) */        /* This is otherwise saved only in an area mmapped by the thread */    /* library, which isn't visible to the collector.		 */    si = GC_malloc_uncollectable(sizeof(struct start_info));     if (0 == si) return(EAGAIN);    si -> start_routine = start_routine;    si -> arg = arg;    if (attr != 0 &&        pthread_attr_getdetachstate(attr, &si->detached)	== PTHREAD_CREATE_DETACHED) {      si->detached = TRUE;    }#   if DEBUG_CYGWIN_THREADS      GC_printf2("About to create a thread from 0x%x(0x%x)\n",		 (int)pthread_self(), GetCurrentThreadId);#   endif    result = pthread_create(new_thread, attr, GC_start_routine, si);     if (result) { /* failure */      	GC_free(si);    }     return(result);}void * GC_start_routine(void * arg){    struct start_info * si = arg;    void * result;    void *(*start)(void *);    void *start_arg;    pthread_t pthread_id;    GC_thread me;    GC_bool detached;    int i;#   if DEBUG_CYGWIN_THREADS      GC_printf2("thread 0x%x(0x%x) starting...\n",(int)pthread_self(),		      				   GetCurrentThreadId());#   endif    /* If a GC occurs before the thread is registered, that GC will	*/    /* ignore this thread.  That's fine, since it will block trying to  */    /* acquire the allocation lock, and won't yet hold interesting 	*/    /* pointers.							*/    LOCK();    /* We register the thread here instead of in the parent, so that	*/    /* we don't need to hold the allocation lock during pthread_create. */    me = GC_new_thread();    UNLOCK();    start = si -> start_routine;    start_arg = si -> arg;    if (si-> detached) me -> flags |= DETACHED;    me -> pthread_id = pthread_id = pthread_self();    GC_free(si); /* was allocated uncollectable */    pthread_cleanup_push(GC_thread_exit_proc, (void *)me);    result = (*start)(start_arg);    me -> status = result;    pthread_cleanup_pop(0);#   if DEBUG_CYGWIN_THREADS      GC_printf2("thread 0x%x(0x%x) returned from start routine.\n",		 (int)pthread_self(),GetCurrentThreadId());#   endif    return(result);}void GC_thread_exit_proc(void *arg){    GC_thread me = (GC_thread)arg;    int i;#   if DEBUG_CYGWIN_THREADS      GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",		 (int)pthread_self(),GetCurrentThreadId());#   endif    LOCK();    if (me -> flags & DETACHED) {      GC_delete_thread(GetCurrentThreadId());    } else {      /* deallocate it as part of join */      me -> flags |= FINISHED;    }    UNLOCK();}/* nothing required here... */int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) {  return pthread_sigmask(how, set, oset);}int GC_pthread_detach(pthread_t thread){    int result;    GC_thread thread_gc_id;        LOCK();    thread_gc_id = GC_lookup_thread(thread);    UNLOCK();    result = pthread_detach(thread);    if (result == 0) {      LOCK();      thread_gc_id -> flags |= DETACHED;      /* Here the pthread thread id may have been recycled. */      if (thread_gc_id -> flags & FINISHED) {        GC_delete_gc_thread(thread_gc_id);      }      UNLOCK();    }    return result;}#else /* !CYGWIN32 *//* * We avoid acquiring locks here, since this doesn't seem to be preemptable. * Pontus Rydin suggests wrapping the thread start routine instead. */#ifdef GC_DLLBOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved){  switch (reason) {  case DLL_PROCESS_ATTACH:    GC_init();	/* Force initialization before thread attach.	*/    /* fall through */  case DLL_THREAD_ATTACH:    GC_ASSERT(GC_thr_initialized);    if (GC_main_thread != GetCurrentThreadId()) {        GC_new_thread();    } /* o.w. we already did it during GC_thr_init(), called by GC_init() */    break;  case DLL_THREAD_DETACH:    GC_delete_thread(GetCurrentThreadId());    break;  case DLL_PROCESS_DETACH:    {      int i;      LOCK();      for (i = 0; i <= GC_get_max_thread_index(); ++i)      {          if (thread_table[i].in_use)	    GC_delete_gc_thread(thread_table + i);      }      UNLOCK();      GC_deinit();      DeleteCriticalSection(&GC_allocate_ml);    }    break;  }  return TRUE;}#endif /* GC_DLL */#endif /* !CYGWIN32 */# endif /* !MSWINCE */#endif /* GC_WIN32_THREADS */

⌨️ 快捷键说明

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