Просмотр исходного кода

or1k: put the rwlock flags byte where the initializers write it

or1k is big endian but declared the little endian order of the four char
fields in pthread_rwlock_t, so __flags came first in the word.  The generic
initializers in pthread.h are positional and pick their order by endianness:
for 32 bit big endian they put the value in the tenth of eleven members, the
last of the four chars.  The two therefore disagreed, and
PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP wrote its 2 into __pad2
while __flags stayed 0.  Measured in the object file: offsetof(__flags) was
24 and the value landed at offset 27.

Effect beyond the test: a statically initialized rwlock silently got reader
preference instead of writer preference.  pthread_rwlock_init() was never
affected, it assigns by member.

Big endian order unconditionally, like powerpc and sparc -- OpenRISC is big
endian only, from gcc (which has no -mlittle-endian) through binutils to
arch/openrisc/Kconfig, which has CPU_BIG_ENDIAN as an unselectable def_bool y.

Fixes all ten tst-initializers1 variants, verified under qemu-or1k against
6.1.53: 768 passed, 1 failed, 7 skipped, was 758/11/7.  The one
remaining failure, tst-tls3-O2, is unrelated: the initial thread's descriptor
is only 4 byte aligned there and the test wants 16.

Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
ramin 1 неделя назад
Родитель
Сommit
594d0a2ad1
1 измененных файлов с 5 добавлено и 3 удалено
  1. 5 3
      libpthread/nptl/sysdeps/unix/sysv/linux/or1k/bits/pthreadtypes.h

+ 5 - 3
libpthread/nptl/sysdeps/unix/sysv/linux/or1k/bits/pthreadtypes.h

@@ -128,12 +128,14 @@ typedef union
     unsigned int __writer_wakeup;
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
+    /* or1k is big endian, so this is the big endian order, like powerpc
+       and sparc.  */
+    unsigned char __pad1;
+    unsigned char __pad2;
+    unsigned char __shared;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned char __flags;
-    unsigned char __shared;
-    unsigned char __pad1;
-    unsigned char __pad2;
     int __writer;
   } __data;
   char __size[__SIZEOF_PTHREAD_RWLOCK_T];