Fixes for very early use of the pthread_mutex_* and libthr malloc.

When libthr is statically linked into the binary, order of the
constructors execution is not deterministic.  It is possible for the
application constructor to use pthread_mutex_* functions before the
libthr initialization was done.

Handle it by:
- making thr_malloc.c locking functions operational when curthread is not
  yet set;
- making __thr_malloc_init() idempotent, allowing more than one call to it;
- unconditionally calling __thr_malloc_init() before initializing
  a process-private mutex.

Reported and tested by:	mmel
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2019-02-04 21:16:15 +00:00
parent bfce461ee9
commit e4314da2e4
2 changed files with 7 additions and 0 deletions

View File

@ -46,6 +46,8 @@ void
__thr_malloc_init(void)
{
if (npagesizes != 0)
return;
npagesizes = getpagesizes(pagesizes_d, nitems(pagesizes_d));
if (npagesizes == -1) {
npagesizes = 1;
@ -59,6 +61,8 @@ static void
thr_malloc_lock(struct pthread *curthread)
{
if (curthread == NULL)
return;
curthread->locklevel++;
_thr_umutex_lock(&thr_malloc_umtx, TID(curthread));
}
@ -67,6 +71,8 @@ static void
thr_malloc_unlock(struct pthread *curthread)
{
if (curthread == NULL)
return;
_thr_umutex_unlock(&thr_malloc_umtx, TID(curthread));
curthread->locklevel--;
_thr_ast(curthread);

View File

@ -390,6 +390,7 @@ __pthread_mutex_init(pthread_mutex_t * __restrict mutex,
}
if (mutex_attr == NULL ||
(*mutex_attr)->m_pshared == PTHREAD_PROCESS_PRIVATE) {
__thr_malloc_init();
return (mutex_init(mutex, mutex_attr ? *mutex_attr : NULL,
__thr_calloc));
}