From: Michael Starzinger Date: Sat, 13 Oct 2007 11:16:56 +0000 (+0200) Subject: * src/mm/cacao-gc/gc.c (gc_global_lock): Removed obsolete global lock. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=df68c7049f662b257061390a1806da9f534de8bf;p=cacao.git * src/mm/cacao-gc/gc.c (gc_global_lock): Removed obsolete global lock. (gc_collect): Use GC mutex as global gc lock. (gc_reference_register_intern, gc_reference_unregister_intern): Use GC mutex to lock the reference lists. * src/mm/cacao-gc/gc.h (GC_MUTEX_LOCK, GC_MUTEX_UNLOCK): Added macros. * src/threads/native/threads.c [ENABLE_GC_CACAO] (mutex_gc): Added GC mutex. [ENABLE_GC_CACAO] (threads_mutex_gc_lock, threads_mutex_gc_unlock): Implemented. * src/threads/threads-common.h [ENABLE_GC_CACAO] (threads_mutex_gc_lock, threads_mutex_gc_unlock): Added prototypes. --- diff --git a/src/mm/cacao-gc/gc.c b/src/mm/cacao-gc/gc.c index 61490282d..dc4487c1a 100644 --- a/src/mm/cacao-gc/gc.c +++ b/src/mm/cacao-gc/gc.c @@ -56,10 +56,6 @@ bool gc_notify_finalizer; list_t *gc_reflist_strong; list_t *gc_reflist_weak; -#if defined(ENABLE_THREADS) -java_object_t *gc_global_lock; -#endif - #if !defined(ENABLE_THREADS) executionstate_t *_no_threads_executionstate; sourcestate_t *_no_threads_sourcestate; @@ -101,12 +97,6 @@ void gc_init(u4 heapmaxsize, u4 heapstartsize) gc_reflist_strong = list_create(OFFSET(list_gcref_entry_t, linkage)); gc_reflist_weak = list_create(OFFSET(list_gcref_entry_t, linkage)); -#if defined(ENABLE_THREADS) - /* create global gc lock object */ - gc_global_lock = NEW(java_object_t); - lock_init_object_lock(gc_global_lock); -#endif - /* region for uncollectable objects */ heap_region_sys = NEW(regioninfo_t); if (!region_create(heap_region_sys, GC_SYS_SIZE)) @@ -124,8 +114,12 @@ void gc_init(u4 heapmaxsize, u4 heapstartsize) /* gc_reference_register ******************************************************* - Register an external reference which points onto the Heap and keeps - objects alive (strong reference). + Register an external reference which points onto the Heap. The + reference needs to be cleared (set to NULL) when registering and + has to be set after it has been registered (to avoid a race condition). + + STRONG REFERENCE: gets updated and keeps objects alive + WEAK REFERENCE: only gets updated (or maybe cleared) *******************************************************************************/ @@ -133,57 +127,81 @@ static void gc_reference_register_intern(list_t *list, java_object_t **ref, int3 { list_gcref_entry_t *re; + /* the global GC lock also guards the reference lists */ + GC_MUTEX_LOCK; + GC_LOG2( printf("Registering Reference at %p\n", (void *) ref); ); /* the reference needs to be registered before it is set, so make sure the reference is not yet set */ GC_ASSERT(*ref == NULL); +#if !defined(NDEBUG) + /* check if this reference is already registered */ + for (re = list_first_unsynced(list); re != NULL; re = list_next_unsynced(list, re)) { + if (re->ref == ref) + vm_abort("gc_reference_register_intern: reference already registered"); + } +#endif + + /* create a new reference entry */ re = NEW(list_gcref_entry_t); - re->ref = ref; + re->ref = ref; #if !defined(NDEBUG) - re->reftype = reftype; + re->reftype = reftype; #endif - list_add_last(list, re); + /* add the entry to the given list */ + list_add_last_unsynced(list, re); + + /* the global GC lock also guards the reference lists */ + GC_MUTEX_UNLOCK; +} + +void gc_reference_register(java_object_t **ref, int32_t reftype) +{ + gc_reference_register_intern(gc_reflist_strong, ref, reftype); } +void gc_weakreference_register(java_object_t **ref, int32_t reftype) +{ + gc_reference_register_intern(gc_reflist_weak, ref, reftype); +} + + +/* gc_reference_unregister ***************************************************** + + Unregister a previously registered external reference. + +*******************************************************************************/ + static void gc_reference_unregister_intern(list_t *list, java_object_t **ref) { list_gcref_entry_t *re; + /* the global GC lock also guards the reference lists */ + GC_MUTEX_LOCK; + GC_LOG2( printf("Un-Registering Reference at %p\n", (void *) ref); ); - for (re = list_first(list); re != NULL; re = list_next(list, re)) { + /* search for the appropriate reference entry */ + for (re = list_first_unsynced(list); re != NULL; re = list_next_unsynced(list, re)) { if (re->ref == ref) { - list_remove(list, re); + /* remove the entry from the given list */ + list_remove_unsynced(list, re); + /* free the reference entry */ FREE(re, list_gcref_entry_t); break; } } - assert(re != NULL); -} - -void gc_reference_register(java_object_t **ref, int32_t reftype) -{ -#if defined(ENABLE_THREADS) - /* XXX dirty hack because threads_init() not yet called */ - if (THREADOBJECT == NULL) { - GC_LOG( dolog("GC: Unable to register Reference!"); ); - return; - } -#endif - - gc_reference_register_intern(gc_reflist_strong, ref, reftype); -} + vm_abort("gc_reference_unregister_intern: reference not found"); -void gc_weakreference_register(java_object_t **ref, int32_t reftype) -{ - gc_reference_register_intern(gc_reflist_weak, ref, reftype); + /* the global GC lock also guards the reference lists */ + GC_MUTEX_UNLOCK; } void gc_reference_unregister(java_object_t **ref) @@ -223,7 +241,7 @@ void gc_collect(s4 level) #endif /* enter the global gc lock */ - LOCK_MONITOR_ENTER(gc_global_lock); + GC_MUTEX_LOCK; /* remember start of dump memory area */ dumpsize = dump_size(); @@ -367,7 +385,7 @@ void gc_collect(s4 level) dump_release(dumpsize); /* leave the global gc lock */ - LOCK_MONITOR_EXIT(gc_global_lock); + GC_MUTEX_UNLOCK; /* XXX move this to an appropriate place */ lock_hashtable_cleanup(); diff --git a/src/mm/cacao-gc/gc.h b/src/mm/cacao-gc/gc.h index b8eeab691..68fbefd59 100644 --- a/src/mm/cacao-gc/gc.h +++ b/src/mm/cacao-gc/gc.h @@ -135,6 +135,17 @@ struct list_gcref_entry_t { }; +/* Global GC mutext stuff *****************************************************/ + +#if defined(ENABLE_THREADS) +# define GC_MUTEX_LOCK threads_mutex_gc_lock() +# define GC_MUTEX_UNLOCK threads_mutex_gc_unlock() +#else +# define GC_MUTEX_LOCK +# define GC_MUTEX_UNLOCK +#endif + + /* No-Thread specific stuff ***************************************************/ #if defined(ENABLE_THREADS) diff --git a/src/threads/native/threads.c b/src/threads/native/threads.c index f4ba1a098..f64af9fec 100644 --- a/src/threads/native/threads.c +++ b/src/threads/native/threads.c @@ -235,6 +235,11 @@ static pthread_mutex_t mutex_threads_list; /* global mutex for stop-the-world */ static pthread_mutex_t stopworldlock; +#if defined(ENABLE_GC_CACAO) +/* global mutex for the GC */ +static pthread_mutex_t mutex_gc; +#endif + /* global mutex and condition for joining threads on exit */ static pthread_mutex_t mutex_join; static pthread_cond_t cond_join; @@ -786,6 +791,12 @@ void threads_impl_preinit(void) pthread_mutex_init(&mutex_join, NULL); pthread_cond_init(&cond_join, NULL); +#if defined(ENABLE_GC_CACAO) + /* initialize the GC mutext */ + + pthread_mutex_init(&mutex_gc, NULL); +#endif + /* initialize the threads-list mutex */ pthread_mutex_init(&mutex_threads_list, NULL); @@ -831,6 +842,37 @@ void threads_list_unlock(void) } +/* threads_mutex_gc_lock ******************************************************* + + Enter the global GC mutex. + +*******************************************************************************/ + +#if defined(ENABLE_GC_CACAO) +void threads_mutex_gc_lock(void) +{ + if (pthread_mutex_lock(&mutex_gc) != 0) + vm_abort("threads_mutex_gc_lock: pthread_mutex_lock failed: %s", + strerror(errno)); +} +#endif + + +/* threads_mutex_gc_unlock ***************************************************** + + Leave the global GC mutex. + +*******************************************************************************/ + +#if defined(ENABLE_GC_CACAO) +void threads_mutex_gc_unlock(void) +{ + if (pthread_mutex_unlock(&mutex_gc) != 0) + vm_abort("threads_mutex_gc_unlock: pthread_mutex_unlock failed: %s", + strerror(errno)); +} +#endif + /* threads_mutex_join_lock ***************************************************** Enter the join mutex. diff --git a/src/threads/threads-common.h b/src/threads/threads-common.h index 3cea52547..f744afbbd 100644 --- a/src/threads/threads-common.h +++ b/src/threads/threads-common.h @@ -151,6 +151,11 @@ void threads_impl_preinit(void); void threads_list_lock(void); void threads_list_unlock(void); +#if defined(ENABLE_GC_CACAO) +void threads_mutex_gc_lock(void); +void threads_mutex_gc_unlock(void); +#endif + void threads_mutex_join_lock(void); void threads_mutex_join_unlock(void);