+ struct thread *p,*th=arch_os_get_current_thread();
+ int status;
+ FSHOW_SIGNAL((stderr,"/gc_stop_the_world:waiting on lock, thread=%lu\n",
+ th->os_thread));
+ /* keep threads from starting while the world is stopped. */
+ pthread_mutex_lock(&all_threads_lock); \
+ FSHOW_SIGNAL((stderr,"/gc_stop_the_world:got lock, thread=%lu\n",
+ th->os_thread));
+ /* stop all other threads by sending them SIG_STOP_FOR_GC */
+ for(p=all_threads; p; p=p->next) {
+ while(p->state==STATE_STARTING) sched_yield();
+ if((p!=th) && (p->state==STATE_RUNNING)) {
+ FSHOW_SIGNAL((stderr,"/gc_stop_the_world: suspending %lu\n",
+ p->os_thread));
+ status=kill_thread_safely(p->os_thread,SIG_STOP_FOR_GC);
+ if (status==ESRCH) {
+ /* This thread has exited. */
+ gc_assert(p->state==STATE_DEAD);
+ } else if (status) {
+ lose("cannot send suspend thread=%lu: %d, %s",
+ p->os_thread,status,strerror(status));
+ }
+ }
+ }
+ FSHOW_SIGNAL((stderr,"/gc_stop_the_world:signals sent\n"));
+ /* wait for the running threads to stop or finish */
+ for(p=all_threads;p;) {
+ gc_assert(p->os_thread!=0);
+ gc_assert(p->state!=STATE_STARTING);
+ if((p==th) || (p->state==STATE_SUSPENDED) ||
+ (p->state==STATE_DEAD)) {
+ p=p->next;
+ } else {
+ sched_yield();
+ }
+ }
+ FSHOW_SIGNAL((stderr,"/gc_stop_the_world:end\n"));