aboutsummaryrefslogtreecommitdiff
path: root/libatomic
diff options
context:
space:
mode:
Diffstat (limited to 'libatomic')
-rw-r--r--libatomic/ChangeLog20
-rw-r--r--libatomic/config/mingw/lock.c50
-rw-r--r--libatomic/config/posix/lock.c39
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);
}