This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi! The following patch seems to cure ex5, ex9 and ex10 on ia64/SMP. Basically, if lock->__status had lowest bit set on spin_count 0, it would always spin until max_count, since lock->__status was cached in a register and never reloaded. __compare_and_swap clobbers it, but the codepath with (__status & 1) == 1 skips that, so there is nothing which requires gcc not to reload register caching lock->__status only inside of the conditionally executed code. The patch is attached in two variants, both seem to fix ex5, ex9 and ex10 (the tests which were previously failing on smp ia64), but the first results in better code while the second one is perhaps more readable. The assembly difference is in fact only: ld8 r15=[r32];; in first patch changed to ld8.acq r15=[r32];; in the second. I don't have ia64 manuals here at home so I cannot check, but ld8.acq smells like it would do cache-line ping-pong which is the code exactly trying to avoid (by only doing CAS if normal loads tells it could be successful). 2001-02-17 Jakub Jelinek <jakub@redhat.com> * spinlock.c (__pthread_lock): Force lock->__status to be read from memory on every spin. Jakub
--- linuxthreads/spinlock.c.jj Sat Feb 17 16:09:57 2001 +++ linuxthreads/spinlock.c Sat Feb 17 16:42:41 2001 @@ -88,6 +88,7 @@ again: return; } } + __asm __volatile ("" : "=m" (lock->__status) : "0" (lock->__status)); } lock->__spinlock += (spin_count - lock->__spinlock) / 8;
--- linuxthreads/spinlock.c.jj Sat Feb 17 16:09:57 2001 +++ linuxthreads/spinlock.c Sat Feb 17 16:16:20 2001 @@ -80,7 +80,7 @@ again: int max_count = lock->__spinlock * 2 + 10; for (spin_count = 0; spin_count < max_count; spin_count++) { - if (((oldstatus = lock->__status) & 1) == 0) { + if (((oldstatus = *(volatile long int *)&lock->__status) & 1) == 0) { if(__compare_and_swap(&lock->__status, oldstatus, oldstatus | 1)) { if (spin_count)
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |