Use generic pthread support on hppa.

This commit is contained in:
John David Anglin 2017-07-09 15:01:11 -04:00
parent 58d021c836
commit c5f70682a5
9 changed files with 42 additions and 382 deletions

View File

@ -1,3 +1,25 @@
2017-07-09 John David Anglin <danglin@gcc.gnu.org>
[BZ #21016]
* sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s):
Fix typo.
* sysdeps/unix/sysv/linux/hppa/pthread.h: Include
bits/types/struct_timespec.h.
(PTHREAD_MUTEX_INITIALIZER): Revise define.
(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Likewise.
(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise.
(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP): Likewise.
(PTHREAD_RWLOCK_INITIALIZER): Likewise.
(PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP): Likewise.
(PTHREAD_COND_INITIALIZER): Likewise.
Remove old definitions.
* sysdeps/unix/sysv/linux/hppa/internaltypes.h: Delete.
* sysdeps/unix/sysv/linux/hppa/pthread_cond_broadcast.c: Delete.
* sysdeps/unix/sysv/linux/hppa/pthread_cond_destroy.c: Delete.
* sysdeps/unix/sysv/linux/hppa/pthread_cond_init.c: Delete.
* sysdeps/unix/sysv/linux/hppa/pthread_cond_signal.c: Delete.
* sysdeps/unix/sysv/linux/hppa/pthread_cond_wait.c: Delete.
2017-07-09 H.J. Lu <hongjiu.lu@intel.com>
* sysdeps/x86_64/multiarch/memcmp.c: Update comments.

View File

@ -118,7 +118,7 @@ struct __pthread_mutex_s
{
__PTHREAD_SPINS_DATA;
__pthread_slist_t __list;
}
};
#endif
__PTHREAD_COMPAT_PADDING_END;
};

View File

@ -1,84 +0,0 @@
#include_next <internaltypes.h>
#ifndef _INTERNAL_TYPES_H_HPPA_
#define _INTERNAL_TYPES_H_HPPA_ 1
#include <atomic.h>
/* In GLIBC 2.10 HPPA switched from Linuxthreads to NPTL, and in order
to maintain ABI compatibility with pthread_cond_t, some care had to be
taken.
The NPTL pthread_cond_t grew in size. When HPPA switched to NPTL, we
dropped the use of ldcw, and switched to the kernel helper routine for
compare-and-swap. This allowed HPPA to use the 4-word 16-byte aligned
lock words, and alignment words to store the additional pthread_cond_t
data. Once organized properly the new NPTL pthread_cond_t was 1 word
smaller than the Linuxthreads version.
However, we were faced with the case that users may have initialized the
pthread_cond_t with PTHREAD_COND_INITIALIZER. In this case, the first
four words were set to one, and must be cleared before any NPTL code
used these words.
We didn't want to use LDCW, because it continues to be a source of bugs
when applications memset pthread_cond_t to all zeroes by accident. This
works on all other architectures where lock words are unlocked at zero.
Remember that because of the semantics of LDCW, a locked word is set to
zero, and an unlocked word is set to 1.
Instead we used atomic_compare_and_exchange_val_acq, but we couldn't use
this on any of the pthread_cond_t words, otherwise it might interfere
with the current operation of the structure. To solve this problem we
used the left over word.
If the stucture was initialized by a legacy Linuxthread
PTHREAD_COND_INITIALIZER it contained a 1, and this indicates that the
structure requires zeroing for NPTL. The first thread to come upon a
pthread_cond_t with a 1 in the __initializer field, will
compare-and-swap the value, placing a 2 there which will cause all other
threads using the same pthread_cond_t to wait for the completion of the
initialization. Lastly, we use a store (with memory barrier) to change
__initializer from 2 to 0. Note that the store is strongly ordered, but
we use the PA 1.1 compatible form which is ",ma" with zero offset.
In the future, when the application is recompiled with NPTL
PTHREAD_COND_INITIALIZER it will be a quick compare-and-swap, which
fails because __initializer is zero, and the structure will be used as
is correctly. */
#define cond_compat_clear(var) \
({ \
int tmp = 0; \
var->__data.__wseq = 0; \
var->__data.__signals_sent = 0; \
var->__data.__confirmed = 0; \
var->__data.__generation = 0; \
var->__data.__mutex = NULL; \
var->__data.__quiescence_waiters = 0; \
var->__data.__clockid = 0; \
/* Clear __initializer last, to indicate initialization is done. */ \
/* This synchronizes-with the acquire load below. */ \
atomic_store_release (&var->__data.__initializer, 0); \
})
#define cond_compat_check_and_clear(var) \
({ \
int v; \
int *value = &var->__data.__initializer; \
/* This synchronizes-with the release store above. */ \
while ((v = atomic_load_acquire (value)) != 0) \
{ \
if (v == 1 \
/* Relaxed MO is fine; it only matters who's first. */ \
&& atomic_compare_exchange_acquire_weak_relaxed (value, 1, 2)) \
{ \
/* We're first; initialize structure. */ \
cond_compat_clear (var); \
break; \
} \
else \
/* Yield before we re-check initialization status. */ \
sched_yield (); \
} \
})
#endif

View File

@ -26,6 +26,7 @@
#include <bits/pthreadtypes.h>
#include <bits/setjmp.h>
#include <bits/wordsize.h>
#include <bits/types/struct_timespec.h>
/* Detach state. */
@ -82,32 +83,18 @@ enum
#endif
#ifdef __PTHREAD_MUTEX_HAVE_PREV
# define PTHREAD_MUTEX_INITIALIZER \
{ { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } }
# ifdef __USE_GNU
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __PTHREAD_SPINS, { 0, 0 } } }
# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
# endif
#else
# define PTHREAD_MUTEX_INITIALIZER \
{ { 0, 0, 0, 0, 0, { __PTHREAD_SPINS } } }
# ifdef __USE_GNU
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { __PTHREAD_SPINS } } }
# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { __PTHREAD_SPINS } } }
# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { __PTHREAD_SPINS } } }
# endif
#define PTHREAD_MUTEX_INITIALIZER \
{ { 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, { __PTHREAD_SPINS }, { 0, 0 } } }
#ifdef __USE_GNU
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, { 0, 0, 0, 0 }, 0, \
{ __PTHREAD_SPINS }, { 0, 0 } } }
# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, { 0, 0, 0, 0 }, 0, \
{ __PTHREAD_SPINS }, { 0, 0 } } }
# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, { 0, 0, 0, 0 }, 0, \
{ __PTHREAD_SPINS }, { 0, 0 } } }
#endif
@ -130,25 +117,14 @@ enum
# endif
#endif
/* Read-write lock initializers. */
# define PTHREAD_RWLOCK_INITIALIZER \
{ { 0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, 0 } }
{ { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
# ifdef __USE_GNU
# ifdef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { 0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, \
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, 0 } }
# else
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
0 } }
# endif
# endif
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0, 0, 0 } }
# endif
#endif /* Unix98 or XOpen2K */
@ -183,9 +159,8 @@ enum
};
/* Conditional variable handling. */
#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }
#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
/* Cleanup buffers */
@ -1161,43 +1136,3 @@ __NTH (pthread_equal (pthread_t __thread1, pthread_t __thread2))
__END_DECLS
#endif /* pthread.h */
#ifndef _PTHREAD_H_HPPA_
#define _PTHREAD_H_HPPA_ 1
/* The pthread_cond_t initializer is compatible only with NPTL. We do not
want to be forwards compatible, we eventually want to drop the code
that has to clear the old LT initializer. */
#undef PTHREAD_COND_INITIALIZER
#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, (void *) 0, 0, 0, 0, 0, 0 } }
/* The pthread_mutex_t and pthread_rwlock_t initializers are compatible
only with NPTL. NPTL assumes pthread_rwlock_t is all zero. */
#undef PTHREAD_MUTEX_INITIALIZER
#undef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#undef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
#undef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
/* Mutex initializers. */
#define PTHREAD_MUTEX_INITIALIZER \
{ { 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
#ifdef __USE_GNU
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
#endif
#undef PTHREAD_RWLOCK_INITIALIZER
#undef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
/* Read-write lock initializers. */
#define PTHREAD_RWLOCK_INITIALIZER \
{ { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
#ifdef __USE_GNU
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
0, 0, 0 } }
#endif /* Unix98 or XOpen2K */
#endif

View File

@ -1,40 +0,0 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef INCLUDED_SELF
# define INCLUDED_SELF
# include <pthread_cond_broadcast.c>
#else
# include <pthread.h>
# include <pthreadP.h>
# include <internaltypes.h>
# include <shlib-compat.h>
int
__pthread_cond_broadcast (pthread_cond_t *cond)
{
cond_compat_check_and_clear (cond);
return __pthread_cond_broadcast_internal (cond);
}
versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
GLIBC_2_3_2);
# undef versioned_symbol
# define versioned_symbol(lib, local, symbol, version)
# undef __pthread_cond_broadcast
# define __pthread_cond_broadcast __pthread_cond_broadcast_internal
# include_next <pthread_cond_broadcast.c>
#endif

View File

@ -1,40 +0,0 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef INCLUDED_SELF
# define INCLUDED_SELF
# include <pthread_cond_destroy.c>
#else
# include <pthread.h>
# include <pthreadP.h>
# include <internaltypes.h>
# include <shlib-compat.h>
int
__pthread_cond_destroy (pthread_cond_t *cond)
{
cond_compat_check_and_clear (cond);
return __pthread_cond_destroy_internal (cond);
}
versioned_symbol (libpthread, __pthread_cond_destroy, pthread_cond_destroy,
GLIBC_2_3_2);
# undef versioned_symbol
# define versioned_symbol(lib, local, symbol, version)
# undef __pthread_cond_destroy
# define __pthread_cond_destroy __pthread_cond_destroy_internal
# include_next <pthread_cond_destroy.c>
#endif

View File

@ -1,40 +0,0 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef INCLUDED_SELF
# define INCLUDED_SELF
# include <pthread_cond_init.c>
#else
# include <pthread.h>
# include <pthreadP.h>
# include <internaltypes.h>
# include <shlib-compat.h>
int
__pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
{
cond_compat_clear (cond);
return __pthread_cond_init_internal (cond, cond_attr);
}
versioned_symbol (libpthread, __pthread_cond_init, pthread_cond_init,
GLIBC_2_3_2);
# undef versioned_symbol
# define versioned_symbol(lib, local, symbol, version)
# undef __pthread_cond_init
# define __pthread_cond_init __pthread_cond_init_internal
# include_next <pthread_cond_init.c>
#endif

View File

@ -1,40 +0,0 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef INCLUDED_SELF
# define INCLUDED_SELF
# include <pthread_cond_signal.c>
#else
# include <pthread.h>
# include <pthreadP.h>
# include <internaltypes.h>
# include <shlib-compat.h>
int
__pthread_cond_signal (pthread_cond_t *cond)
{
cond_compat_check_and_clear (cond);
return __pthread_cond_signal_internal (cond);
}
versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
GLIBC_2_3_2);
# undef versioned_symbol
# define versioned_symbol(lib, local, symbol, version)
# undef __pthread_cond_signal
# define __pthread_cond_signal __pthread_cond_signal_internal
# include_next <pthread_cond_signal.c>
#endif

View File

@ -1,53 +0,0 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef INCLUDED_SELF
# define INCLUDED_SELF
# include <pthread_cond_wait.c>
#else
# include <pthread.h>
# include <pthreadP.h>
# include <internaltypes.h>
# include <shlib-compat.h>
int
__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
{
cond_compat_check_and_clear (cond);
return __pthread_cond_wait_internal (cond, mutex);
}
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
GLIBC_2_3_2);
int
__pthread_cond_timedwait (cond, mutex, abstime)
pthread_cond_t *cond;
pthread_mutex_t *mutex;
const struct timespec *abstime;
{
cond_compat_check_and_clear (cond);
return __pthread_cond_timedwait_internal (cond, mutex, abstime);
}
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2);
# undef versioned_symbol
# define versioned_symbol(lib, local, symbol, version)
# undef __pthread_cond_wait
# define __pthread_cond_wait __pthread_cond_wait_internal
# undef __pthread_cond_timedwait
# define __pthread_cond_timedwait __pthread_cond_timedwait_internal
# include_next <pthread_cond_wait.c>
#endif