codeowners update
[mono.git] / libgc / pthread_stop_world.c
index 3819693c45cea458812c159cb808312eeeec7e96..afa77dadfab52b020debb373f370f7b42c32fe21 100644 (file)
 #undef PACKAGE_VERSION
 #include "mono/utils/mono-compiler.h"
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-#include "include/libgc-mono-debugger.h"
-#endif
-
 #ifdef NACL
-int nacl_park_threads_now = 0;
+volatile int __nacl_thread_suspension_needed = 0;
 pthread_t nacl_thread_parker = -1;
 
-int nacl_thread_parked[MAX_NACL_GC_THREADS];
-int nacl_thread_used[MAX_NACL_GC_THREADS];
-int nacl_thread_parking_inited = 0;
-int nacl_num_gc_threads = 0;
+volatile int nacl_thread_parked[MAX_NACL_GC_THREADS];
+volatile int nacl_thread_used[MAX_NACL_GC_THREADS];
+volatile int nacl_thread_parking_inited = 0;
+volatile int nacl_num_gc_threads = 0;
 pthread_mutex_t nacl_thread_alloc_lock = PTHREAD_MUTEX_INITIALIZER;
 __thread int nacl_thread_idx = -1;
 __thread GC_thread nacl_gc_thread_self = NULL;
@@ -290,6 +286,10 @@ static void pthread_push_all_stacks()
                (unsigned long) lo, (unsigned long) hi);
         #endif
        if (0 == lo) ABORT("GC_push_all_stacks: sp not set!\n");
+       if (p->altstack && lo >= p->altstack && lo <= p->altstack + p->altstack_size)
+               hi = p->altstack + p->altstack_size;
+       /* FIXME: Need to scan the normal stack too, but how ? */
+
 #       ifdef STACK_GROWS_UP
          /* We got them backwards! */
           GC_push_all_stack(hi, lo);
@@ -337,7 +337,7 @@ void GC_push_all_stacks()
 pthread_t GC_stopping_thread;
 int GC_stopping_pid;
 
-#ifdef PLATFORM_ANDROID
+#ifdef HOST_ANDROID
 static
 int android_thread_kill(pid_t tid, int sig)
 {
@@ -379,7 +379,7 @@ int GC_suspend_all()
              GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
            #endif
 
-#ifndef PLATFORM_ANDROID
+#ifndef HOST_ANDROID
         result = pthread_kill(p -> id, SIG_SUSPEND);
 #else
         result = android_thread_kill(p -> kernel_id, SIG_SUSPEND);
@@ -467,7 +467,7 @@ static void pthread_stop_world()
     GC_printf1("pthread_stop_world: num_threads %d\n", nacl_num_gc_threads - 1);
     #endif
     nacl_thread_parker = pthread_self();
-    nacl_park_threads_now = 1;
+    __nacl_thread_suspension_needed = 1;
     
     while (1) {
        #define NACL_PARK_WAIT_NANOSECONDS 100000
@@ -509,31 +509,49 @@ static void pthread_stop_world()
 
 #define NACL_STORE_REGS()  \
     do {                  \
-       asm("push %rbx");\
-       asm("push %rbp");\
-       asm("push %r12");\
-       asm("push %r13");\
-       asm("push %r14");\
-       asm("push %r15");\
-       asm("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\
+       __asm__ __volatile__ ("push %rbx");\
+       __asm__ __volatile__ ("push %rbp");\
+       __asm__ __volatile__ ("push %r12");\
+       __asm__ __volatile__ ("push %r13");\
+       __asm__ __volatile__ ("push %r14");\
+       __asm__ __volatile__ ("push %r15");\
+       __asm__ __volatile__ ("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\
         memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\
-       asm("add $48, %esp");\
-        asm("add %r15, %rsp");\
+        __asm__ __volatile__ ("naclasp $48, %r15");\
     } while (0)
 
 #elif __i386__
 
 #define NACL_STORE_REGS()  \
     do {                  \
-       asm("push %ebx");\
-       asm("push %ebp");\
-       asm("push %esi");\
-       asm("push %edi");\
-       asm("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\
+       __asm__ __volatile__ ("push %ebx");\
+       __asm__ __volatile__ ("push %ebp");\
+       __asm__ __volatile__ ("push %esi");\
+       __asm__ __volatile__ ("push %edi");\
+       __asm__ __volatile__ ("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\
         memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\
-       asm("add $16, %esp");\
+       __asm__ __volatile__ ("add $16, %esp");\
     } while (0)
 
+#elif __arm__
+
+#define NACL_STORE_REGS()  \
+    do {                   \
+       __asm__ __volatile__ (                      \
+               ".align 4\n\t"                      \
+               "bic %0, %0, #0xc0000000\n\t"       \
+               "str sp, [%0]\n\t"                  \
+               "bic %1, %1, #0xc0000000\n\t"       \
+               "stm %1, {r4-r8,r10-r12,lr}\n\t"    \
+                       :                                               \
+                       : "r" (&nacl_gc_thread_self->stop_info.stack_ptr), \
+                        "r"(nacl_gc_thread_self->stop_info.reg_storage) \
+                       : "memory");                 \
+    } while (0)
+#else
+
+#error "Please port NACL_STORE_REGS"
+
 #endif
 
 void nacl_pre_syscall_hook()
@@ -546,6 +564,8 @@ void nacl_pre_syscall_hook()
     }
 }
 
+void __nacl_suspend_thread_if_needed();
+
 void nacl_post_syscall_hook()
 {
     /* Calling __nacl_suspend_thread_if_needed() right away should guarantee we don't mutate the GC set. */
@@ -556,7 +576,7 @@ void nacl_post_syscall_hook()
 }
 
 void __nacl_suspend_thread_if_needed() {
-    if (nacl_park_threads_now) {
+    if (__nacl_thread_suspension_needed) {
         pthread_t self = pthread_self();
         int local_dummy = 0;
         /* Don't try to park the thread parker. */
@@ -575,7 +595,7 @@ void __nacl_suspend_thread_if_needed() {
             nacl_gc_thread_self->stop_info.stack_ptr = (ptr_t)(&local_dummy);
         }
         nacl_thread_parked[nacl_thread_idx] = 1;
-        while (nacl_park_threads_now)
+        while (__nacl_thread_suspension_needed)
             ; /* spin */
         nacl_thread_parked[nacl_thread_idx] = 0;
 
@@ -591,6 +611,7 @@ void GC_stop_world()
 {
     if (GC_notify_event)
         GC_notify_event (GC_EVENT_PRE_STOP_WORLD);
+       GC_process_togglerefs ();
     /* 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,   */
@@ -601,11 +622,6 @@ void GC_stop_world()
       /* We should have previously waited for it to become zero. */
 #   endif /* PARALLEL_MARK */
     ++GC_stop_count;
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->stop_world)
-       gc_thread_vtable->stop_world ();
-    else
-#endif
        pthread_stop_world ();
 #   ifdef PARALLEL_MARK
       GC_release_mark_lock();
@@ -642,7 +658,7 @@ static void pthread_start_world()
              GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
            #endif
 
-#ifndef PLATFORM_ANDROID
+#ifndef HOST_ANDROID
         result = pthread_kill(p -> id, SIG_THR_RESTART);
 #else
         result = android_thread_kill(p -> kernel_id, SIG_THR_RESTART);
@@ -680,20 +696,19 @@ static void pthread_start_world()
       GC_printf0("World started\n");
     #endif
 #else /* NACL */
+    if (GC_notify_event)
+        GC_notify_event (GC_EVENT_PRE_START_WORLD);
 #   if DEBUG_THREADS
     GC_printf0("World starting\n");
 #   endif
-    nacl_park_threads_now = 0;
+    __nacl_thread_suspension_needed = 0;
+    if (GC_notify_event)
+        GC_notify_event (GC_EVENT_POST_START_WORLD);
 #endif /* NACL */
 }
 
 void GC_start_world()
 {
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->start_world)
-       gc_thread_vtable->start_world();
-    else
-#endif
        pthread_start_world ();
 }
 
@@ -745,27 +760,7 @@ static void pthread_stop_init() {
 /* We hold the allocation lock.        */
 void GC_stop_init()
 {
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->initialize)
-       gc_thread_vtable->initialize ();
-    else
-#endif
        pthread_stop_init ();
 }
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-
-GCThreadFunctions *gc_thread_vtable = NULL;
-
-void *
-GC_mono_debugger_get_stack_ptr (void)
-{
-       GC_thread me;
-
-       me = GC_lookup_thread (pthread_self ());
-       return &me->stop_info.stack_ptr;
-}
-
-#endif
-
 #endif