# if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \
- defined(GC_NETBSD_THREADS) && !defined(USE_PTHREAD_SPECIFIC)
+ defined(GC_NETBSD_THREADS) && !defined(USE_PTHREAD_SPECIFIC) || \
+ defined(GC_OPENBSD_THREADS)
# define USE_PTHREAD_SPECIFIC
# endif
# include <sys/sysctl.h>
#endif /* GC_DARWIN_THREADS */
-#if defined(GC_NETBSD_THREADS)
+#if defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS)
# include <sys/param.h>
# include <sys/sysctl.h>
#endif
# endif
# undef pthread_join
# undef pthread_detach
+# if defined(NACL)
+# undef pthread_exit
+# endif
# if defined(GC_OSF1_THREADS) && defined(_PTHREAD_USE_MANGLED_NAMES_) \
&& !defined(_PTHREAD_USE_PTDNAM_)
/* Restore the original mangled names on Tru64 UNIX. */
static struct GC_Thread_Rep first_thread;
+#ifdef NACL
+extern int nacl_thread_parked[MAX_NACL_GC_THREADS];
+extern int nacl_thread_used[MAX_NACL_GC_THREADS];
+extern int nacl_thread_parking_inited;
+extern int nacl_num_gc_threads;
+extern pthread_mutex_t nacl_thread_alloc_lock;
+extern __thread int nacl_thread_idx;
+extern __thread GC_thread nacl_gc_thread_self;
+
+void nacl_initialize_gc_thread()
+{
+ int i;
+ pthread_mutex_lock(&nacl_thread_alloc_lock);
+ if (!nacl_thread_parking_inited)
+ {
+ for (i = 0; i < MAX_NACL_GC_THREADS; i++) {
+ nacl_thread_used[i] = 0;
+ nacl_thread_parked[i] = 0;
+ }
+ nacl_thread_parking_inited = 1;
+ }
+ GC_ASSERT(nacl_num_gc_threads <= MAX_NACL_GC_THREADS);
+ for (i = 0; i < MAX_NACL_GC_THREADS; i++) {
+ if (nacl_thread_used[i] == 0) {
+ nacl_thread_used[i] = 1;
+ nacl_thread_idx = i;
+ nacl_num_gc_threads++;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&nacl_thread_alloc_lock);
+}
+
+void nacl_shutdown_gc_thread()
+{
+ pthread_mutex_lock(&nacl_thread_alloc_lock);
+ GC_ASSERT(nacl_thread_idx >= 0 && nacl_thread_idx < MAX_NACL_GC_THREADS);
+ GC_ASSERT(nacl_thread_used[nacl_thread_idx] != 0);
+ nacl_thread_used[nacl_thread_idx] = 0;
+ nacl_thread_idx = -1;
+ nacl_num_gc_threads--;
+ pthread_mutex_unlock(&nacl_thread_alloc_lock);
+}
+
+#endif /* NACL */
+
/* Add a thread to GC_threads. We assume it wasn't already there. */
/* Caller holds allocation lock. */
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;
+#ifdef NACL
+ nacl_gc_thread_self = result;
+ nacl_initialize_gc_thread();
+#endif
GC_ASSERT(result -> flags == 0 && result -> thread_blocked == 0);
return(result);
}
register GC_thread p = GC_threads[hv];
register GC_thread prev = 0;
+#ifdef NACL
+ nacl_shutdown_gc_thread();
+ nacl_gc_thread_self = NULL;
+#endif
+
while (!pthread_equal(p -> id, id)) {
prev = p;
p = p -> next;
GC_nprocs = sysconf(_SC_NPROC_ONLN);
if (GC_nprocs <= 0) GC_nprocs = 1;
# endif
-# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS)
+# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS)
int ncpus = 1;
size_t len = sizeof(ncpus);
sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
GC_markers = atoi(markers_string);
} else {
GC_markers = GC_nprocs;
+ if (GC_markers > MAX_MARKERS)
+ GC_markers = MAX_MARKERS;
}
}
# endif
}
-#if !defined(GC_DARWIN_THREADS)
+#if !defined(GC_DARWIN_THREADS) && !defined(GC_OPENBSD_THREADS)
+#ifndef NACL
int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
{
sigset_t fudged_set;
}
return(REAL_FUNC(pthread_sigmask)(how, set, oset));
}
+#endif
#endif /* !GC_DARWIN_THREADS */
/* Wrappers for functions that are likely to block for an appreciable */
return result;
}
+#ifdef NACL
+/* Native Client doesn't support pthread cleanup functions, */
+/* so wrap pthread_exit and manually cleanup the thread. */
+void
+WRAP_FUNC(pthread_exit)(void *status)
+{
+ GC_thread_exit_proc(0);
+ REAL_FUNC(pthread_exit)(status);
+}
+#endif
+
int
WRAP_FUNC(pthread_detach)(pthread_t thread)
{
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();