]> granicus.if.org Git - gc/commitdiff
NaCl runtime fixes
authorElijah Taylor <elijahtaylor@google.com>
Thu, 31 Jan 2013 20:04:20 +0000 (12:04 -0800)
committerIvan Maidanski <ivmai@mail.ru>
Sun, 15 Sep 2013 09:00:15 +0000 (13:00 +0400)
- fix compile/runtime issues caused by upstream changes
- add NaCl glibc support
- various changes to support running tests in NaCl glibc
  from 'make check'

dyn_load.c
include/private/gcconfig.h
misc.c
pthread_stop_world.c
pthread_support.c

index e4be3c7d183e31d4410d2f99c4c5ec32d4676a15..ca7ce54f19461e6f38f49c57c9ed49c849b8a935 100644 (file)
@@ -26,7 +26,7 @@
  * None of this is safe with dlclose and incremental collection.
  * But then not much of anything is safe in the presence of dlclose.
  */
-#if defined(__linux__) && !defined(_GNU_SOURCE)
+#if (defined(__linux__) || defined(__native_client__)) && !defined(_GNU_SOURCE)
     /* Can't test LINUX, since this must be define before other includes */
 #   define _GNU_SOURCE
 #endif
@@ -54,7 +54,7 @@
 #if !defined(SUNOS4) && !defined(SUNOS5DL) && !defined(IRIX5) && \
     !defined(MSWIN32) && !defined(MSWINCE) && \
     !(defined(ALPHA) && defined(OSF1)) && \
-    !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
+    !defined(HPUX) && !((defined(LINUX) || defined(NACL)) && defined(__ELF__)) && \
     !defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \
     !(defined(FREEBSD) && defined(__ELF__)) && \
     !(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \
@@ -91,7 +91,7 @@
 #   define ELFSIZE ARCH_ELFSIZE
 #endif
 
-#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
+#if (defined(LINUX) || defined(NACL)) && defined(__ELF__) || defined(SCO_ELF) || \
     (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
     (defined(OPENBSD) && defined(__ELF__)) || \
     (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
@@ -297,7 +297,7 @@ void GC_register_dynamic_libraries()
 # endif /* !USE_PROC ... */
 # endif /* SUNOS */
 
-#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
+#if (defined(LINUX) || defined(NACL)) && defined(__ELF__) || defined(SCO_ELF) || \
     (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
     (defined(OPENBSD) && defined(__ELF__)) || \
     (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
@@ -394,7 +394,7 @@ GC_bool GC_register_main_static_data()
 /* For glibc 2.2.4+.  Unfortunately, it doesn't work for older */
 /* versions.  Thanks to Jakub Jelinek for most of the code.    */
 
-# if defined(LINUX) /* Are others OK here, too? */ \
+# if (defined(LINUX) || defined(NACL)) /* Are others OK here, too? */ \
      && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
          || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) 
 
index ec53e3a95eab84e5de67b9b3247c96516ee74e70..49ffccddf505b1680240cce5069929abae02ebd8 100644 (file)
 /* Determine the machine type: */
 # if defined(__native_client__)
 #    define NACL
-#    define I386
-#    define mach_type_known
+#    if !defined(__portable_native_client__)
+#        define I386
+#        define mach_type_known
+#    else
+         /* Here we will rely upon arch-specific defines. */
+#    endif
 # endif
 # if defined(__arm__) || defined(__thumb__)
 #    define ARM32
 #   endif
 # endif
 
+
+# ifdef NACL
+#   define OS_TYPE "NACL"
+#   if defined(__GLIBC__)
+#      define DYNAMIC_LOADING
+#   endif
+#   define DATASTART ((ptr_t)0x10020000)
+    extern int _end[];
+#   define DATAEND (_end)
+#   ifdef STACK_GRAN
+#      undef STACK_GRAN
+#   endif /* STACK_GRAN */
+#   define STACK_GRAN 0x10000
+#   define HEURISTIC1
+#   define USE_MMAP
+#   define USE_MUNMAP
+#   define USE_MMAP_ANON
+#   ifdef USE_MMAP_FIXED
+#      undef USE_MMAP_FIXED
+#   endif
+#   define GETPAGESIZE() 65536
+#   define MAX_NACL_GC_THREADS 1024
+# endif
+
 # ifdef VAX
 #   define MACH_TYPE "VAX"
 #   define ALIGNMENT 4 /* Pointers are longword aligned by 4.2 C compiler */
 #        define HEAP_START DATAEND
 #      endif /* USE_MMAP */
 #   endif /* DGUX */
-#   ifdef NACL
-#      define OS_TYPE "NACL"
-       extern int etext[];
-//#    define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
-#       define DATASTART ((ptr_t)0x10000000)
-       extern int _end[];
-#      define DATAEND (_end)
-#      ifdef STACK_GRAN
-#        undef STACK_GRAN
-#      endif /* STACK_GRAN */
-#      define STACK_GRAN 0x10000
-#      define HEURISTIC1
-#      ifdef USE_MMAP
-#        undef USE_MMAP
-#      endif
-#      ifdef USE_MUNMAP
-#        undef USE_MUNMAP
-#      endif
-#      ifdef USE_MMAP_ANON
-#        undef USE_MMAP_ANON
-#      endif
-#      ifdef USE_MMAP_FIXED
-#        undef USE_MMAP_FIXED
-#      endif
-#      define GETPAGESIZE() 65536
-#      define MAX_NACL_GC_THREADS 1024
-#   endif
 #   ifdef LINUX
 #      ifndef __GNUC__
          /* The Intel compiler doesn't like inline assembly */
diff --git a/misc.c b/misc.c
index 5b2868d808b691d90fd521f01e6b28757f5c86f9..53d47c53dbc86338b6b06c00141da1b8a8766098 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1003,7 +1003,11 @@ long a, b, c, d, e, f;
     buf[1024] = 0x15;
     (void) sprintf(buf, format, a, b, c, d, e, f);
     if (buf[1024] != 0x15) ABORT("GC_printf clobbered stack");
+#ifdef NACL
+    WRITE(GC_stdout, buf, strlen(buf));
+#else
     if (WRITE(GC_stdout, buf, strlen(buf)) < 0) ABORT("write to stdout failed");
+#endif
 }
 
 void GC_err_printf(format, a, b, c, d, e, f)
@@ -1015,13 +1019,21 @@ long a, b, c, d, e, f;
     buf[1024] = 0x15;
     (void) sprintf(buf, format, a, b, c, d, e, f);
     if (buf[1024] != 0x15) ABORT("GC_err_printf clobbered stack");
+#ifdef NACL
+    WRITE(GC_stderr, buf, strlen(buf));
+#else
     if (WRITE(GC_stderr, buf, strlen(buf)) < 0) ABORT("write to stderr failed");
+#endif
 }
 
 void GC_err_puts(s)
 GC_CONST char *s;
 {
+#ifdef NACL
+    WRITE(GC_stderr, s, strlen(s));
+#else
     if (WRITE(GC_stderr, s, strlen(s)) < 0) ABORT("write to stderr failed");
+#endif
 }
 
 #if defined(LINUX) && !defined(SMALL_CONFIG)
index 05e897fb739ba5a4468ccd54c99f51f7771118c3..8b25376b54ab6d691176ba61f0d7345c6b5c1ab6 100644 (file)
@@ -24,7 +24,7 @@
 #endif
 
 #ifdef NACL
-int nacl_park_threads_now = 0;
+volatile int __nacl_thread_suspension_needed = 0;
 pthread_t nacl_thread_parker = -1;
 
 volatile int nacl_thread_parked[MAX_NACL_GC_THREADS];
@@ -471,7 +471,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
@@ -549,6 +549,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. */
@@ -559,7 +561,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. */
@@ -578,7 +580,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;
 
@@ -688,7 +690,7 @@ static void pthread_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 */
index 50241e44bf87e3053e27fd8cf666ef96fae4cb12..b302688a76e589fc603da7c0ce126696f842579e 100644 (file)
@@ -699,10 +699,20 @@ extern void nacl_pre_syscall_hook();
 extern void nacl_post_syscall_hook();
 extern void nacl_register_gc_hooks(void (*pre)(), void (*post)());
 
+#include <stdio.h>
+
+struct nacl_irt_blockhook {
+  int (*register_block_hooks)(void (*pre)(void), void (*post)(void));
+};
+
+extern size_t nacl_interface_query(const char *interface_ident,
+                            void *table, size_t tablesize);
+
 void nacl_initialize_gc_thread()
 {
     int i;
-    nacl_register_gc_hooks(nacl_pre_syscall_hook, nacl_post_syscall_hook);
+    static struct nacl_irt_blockhook gc_hook;
+
     pthread_mutex_lock(&nacl_thread_alloc_lock);
     if (!nacl_thread_parking_inited)
     {
@@ -710,6 +720,10 @@ void nacl_initialize_gc_thread()
             nacl_thread_used[i] = 0;
             nacl_thread_parked[i] = 0;
         }
+        // TODO: replace with public 'register hook' function when
+        // available from glibc
+        nacl_interface_query("nacl-irt-blockhook-0.1", &gc_hook, sizeof(gc_hook));
+        gc_hook.register_block_hooks(nacl_pre_syscall_hook, nacl_post_syscall_hook);
         nacl_thread_parking_inited = 1;
     }
     GC_ASSERT(nacl_num_gc_threads <= MAX_NACL_GC_THREADS);
@@ -942,6 +956,7 @@ int GC_segment_is_thread_stack(ptr_t lo, ptr_t hi)
 /* Return the number of processors, or i<= 0 if it can't be determined.        */
 int GC_get_nprocs()
 {
+#ifndef NACL
     /* Should be "return sysconf(_SC_NPROCESSORS_ONLN);" but that      */
     /* appears to be buggy in many cases.                              */
     /* We look for lines "cpu<n>" in /proc/stat.                       */
@@ -971,6 +986,9 @@ int GC_get_nprocs()
     }
     close(f);
     return result;
+#else /* NACL */
+    return sysconf(_SC_NPROCESSORS_ONLN);
+#endif
 }
 #endif /* GC_LINUX_THREADS */
 
@@ -1362,12 +1380,10 @@ int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
 }
 
 #ifdef NACL
-/* Native Client doesn't support pthread cleanup functions, */
-/* so wrap pthread_exit and manually cleanup the thread.    */
+/* TODO: remove, NaCl glibc now supports pthread cleanup functions. */
 void
 WRAP_FUNC(pthread_exit)(void *status)
 {
-    GC_thread_exit_proc(0); 
     REAL_FUNC(pthread_exit)(status);
 }
 #endif