Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libgc
diff options
context:
space:
mode:
authorPaolo Molaro <lupus@oddwiz.org>2005-08-01 18:51:35 +0400
committerPaolo Molaro <lupus@oddwiz.org>2005-08-01 18:51:35 +0400
commit20c942a6d27aa7bdaa4687a45ba8085b73ba8947 (patch)
treebc5ed66a15d4e7acc2c48a21d1c2955550fc2015 /libgc
parentbaa5cb3456a8432a09ce173395327768df88381a (diff)
Mon Aug 1 16:49:45 CEST 2005 Paolo Molaro <lupus@ximian.com>
* include/private/pthread_support.h, pthread_support.c: added patch to support registering new threads at runtime (from Michael Meeks <michael.meeks@novell.com>). svn path=/trunk/mono/; revision=47889
Diffstat (limited to 'libgc')
-rw-r--r--libgc/ChangeLog7
-rw-r--r--libgc/include/private/pthread_support.h3
-rw-r--r--libgc/pthread_support.c76
3 files changed, 73 insertions, 13 deletions
diff --git a/libgc/ChangeLog b/libgc/ChangeLog
index 89b941970c8..0463c3e33df 100644
--- a/libgc/ChangeLog
+++ b/libgc/ChangeLog
@@ -1,3 +1,10 @@
+
+Mon Aug 1 16:49:45 CEST 2005 Paolo Molaro <lupus@ximian.com>
+
+ * include/private/pthread_support.h, pthread_support.c: added
+ patch to support registering new threads at runtime (from
+ Michael Meeks <michael.meeks@novell.com>).
+
2005-07-07 Raja R Harinath <rharinath@novell.com>
* Makefile.am (INCLUDES): Add $(top_builddir)/.. to pick up mono's
diff --git a/libgc/include/private/pthread_support.h b/libgc/include/private/pthread_support.h
index d52e4da90aa..c00ec51fa7b 100644
--- a/libgc/include/private/pthread_support.h
+++ b/libgc/include/private/pthread_support.h
@@ -33,6 +33,7 @@ typedef struct GC_Thread_Rep {
# define FINISHED 1 /* Thread has exited. */
# define DETACHED 2 /* Thread is intended to be detached. */
# define MAIN_THREAD 4 /* True for the original thread only. */
+# define FOREIGN_THREAD 8 /* Will not be de-registered by us */
short thread_blocked; /* Protected by GC lock. */
/* Treated as a boolean value. If set, */
/* thread will acquire GC lock before */
@@ -91,6 +92,8 @@ extern GC_bool GC_thr_initialized;
GC_thread GC_lookup_thread(pthread_t id);
+void *GC_thread_deregister_foreign (void *data);
+
void GC_stop_init();
extern GC_bool GC_in_thread_creation;
diff --git a/libgc/pthread_support.c b/libgc/pthread_support.c
index bece06f1399..24d81ee5d52 100644
--- a/libgc/pthread_support.c
+++ b/libgc/pthread_support.c
@@ -221,6 +221,20 @@ static void return_freelists(ptr_t *fl, ptr_t *gfl)
/* we arrange for those to fault asap.) */
static ptr_t size_zero_object = (ptr_t)(&size_zero_object);
+void GC_delete_thread(pthread_t id);
+
+void *GC_thread_deregister_foreign (void *data)
+{
+ GC_thread me = (GC_thread)data;
+ /* GC_fprintf1( "\n\n\n\n --- Deregister %x ---\n\n\n\n\n", me->flags ); */
+ if (me -> flags & FOREIGN_THREAD) {
+ LOCK();
+ /* GC_fprintf0( "\n\n\n\n --- FOO ---\n\n\n\n\n" ); */
+ GC_delete_thread(me->id);
+ UNLOCK();
+ }
+}
+
/* Each thread structure must be initialized. */
/* This call must be made from the new thread. */
/* Caller holds allocation lock. */
@@ -229,7 +243,7 @@ void GC_init_thread_local(GC_thread p)
int i;
if (!keys_initialized) {
- if (0 != GC_key_create(&GC_thread_key, 0)) {
+ if (0 != GC_key_create(&GC_thread_key, GC_thread_deregister_foreign)) {
ABORT("Failed to create key for local allocator");
}
keys_initialized = TRUE;
@@ -1201,15 +1215,14 @@ WRAP_FUNC(pthread_detach)(pthread_t thread)
GC_bool GC_in_thread_creation = FALSE;
-void * GC_start_routine(void * arg)
+typedef void *(*ThreadStartFn)(void *);
+void * GC_start_routine_head(void * arg, void *base_addr,
+ ThreadStartFn *start, void **start_arg )
{
- int dummy;
struct start_info * si = arg;
void * result;
GC_thread me;
pthread_t my_pthread;
- void *(*start)(void *);
- void *start_arg;
my_pthread = pthread_self();
# ifdef DEBUG_THREADS
@@ -1232,7 +1245,7 @@ void * GC_start_routine(void * arg)
/* one for the main thread. There is a strong argument that that's */
/* a kernel bug, but a pervasive one. */
# ifdef STACK_GROWS_DOWN
- me -> stack_end = (ptr_t)(((word)(&dummy) + (GC_page_size - 1))
+ me -> stack_end = (ptr_t)(((word)(base_addr) + (GC_page_size - 1))
& ~(GC_page_size - 1));
# ifndef GC_DARWIN_THREADS
me -> stop_info.stack_ptr = me -> stack_end - 0x10;
@@ -1240,7 +1253,7 @@ void * GC_start_routine(void * arg)
/* Needs to be plausible, since an asynchronous stack mark */
/* should not crash. */
# else
- me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1));
+ me -> stack_end = (ptr_t)((word)(base_addr) & ~(GC_page_size - 1));
me -> stop_info.stack_ptr = me -> stack_end + 0x10;
# endif
/* This is dubious, since we may be more than a page into the stack, */
@@ -1252,19 +1265,56 @@ void * GC_start_routine(void * arg)
/* from /proc, but the hook to do so isn't there yet. */
# endif /* IA64 */
UNLOCK();
- start = si -> start_routine;
-# ifdef DEBUG_THREADS
- GC_printf1("start_routine = 0x%lx\n", start);
-# endif
- start_arg = si -> arg;
+
+ if (start) *start = si -> start_routine;
+ if (start_arg) *start_arg = si -> arg;
+
sem_post(&(si -> registered)); /* Last action on si. */
/* OK to deallocate. */
- pthread_cleanup_push(GC_thread_exit_proc, 0);
# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
LOCK();
GC_init_thread_local(me);
UNLOCK();
# endif
+
+ return me;
+}
+
+int GC_thread_register_foreign (void *base_addr)
+{
+ struct start_info si = { 0, }; /* stacked for legibility & locking */
+ GC_thread me;
+
+ GC_printf1( "GC_thread_register_foreign %p\n", &si );
+
+ si.flags = FOREIGN_THREAD;
+
+ if (!parallel_initialized) GC_init_parallel();
+ LOCK();
+ if (!GC_thr_initialized) GC_thr_init();
+
+ UNLOCK();
+
+ me = GC_start_routine_head(&si, base_addr, NULL, NULL);
+
+ return me != NULL;
+}
+
+void * GC_start_routine(void * arg)
+{
+ int dummy;
+ struct start_info * si = arg;
+ void * result;
+ GC_thread me;
+ ThreadStartFn start;
+ void *start_arg;
+
+ me = GC_start_routine_head (arg, &dummy, &start, &start_arg);
+
+ pthread_cleanup_push(GC_thread_exit_proc, 0);
+# ifdef DEBUG_THREADS
+ GC_printf1("start_routine = 0x%lx\n", start);
+# endif
result = (*start)(start_arg);
#if DEBUG_THREADS
GC_printf1("Finishing thread 0x%x\n", pthread_self());