static void* boehm_thread_register (MonoThreadInfo* info, void *baseptr) { #if GC_VERSION_MAJOR >= 7 struct GC_stack_base sb; int res; res = GC_get_stack_base (&sb); if (res != GC_SUCCESS) { sb.mem_base = baseptr; #ifdef __ia64__ /* Can't determine the register stack bounds */ g_error ("mono_gc_register_thread failed ().\n"); #endif } res = GC_register_my_thread (&sb); if ((res != GC_SUCCESS) && (res != GC_DUPLICATE)) { g_warning ("GC_register_my_thread () failed.\n"); return NULL; } return info; #else if (mono_gc_is_gc_thread()) return info; #if defined(USE_INCLUDED_LIBGC) && !defined(HOST_WIN32) return GC_thread_register_foreign (baseptr) ? info : NULL; #else return NULL; #endif #endif }
gboolean mono_gc_register_thread (void *baseptr) { #if GC_VERSION_MAJOR >= 7 struct GC_stack_base sb; int res; res = GC_get_stack_base (&sb); if (res != GC_SUCCESS) { sb.mem_base = baseptr; #ifdef __ia64__ /* Can't determine the register stack bounds */ g_error ("mono_gc_register_thread failed ().\n"); #endif } res = GC_register_my_thread (&sb); if ((res != GC_SUCCESS) && (res != GC_DUPLICATE)) { g_warning ("GC_register_my_thread () failed.\n"); return FALSE; } return TRUE; #else if (mono_gc_is_gc_thread()) return TRUE; #if defined(USE_INCLUDED_LIBGC) && !defined(PLATFORM_WIN32) return GC_thread_register_foreign (baseptr); #else return FALSE; #endif #endif }
void * GC_win32_start_inner(struct GC_stack_base *sb, LPVOID arg) { void * ret; thread_args *args = (thread_args *)arg; # if DEBUG_WIN32_THREADS GC_printf("thread 0x%x starting...\n", GetCurrentThreadId()); # endif GC_register_my_thread(sb); /* This waits for an in-progress GC. */ /* 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 = (void *)(size_t)args->start (args->param); #ifndef __GNUC__ } __finally { #endif /* __GNUC__ */ GC_unregister_my_thread(); GC_free(args); #ifndef __GNUC__ } #endif /* __GNUC__ */ # if DEBUG_WIN32_THREADS GC_printf("thread 0x%x returned from start routine.\n", GetCurrentThreadId()); # endif return ret; }
void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg) { int res = GC_register_my_thread (sb); pthread_t t; GC_pthread_create (&t, NULL, entry, NULL); if (res == GC_SUCCESS) GC_unregister_my_thread (); return NULL; }
/* At the start of a thread other than the main thread, we need to register the new thread with the collector. */ static void conservative_thread_start() { struct GC_stack_base sb; if(GC_get_stack_base(&sb) != GC_SUCCESS) { fprintf(stderr, "Failure getting stack base for interpreter thread.\n"); exit(EXIT_FAILURE); } if(GC_register_my_thread(&sb) != GC_SUCCESS) { fprintf(stderr, "Failure registering interpreter thread.\n"); exit(EXIT_FAILURE); } }
/* Called by GC_init() - we hold the allocation lock. */ void GC_thr_init(void) { struct GC_stack_base sb; int sb_result; GC_ASSERT(I_HOLD_LOCK()); if (GC_thr_initialized) return; GC_main_thread = GetCurrentThreadId(); GC_thr_initialized = TRUE; /* Add the initial thread, so we can stop it. */ sb_result = GC_get_stack_base(&sb); GC_ASSERT(sb_result == GC_SUCCESS); GC_register_my_thread(&sb); }
void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg) { int res = GC_register_my_thread (sb); pthread_t t; int creation_res; /* Used to suppress a warning about */ /* unchecked pthread_create() result. */ pthread_attr_t attr; if (pthread_attr_init(&attr) != 0 || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) { fprintf(stderr, "Thread attribute init or setdetachstate failed\n"); exit(2); } creation_res = GC_pthread_create(&t, &attr, entry, NULL); (void)pthread_attr_destroy(&attr); if (res == GC_SUCCESS) GC_unregister_my_thread (); return arg ? (void*)(GC_word)creation_res : 0; }
EXTERN bool neko_thread_register( bool t ) { # if !defined(NEKO_THREADS) return 0; # elif defined(NEKO_WINDOWS) struct GC_stack_base sb; int r; if( !t ) return GC_unregister_my_thread() == GC_SUCCESS; if( GC_get_stack_base(&sb) != GC_SUCCESS ) return 0; r = GC_register_my_thread(&sb); return( r == GC_SUCCESS || r == GC_DUPLICATE ); # else // since the API is only available on GC 7.0, // we will do our best to locate it dynamically static gc_stack_ptr get_sb = NULL, my_thread = NULL; static std_func unreg_my_thread = NULL; if( !t && unreg_my_thread != NULL ) { return unreg_my_thread() == GC_SUCCESS; } else if( my_thread != NULL ) { __stack_base sb; int r; if( get_sb(&sb) != GC_SUCCESS ) return 0; r = my_thread(&sb); return( r == GC_SUCCESS || r == GC_DUPLICATE ); } else { void *self = dlopen(NULL,0); my_thread = (gc_stack_ptr)dlsym(self,"GC_register_my_thread"); get_sb = (gc_stack_ptr)dlsym(self,"GC_get_stack_base"); unreg_my_thread = (std_func)dlsym(self,"GC_unregister_my_thread"); if( my_thread == NULL ) my_thread = do_nothing; if( get_sb == NULL ) get_sb = do_nothing; if( unreg_my_thread == NULL ) unreg_my_thread = (std_func)do_nothing; return neko_thread_register(t); } # endif }
int ecl_boot(const char *root_dir) { int argc = 1; char *argv[256]; argv[0] = "ecl"; GC_allow_register_threads(); GC_register_my_thread((const struct GC_stack_base *)argv); GC_stackbottom = (void*)(argv+255); setenv("ECLDIR", "", 1); cl_boot(argc, argv); main_lib_ECL_HELP(); main_lib_ASDF(); main_lib_SOCKETS(); main_lib_IPHONEPSYSTEM(); si_select_package(ecl_make_simple_base_string("CL-USER", 7)); char tmp[2048]; sprintf(tmp, "(setq *default-pathnames-defaults* #p\"%s\")", root_dir); si_safe_eval(3, c_string_to_object(tmp), Cnil, OBJNULL); init_callbacks_registry(); ecl_toplevel(root_dir); return 0; }