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

📄 darwin_stop_world.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 2 页
字号:
	lo = (void*)info . THREAD_FLD (rsp);	hi = (ptr_t)FindTopOfStack(info . THREAD_FLD (rsp));	GC_push_one(info . THREAD_FLD (rax));	GC_push_one(info . THREAD_FLD (rbx));	GC_push_one(info . THREAD_FLD (rcx));	GC_push_one(info . THREAD_FLD (rdx));	GC_push_one(info . THREAD_FLD (rdi));	GC_push_one(info . THREAD_FLD (rsi));	GC_push_one(info . THREAD_FLD (rbp));	GC_push_one(info . THREAD_FLD (rsp));	GC_push_one(info . THREAD_FLD (r8));	GC_push_one(info . THREAD_FLD (r9));	GC_push_one(info . THREAD_FLD (r10));	GC_push_one(info . THREAD_FLD (r11));	GC_push_one(info . THREAD_FLD (r12));	GC_push_one(info . THREAD_FLD (r13));	GC_push_one(info . THREAD_FLD (r14));	GC_push_one(info . THREAD_FLD (r15));	GC_push_one(info . THREAD_FLD (rip));	GC_push_one(info . THREAD_FLD (rflags));	GC_push_one(info . THREAD_FLD (cs));	GC_push_one(info . THREAD_FLD (fs));	GC_push_one(info . THREAD_FLD (gs));#     else#	error FIXME for non-x86 || ppc architectures#     endif      }#     if DEBUG_THREADS        GC_printf("Darwin: Stack for thread 0x%lx = [%p,%p)\n",		  (unsigned long) thread, lo, hi);#     endif      GC_push_all_stack(lo, hi);      mach_port_deallocate(my_task, thread);    } /* for(p=GC_threads[i]...) */    vm_deallocate(my_task, (vm_address_t)act_list,		  sizeof(thread_t) * listcount);    mach_port_deallocate(my_task, me);}#endif /* !DARWIN_DONT_PARSE_STACK */static mach_port_t GC_mach_handler_thread;static int GC_use_mach_handler_thread = 0;static struct GC_mach_thread GC_mach_threads[THREAD_TABLE_SZ];static int GC_mach_threads_count;void GC_stop_init(){  int i;  for (i = 0; i < THREAD_TABLE_SZ; i++) {    GC_mach_threads[i].thread = 0;    GC_mach_threads[i].already_suspended = 0;  }  GC_mach_threads_count = 0;}/* returns true if there's a thread in act_list that wasn't in old_list */int GC_suspend_thread_list(thread_act_array_t act_list, int count,			   thread_act_array_t old_list, int old_count){  mach_port_t my_thread = mach_thread_self();  int i, j;  int changed = 0;  for(i = 0; i < count; i++) {    thread_act_t thread = act_list[i];#   if DEBUG_THREADS      GC_printf("Attempting to suspend thread %p\n", thread);#   endif    /* find the current thread in the old list */    int found = 0;    for(j = 0; j < old_count; j++) {      thread_act_t old_thread = old_list[j];      if (old_thread == thread) {	found = 1;	break;      }    }    if (!found) {      /* add it to the GC_mach_threads list */      GC_mach_threads[GC_mach_threads_count].thread = thread;      /* default is not suspended */      GC_mach_threads[GC_mach_threads_count].already_suspended = 0;      changed = 1;    }    if (thread != my_thread	&& (!GC_use_mach_handler_thread	    || (GC_use_mach_handler_thread		&& GC_mach_handler_thread != thread))) {      struct thread_basic_info info;      mach_msg_type_number_t outCount = THREAD_INFO_MAX;      kern_return_t kern_result = thread_info(thread, THREAD_BASIC_INFO,				(thread_info_t)&info, &outCount);      if(kern_result != KERN_SUCCESS) {	/* the thread may have quit since the thread_threads () call	 * we mark already_suspended so it's not dealt with anymore later	 */	if (!found) {	  GC_mach_threads[GC_mach_threads_count].already_suspended = TRUE;	  GC_mach_threads_count++;	}	continue;      }#     if DEBUG_THREADS        GC_printf("Thread state for 0x%lx = %d\n", (unsigned long)thread,		  info.run_state);#     endif      if (!found) {	GC_mach_threads[GC_mach_threads_count].already_suspended	  = info.suspend_count;      }      if (info.suspend_count)	continue;#     if DEBUG_THREADS        GC_printf("Suspending 0x%lx\n", (unsigned long)thread);#     endif      /* Suspend the thread */      kern_result = thread_suspend(thread);      if(kern_result != KERN_SUCCESS) {	/* the thread may have quit since the thread_threads () call	 * we mark already_suspended so it's not dealt with anymore later	 */	if (!found) {	  GC_mach_threads[GC_mach_threads_count].already_suspended = TRUE;	  GC_mach_threads_count++;	}	continue;      }    }    if (!found) GC_mach_threads_count++;  }  mach_port_deallocate(current_task(), my_thread);  return changed;}/* Caller holds allocation lock.	*/void GC_stop_world(){    unsigned int i, changes;    task_t my_task = current_task();    mach_port_t my_thread = mach_thread_self();    kern_return_t kern_result;    thread_act_array_t act_list, prev_list;    mach_msg_type_number_t listcount, prevcount;#   if DEBUG_THREADS      GC_printf("Stopping the world from 0x%lx\n",		(unsigned long)mach_thread_self());#   endif    /* clear out the mach threads list table */    GC_stop_init();    /* Make sure all free list construction has stopped before we start. */    /* No new construction can start, since free list construction is	*/    /* required to acquire and release the GC lock before it starts,	*/    /* and we have the lock.						*/#   ifdef PARALLEL_MARK      GC_acquire_mark_lock();      GC_ASSERT(GC_fl_builder_count == 0);      /* We should have previously waited for it to become zero. */#   endif /* PARALLEL_MARK */    /* Loop stopping threads until you have gone over the whole list       twice without a new one appearing. thread_create() won't       return (and thus the thread stop) until the new thread       exists, so there is no window whereby you could stop a       thread, recognise it is stopped, but then have a new thread       it created before stopping show up later.    */    changes = 1;    prev_list = NULL;    prevcount = 0;    do {      int result;      kern_result = task_threads(my_task, &act_list, &listcount);      if(kern_result == KERN_SUCCESS) {	result = GC_suspend_thread_list(act_list, listcount, prev_list,					prevcount);	changes = result;	if(prev_list != NULL) {	  for(i = 0; i < prevcount; i++)	    mach_port_deallocate(my_task, prev_list[i]);	  vm_deallocate(my_task, (vm_address_t)prev_list,			sizeof(thread_t) * prevcount);	}	prev_list = act_list;	prevcount = listcount;      }    } while (changes);    GC_ASSERT(prev_list != 0);    for(i = 0; i < prevcount; i++)      mach_port_deallocate(my_task, prev_list[i]);    vm_deallocate(my_task, (vm_address_t)act_list,		  sizeof(thread_t) * listcount);#   ifdef MPROTECT_VDB      if(GC_incremental) {	extern void GC_mprotect_stop();	GC_mprotect_stop();      }#   endif#   ifdef PARALLEL_MARK      GC_release_mark_lock();#   endif#   if DEBUG_THREADS      GC_printf("World stopped from 0x%lx\n", (unsigned long)my_thread);#   endif    mach_port_deallocate(my_task, my_thread);}/* Caller holds allocation lock, and has held it continuously since	*//* the world stopped.							*/void GC_start_world(){  task_t my_task = current_task();  mach_port_t my_thread = mach_thread_self();  unsigned int i;  int j;  kern_return_t kern_result;  thread_act_array_t act_list;  mach_msg_type_number_t listcount;  struct thread_basic_info info;  mach_msg_type_number_t outCount = THREAD_INFO_MAX;#   if DEBUG_THREADS      GC_printf("World starting\n");#   endif#   ifdef MPROTECT_VDB      if(GC_incremental) {	extern void GC_mprotect_resume();	GC_mprotect_resume();      }#   endif    kern_result = task_threads(my_task, &act_list, &listcount);    for(i = 0; i < listcount; i++) {      thread_act_t thread = act_list[i];      if (thread != my_thread	  && (!GC_use_mach_handler_thread	      || (GC_use_mach_handler_thread		  && GC_mach_handler_thread != thread))) {	for(j = 0; j < GC_mach_threads_count; j++) {	  if (thread == GC_mach_threads[j].thread) {	    if (GC_mach_threads[j].already_suspended) {#             if DEBUG_THREADS	        GC_printf("Not resuming already suspended thread %p\n", thread);#             endif	      continue;	    }	    kern_result = thread_info(thread, THREAD_BASIC_INFO,				      (thread_info_t)&info, &outCount);	    if(kern_result != KERN_SUCCESS)	      ABORT("thread_info failed");#           if DEBUG_THREADS	      GC_printf("Thread state for 0x%lx = %d\n", (unsigned long)thread,			 info.run_state);	      GC_printf("Resuming 0x%lx\n", (unsigned long)thread);#           endif	    /* Resume the thread */	    kern_result = thread_resume(thread);	    if(kern_result != KERN_SUCCESS)	      ABORT("thread_resume failed");	  }	}      }      mach_port_deallocate(my_task, thread);    }    vm_deallocate(my_task, (vm_address_t)act_list,		  sizeof(thread_t) * listcount);    mach_port_deallocate(my_task, my_thread);#   if DEBUG_THREADS      GC_printf("World started\n");#   endif}void GC_darwin_register_mach_handler_thread(mach_port_t thread){  GC_mach_handler_thread = thread;  GC_use_mach_handler_thread = 1;}#endif

⌨️ 快捷键说明

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