Enable test for #318677
[mono.git] / libgc / pthread_support.c
index 68084bd61874464b4ae34adcb2224d6db1dcfe77..2d54a513d017a742472cdb1c77a86f342047369d 100644 (file)
       typedef pthread_key_t GC_key_t;
 #   endif
 #   if defined(USE_COMPILER_TLS)
+/* Note sles9 gcc on powerpc gets confused by the define to set GC_thread_tls and pthread_setspecific
+ * so we actually use a static inline function decalred below that is equivalent to:
+ *   define GC_setspecific(key, v) (GC_thread_tls = (v), pthread_setspecific ((key), (v)))
+ */
 #     define GC_getspecific(x) (GC_thread_tls)
-#     define GC_setspecific(key, v) (GC_thread_tls = (v), pthread_setspecific ((key), (v)))
 #     define GC_key_create pthread_key_create
       typedef pthread_key_t GC_key_t;
 #   endif
@@ -191,7 +194,19 @@ static
 GC_key_t GC_thread_key;
 
 #ifdef USE_COMPILER_TLS
-static __thread MONO_TLS_FAST void* GC_thread_tls;
+__thread MONO_TLS_FAST void* GC_thread_tls;
+
+/*
+ * gcc errors out with /tmp/ccdPMFuq.s:2994: Error: symbol `.LTLS4' is already defined
+ * if the inline is added on powerpc
+ */
+#if !defined(__ppc__) && !defined(__powerpc__)
+inline
+#endif
+static int GC_setspecific (GC_key_t key, void *value) {
+       GC_thread_tls = value;
+       return pthread_setspecific (key, value);
+}
 #endif
 
 static GC_bool keys_initialized;
@@ -677,6 +692,9 @@ GC_thread GC_new_thread(pthread_t id)
     }
     if (result == 0) return(0);
     result -> id = id;
+#ifdef PLATFORM_ANDROID
+    result -> kernel_id = gettid();
+#endif
     result -> next = GC_threads[hv];
     GC_threads[hv] = result;
     GC_ASSERT(result -> flags == 0 && result -> thread_blocked == 0);
@@ -995,7 +1013,11 @@ void GC_thr_init()
       t -> flags = DETACHED | MAIN_THREAD;
 #ifdef MONO_DEBUGGER_SUPPORTED
       if (gc_thread_vtable && gc_thread_vtable->thread_created)
-        gc_thread_vtable->thread_created (pthread_self (), &t->stop_info.stack_ptr);
+#     ifdef GC_DARWIN_THREADS
+        gc_thread_vtable->thread_created (mach_thread_self (), &t->stop_info.stack_ptr);
+#     else
+         gc_thread_vtable->thread_created (pthread_self (), &t->stop_info.stack_ptr);
+#     endif
 #endif
 
     GC_stop_init();
@@ -1042,6 +1064,8 @@ void GC_thr_init()
              GC_markers = atoi(markers_string);
            } else {
              GC_markers = GC_nprocs;
+                 if (GC_markers > MAX_MARKERS)
+                         GC_markers = MAX_MARKERS;
            }
           }
 #      endif
@@ -1185,6 +1209,11 @@ void GC_thread_exit_proc(void *arg)
     me = GC_lookup_thread(pthread_self());
     GC_destroy_thread_local(me);
     if (me -> flags & DETACHED) {
+# ifdef THREAD_LOCAL_ALLOC
+               /* NULL out the tls key to prevent the dtor function from being called */
+               if (0 != GC_setspecific(GC_thread_key, NULL))
+                       ABORT("Failed to set thread specific allocation pointers");
+#endif
        GC_delete_thread(pthread_self());
     } else {
        me -> flags |= FINISHED;
@@ -1304,14 +1333,19 @@ void * GC_start_routine_head(void * arg, void *base_addr,
 #   endif /* IA64 */
 #ifdef MONO_DEBUGGER_SUPPORTED
     if (gc_thread_vtable && gc_thread_vtable->thread_created)
-       gc_thread_vtable->thread_created (my_pthread, &me->stop_info.stack_ptr);
+#      ifdef GC_DARWIN_THREADS
+       gc_thread_vtable->thread_created (mach_thread_self(), &me->stop_info.stack_ptr);
+#      else
+       gc_thread_vtable->thread_created (my_pthread, &me->stop_info.stack_ptr);
+#      endif
 #endif
     UNLOCK();
 
     if (start) *start = si -> start_routine;
     if (start_arg) *start_arg = si -> arg;
 
-    sem_post(&(si -> registered));     /* Last action on si.   */
+       if (!(si->flags & FOREIGN_THREAD))
+               sem_post(&(si -> registered));  /* Last action on si.   */
                                        /* OK to deallocate.    */
 #   if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
        LOCK();