# endif
# if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
- defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) \
- && !defined(USE_PTHREAD_SPECIFIC)
+ defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \
+ defined(GC_NETBSD_THREADS) && !defined(USE_PTHREAD_SPECIFIC)
# define USE_PTHREAD_SPECIFIC
# endif
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
# include <sys/sysctl.h>
#endif /* GC_DARWIN_THREADS */
+#if defined(GC_NETBSD_THREADS)
+# include <sys/param.h>
+# include <sys/sysctl.h>
+#endif
+
#if defined(GC_DGUX386_THREADS)
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;
result = &first_thread;
first_thread_used = TRUE;
} else {
- result = calloc (1, sizeof (struct GC_Thread_Rep));
+ result = (struct GC_Thread_Rep *)
+ GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep), NORMAL);
}
if (result == 0) return(0);
result -> id = id;
if (gc_thread_vtable && gc_thread_vtable->thread_exited)
gc_thread_vtable->thread_exited (id, &p->stop_info.stack_ptr);
#endif
- free(p);
+
+#ifdef GC_DARWIN_THREADS
+ mach_port_deallocate(mach_task_self(), p->stop_info.mach_thread);
+#endif
+
+ GC_INTERNAL_FREE(p);
}
/* If a thread has been joined, but we have not yet */
} else {
prev -> next = p -> next;
}
- free(p);
+
+#ifdef GC_DARWIN_THREADS
+ mach_port_deallocate(mach_task_self(), p->stop_info.mach_thread);
+#endif
+
+ GC_INTERNAL_FREE(p);
}
/* Return a GC_thread corresponding to a given pthread_t. */
GC_destroy_thread_local(p);
}
# endif /* THREAD_LOCAL_ALLOC */
- if (p != &first_thread) free(p);
+ if (p != &first_thread) GC_INTERNAL_FREE(p);
}
}
GC_threads[hv] = me;
}
+ GC_INTERNAL_FREE(p);
}
#endif /* HANDLE_FORK */
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();
GC_nprocs = sysconf(_SC_NPROC_ONLN);
if (GC_nprocs <= 0) GC_nprocs = 1;
# endif
-# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS)
+# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS)
int ncpus = 1;
size_t len = sizeof(ncpus);
sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
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;
# 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();
/* responsibility. */
LOCK();
- si = calloc (1, sizeof (struct start_info));
+ si = (struct start_info *)GC_INTERNAL_MALLOC(sizeof(struct start_info),
+ NORMAL);
UNLOCK();
if (!parallel_initialized) GC_init_parallel();
if (0 == si) return(ENOMEM);
}
sem_destroy(&(si -> registered));
LOCK();
- free(si);
+ GC_INTERNAL_FREE(si);
UNLOCK();
return(result);