diff options
Diffstat (limited to 'libatomic')
-rw-r--r-- | libatomic/ChangeLog | 20 | ||||
-rw-r--r-- | libatomic/config/mingw/lock.c | 50 | ||||
-rw-r--r-- | libatomic/config/posix/lock.c | 39 |
3 files changed, 75 insertions, 34 deletions
diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog index ac7e729..62e6c4e 100644 --- a/libatomic/ChangeLog +++ b/libatomic/ChangeLog @@ -1,3 +1,23 @@ +2025-04-16 Jakub Jelinek <jakub@redhat.com> + + PR libgcc/101075 + PR libgcc/119796 + * config/mingw/lock.c (libat_lock_n, libat_unlock_n): Start with + computing how many locks will be needed and take into account + ((uintptr_t)ptr % WATCH_SIZE). If some locks from the end of the + locks array and others from the start of it will be needed, first + lock the ones from the start followed by ones from the end. + +2025-04-16 Jakub Jelinek <jakub@redhat.com> + + PR libgcc/101075 + PR libgcc/119796 + * config/posix/lock.c (libat_lock_n, libat_unlock_n): Start with + computing how many locks will be needed and take into account + ((uintptr_t)ptr % WATCH_SIZE). If some locks from the end of the + locks array and others from the start of it will be needed, first + lock the ones from the start followed by ones from the end. + 2025-01-10 Wilco Dijkstra <wilco.dijkstra@arm.com> * config/linux/aarch64/host-config.h (has_lse2): Cleanup. diff --git a/libatomic/config/mingw/lock.c b/libatomic/config/mingw/lock.c index 17faa66..8b0b4dd 100644 --- a/libatomic/config/mingw/lock.c +++ b/libatomic/config/mingw/lock.c @@ -87,21 +87,30 @@ libat_lock_n (void *ptr, size_t n) { uintptr_t h = addr_hash (ptr); size_t i = 0; + size_t nlocks + = (n + ((uintptr_t)ptr % WATCH_SIZE) + WATCH_SIZE - 1) / WATCH_SIZE; /* Don't lock more than all the locks we have. */ - if (n > PAGE_SIZE) - n = PAGE_SIZE; + if (nlocks > NLOCKS) + nlocks = NLOCKS; - do + if (__builtin_expect (h + nlocks > NLOCKS, 0)) + { + size_t j = h + nlocks - NLOCKS; + for (; i < j; ++i) + { + if (!locks[i].mutex) + locks[i].mutex = CreateMutex (NULL, FALSE, NULL); + WaitForSingleObject (locks[i].mutex, INFINITE); + } + } + + for (; i < nlocks; ++i) { if (!locks[h].mutex) - locks[h].mutex = CreateMutex (NULL, FALSE, NULL); - WaitForSingleObject (locks[h].mutex, INFINITE); - if (++h == NLOCKS) - h = 0; - i += WATCH_SIZE; + locks[h].mutex = CreateMutex (NULL, FALSE, NULL); + WaitForSingleObject (locks[h++].mutex, INFINITE); } - while (i < n); } void @@ -109,17 +118,22 @@ libat_unlock_n (void *ptr, size_t n) { uintptr_t h = addr_hash (ptr); size_t i = 0; + size_t nlocks + = (n + ((uintptr_t)ptr % WATCH_SIZE) + WATCH_SIZE - 1) / WATCH_SIZE; - if (n > PAGE_SIZE) - n = PAGE_SIZE; + /* Don't lock more than all the locks we have. */ + if (nlocks > NLOCKS) + nlocks = NLOCKS; - do + if (__builtin_expect (h + nlocks > NLOCKS, 0)) { - if (locks[h].mutex) - ReleaseMutex (locks[h].mutex); - if (++h == NLOCKS) - h = 0; - i += WATCH_SIZE; + size_t j = h + nlocks - NLOCKS; + for (; i < j; ++i) + if (locks[i].mutex) + ReleaseMutex (locks[i].mutex); } - while (i < n); + + for (; i < nlocks; ++i, ++h) + if (locks[h].mutex) + ReleaseMutex (locks[h].mutex); } diff --git a/libatomic/config/posix/lock.c b/libatomic/config/posix/lock.c index 6ee4240..5662b77 100644 --- a/libatomic/config/posix/lock.c +++ b/libatomic/config/posix/lock.c @@ -81,19 +81,22 @@ libat_lock_n (void *ptr, size_t n) { uintptr_t h = addr_hash (ptr); size_t i = 0; + size_t nlocks + = (n + ((uintptr_t)ptr % WATCH_SIZE) + WATCH_SIZE - 1) / WATCH_SIZE; /* Don't lock more than all the locks we have. */ - if (n > PAGE_SIZE) - n = PAGE_SIZE; + if (nlocks > NLOCKS) + nlocks = NLOCKS; - do + if (__builtin_expect (h + nlocks > NLOCKS, 0)) { - pthread_mutex_lock (&locks[h].mutex); - if (++h == NLOCKS) - h = 0; - i += WATCH_SIZE; + size_t j = h + nlocks - NLOCKS; + for (; i < j; ++i) + pthread_mutex_lock (&locks[i].mutex); } - while (i < n); + + for (; i < nlocks; ++i) + pthread_mutex_lock (&locks[h++].mutex); } void @@ -101,16 +104,20 @@ libat_unlock_n (void *ptr, size_t n) { uintptr_t h = addr_hash (ptr); size_t i = 0; + size_t nlocks + = (n + ((uintptr_t)ptr % WATCH_SIZE) + WATCH_SIZE - 1) / WATCH_SIZE; - if (n > PAGE_SIZE) - n = PAGE_SIZE; + /* Don't lock more than all the locks we have. */ + if (nlocks > NLOCKS) + nlocks = NLOCKS; - do + if (__builtin_expect (h + nlocks > NLOCKS, 0)) { - pthread_mutex_unlock (&locks[h].mutex); - if (++h == NLOCKS) - h = 0; - i += WATCH_SIZE; + size_t j = h + nlocks - NLOCKS; + for (; i < j; ++i) + pthread_mutex_unlock (&locks[i].mutex); } - while (i < n); + + for (; i < nlocks; ++i) + pthread_mutex_unlock (&locks[h++].mutex); } |