diff options
author | Ben Gamari <ben@smart-cactus.org> | 2021-02-23 13:30:48 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2021-02-23 13:44:09 -0500 |
commit | fe28a062e47bd914a6879f2d01ff268983c075ad (patch) | |
tree | e45e052102ac387caafab8a7ccad8e447f9b0db9 | |
parent | ab571457b9960cc05d46d3ae6a3796e760766750 (diff) | |
download | haskell-wip/T19417-ghc-8.10.tar.gz |
rts: Make markLiveObject thread-safewip/T19417-ghc-8.10
markLiveObject is called by GC worker threads and therefore must be
thread-safe. This was a rather egregious oversight which the testsuite
missed.
-rw-r--r-- | rts/CheckUnload.c | 10 | ||||
-rw-r--r-- | rts/LinkerInternals.h | 2 |
2 files changed, 9 insertions, 3 deletions
diff --git a/rts/CheckUnload.c b/rts/CheckUnload.c index fcbe0f6156..d67696a061 100644 --- a/rts/CheckUnload.c +++ b/rts/CheckUnload.c @@ -357,11 +357,16 @@ static ObjectCode *findOC(OCSectionIndices *s_indices, const void *addr) { static bool markObjectLive(void *data STG_UNUSED, StgWord key, const void *value STG_UNUSED) { ObjectCode *oc = (ObjectCode*)key; - if (oc->mark == object_code_mark_bit) { + + // N.B. we may be called by the parallel GC and therefore this must be + // thread-safe. To avoid taking the linker_mutex in the fast path + // (when the object is already marked) we do an atomic exchange here and + // only take the lock in the case that the object is unmarked. + if (xchg(&oc->mark, object_code_mark_bit) == object_code_mark_bit) { return true; // for hash table iteration } - oc->mark = object_code_mark_bit; + ACQUIRE_LOCK(&linker_mutex); // Remove from 'old_objects' list if (oc->prev != NULL) { // TODO(osa): Maybe 'prev' should be a pointer to the referencing @@ -381,6 +386,7 @@ static bool markObjectLive(void *data STG_UNUSED, StgWord key, const void *value objects->prev = oc; } objects = oc; + RELEASE_LOCK(&linker_mutex); // Mark its dependencies iterHashTable(oc->dependencies, NULL, markObjectLive); diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h index 1a83771439..8c977ce767 100644 --- a/rts/LinkerInternals.h +++ b/rts/LinkerInternals.h @@ -221,7 +221,7 @@ typedef struct _ObjectCode { struct _ObjectCode *next_loaded_object; // Mark bit - uint8_t mark; + StgWord mark; // Set of dependencies (ObjectCode*) of the object file. Traverse // dependencies using `iterHashTable`. |