On Mon, 14 Apr 2025, Jakub Jelinek wrote: > Hi! > > Here is just a port of the previously posted patch to mingw which > clearly has the same problems. > > Untested though, I don't have Windows anywhere around.
OK. Richard. > 2025-04-14 Jakub Jelinek <ja...@redhat.com> > > PR libstdc++/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. > > --- libatomic/config/mingw/lock.c.jj 2025-04-08 14:09:40.988589457 +0200 > +++ libatomic/config/mingw/lock.c 2025-04-14 15:39:08.244686172 +0200 > @@ -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); > } > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)