Commit 24bbc3e7 authored by Simon Marlow's avatar Simon Marlow

Allow the linker to run concurrently with the GC

parent 2a103c7d
...@@ -260,7 +260,7 @@ void checkUnload (StgClosure *static_objects) ...@@ -260,7 +260,7 @@ void checkUnload (StgClosure *static_objects)
if (unloaded_objects == NULL) return; if (unloaded_objects == NULL) return;
ACQUIRE_LOCK(&linker_mutex); ACQUIRE_LOCK(&linker_unloaded_mutex);
// Mark every unloadable object as unreferenced initially // Mark every unloadable object as unreferenced initially
for (oc = unloaded_objects; oc; oc = oc->next) { for (oc = unloaded_objects; oc; oc = oc->next) {
...@@ -320,5 +320,5 @@ void checkUnload (StgClosure *static_objects) ...@@ -320,5 +320,5 @@ void checkUnload (StgClosure *static_objects)
freeHashTable(addrs, NULL); freeHashTable(addrs, NULL);
RELEASE_LOCK(&linker_mutex); RELEASE_LOCK(&linker_unloaded_mutex);
} }
...@@ -156,7 +156,15 @@ ObjectCode *objects = NULL; /* initially empty */ ...@@ -156,7 +156,15 @@ ObjectCode *objects = NULL; /* initially empty */
ObjectCode *unloaded_objects = NULL; /* initially empty */ ObjectCode *unloaded_objects = NULL; /* initially empty */
#ifdef THREADED_RTS #ifdef THREADED_RTS
/* This protects all the Linker's global state except unloaded_objects */
Mutex linker_mutex; Mutex linker_mutex;
/*
* This protects unloaded_objects. We have a separate mutex for this, because
* the GC needs to access unloaded_objects in checkUnload, while the linker only
* needs to access unloaded_objects in unloadObj(), so this allows most linker
* operations proceed concurrently with the GC.
*/
Mutex linker_unloaded_mutex;
#endif #endif
/* Type of the initializer */ /* Type of the initializer */
...@@ -1648,6 +1656,7 @@ initLinker_ (int retain_cafs) ...@@ -1648,6 +1656,7 @@ initLinker_ (int retain_cafs)
#if defined(THREADED_RTS) #if defined(THREADED_RTS)
initMutex(&linker_mutex); initMutex(&linker_mutex);
initMutex(&linker_unloaded_mutex);
#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
initMutex(&dl_mutex); initMutex(&dl_mutex);
#endif #endif
...@@ -3235,9 +3244,13 @@ static HsInt unloadObj_ (pathchar *path, rtsBool just_purge) ...@@ -3235,9 +3244,13 @@ static HsInt unloadObj_ (pathchar *path, rtsBool just_purge)
} else { } else {
prev->next = oc->next; prev->next = oc->next;
} }
ACQUIRE_LOCK(&linker_unloaded_mutex);
oc->next = unloaded_objects; oc->next = unloaded_objects;
unloaded_objects = oc; unloaded_objects = oc;
oc->status = OBJECT_UNLOADED; oc->status = OBJECT_UNLOADED;
RELEASE_LOCK(&linker_unloaded_mutex);
// We do not own oc any more; it can be released at any time by
// the GC in checkUnload().
} else { } else {
prev = oc; prev = oc;
} }
......
...@@ -146,6 +146,7 @@ extern ObjectCode *unloaded_objects; ...@@ -146,6 +146,7 @@ extern ObjectCode *unloaded_objects;
#ifdef THREADED_RTS #ifdef THREADED_RTS
extern Mutex linker_mutex; extern Mutex linker_mutex;
extern Mutex linker_unloaded_mutex;
#endif #endif
void exitLinker( void ); void exitLinker( void );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment