From 7334cc94a04bf188762c99b2e4bfc932e508bdc2 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 27 Apr 2023 07:33:50 +0300 Subject: Eliminate data race FP between remove_protection and write_fault_handler * os_dep.c [MPROTECT_VDB] (get_pht_entry_from_index_async): Define (as a static function with GC_ATTR_NO_SANITIZE_THREAD or as a macro); add comment. * os_dep.c [!GC_DISABLE_INCREMENTAL && MPROTECT_VDB] (GC_remove_protection): Call get_pht_entry_from_index_async() instead of get_pht_entry_from_index(). --- os_dep.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'os_dep.c') diff --git a/os_dep.c b/os_dep.c index 9b436584..b5d6ef98 100644 --- a/os_dep.c +++ b/os_dep.c @@ -3534,6 +3534,22 @@ STATIC void GC_protect_heap(void) * happens to work. */ +# ifdef THREAD_SANITIZER + /* Used by GC_remove_protection only. Potential data race between */ + /* this function and GC_write_fault_handler should not be harmful */ + /* because it would only result in a double call of UNPROTECT() for */ + /* a region. */ + GC_ATTR_NO_SANITIZE_THREAD + static GC_bool get_pht_entry_from_index_async(volatile page_hash_table db, + size_t index) + { + return (GC_bool)get_pht_entry_from_index(db, index); + } +# else +# define get_pht_entry_from_index_async(bl, index) \ + get_pht_entry_from_index(bl, index) +# endif + /* We no longer wrap read by default, since that was causing too many */ /* problems. It is preferred that the client instead avoids writing */ /* to the write-protected heap with a system call. */ @@ -4245,7 +4261,7 @@ GC_INNER GC_bool GC_dirty_init(void) h_end = (struct hblk *)(((word)(h + nblocks) + GC_page_size - 1) & ~(GC_page_size - 1)); if (h_end == h_trunc + 1 && - get_pht_entry_from_index(GC_dirty_pages, PHT_HASH(h_trunc))) { + get_pht_entry_from_index_async(GC_dirty_pages, PHT_HASH(h_trunc))) { /* already marked dirty, and hence unprotected. */ return; } -- cgit v1.2.1