|
Packit Service |
f2f644 |
/* Test multi-threading using LD_AUDIT.
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
Copyright (C) 2018 Free Software Foundation, Inc.
|
|
Packit Service |
f2f644 |
This file is part of the GNU C Library.
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
The GNU C Library is free software; you can redistribute it and/or
|
|
Packit Service |
f2f644 |
modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
f2f644 |
License as published by the Free Software Foundation; either
|
|
Packit Service |
f2f644 |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
The GNU C Library is distributed in the hope that it will be useful,
|
|
Packit Service |
f2f644 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
f2f644 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
f2f644 |
Lesser General Public License for more details.
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
f2f644 |
License along with the GNU C Library; if not, see
|
|
Packit Service |
f2f644 |
<http://www.gnu.org/licenses/>. */
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
|
|
Packit Service |
f2f644 |
library with a huge number of functions in order to validate lazy symbol
|
|
Packit Service |
f2f644 |
binding with an audit library. We use one thread per CPU to test that
|
|
Packit Service |
f2f644 |
concurrent lazy resolution does not have any defects which would cause
|
|
Packit Service |
f2f644 |
the process to fail. We use an LD_AUDIT library to force the testing of
|
|
Packit Service |
f2f644 |
the relocation resolution caching code in the dynamic loader i.e.
|
|
Packit Service |
f2f644 |
_dl_runtime_profile and _dl_profile_fixup. */
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
#include <support/xthread.h>
|
|
Packit Service |
f2f644 |
#include <strings.h>
|
|
Packit Service |
f2f644 |
#include <stdlib.h>
|
|
Packit Service |
f2f644 |
#include <sys/sysinfo.h>
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
static int do_test (void);
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
/* This test usually takes less than 3s to run. However, there are cases that
|
|
Packit Service |
f2f644 |
take up to 30s. */
|
|
Packit Service |
f2f644 |
#define TIMEOUT 60
|
|
Packit Service |
f2f644 |
#define TEST_FUNCTION do_test ()
|
|
Packit Service |
f2f644 |
#include "../test-skeleton.c"
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
/* Declare the functions we are going to call. */
|
|
Packit Service |
f2f644 |
#define externnum
|
|
Packit Service |
f2f644 |
#include "tst-audit-threads.h"
|
|
Packit Service |
f2f644 |
#undef externnum
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
int num_threads;
|
|
Packit Service |
f2f644 |
pthread_barrier_t barrier;
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
void
|
|
Packit Service |
f2f644 |
sync_all (int num)
|
|
Packit Service |
f2f644 |
{
|
|
Packit Service |
f2f644 |
pthread_barrier_wait (&barrier);
|
|
Packit Service |
f2f644 |
}
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
void
|
|
Packit Service |
f2f644 |
call_all_ret_nums (void)
|
|
Packit Service |
f2f644 |
{
|
|
Packit Service |
f2f644 |
/* Call each function one at a time from all threads. */
|
|
Packit Service |
f2f644 |
#define callnum
|
|
Packit Service |
f2f644 |
#include "tst-audit-threads.h"
|
|
Packit Service |
f2f644 |
#undef callnum
|
|
Packit Service |
f2f644 |
}
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
void *
|
|
Packit Service |
f2f644 |
thread_main (void *unused)
|
|
Packit Service |
f2f644 |
{
|
|
Packit Service |
f2f644 |
call_all_ret_nums ();
|
|
Packit Service |
f2f644 |
return NULL;
|
|
Packit Service |
f2f644 |
}
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
#define STR2(X) #X
|
|
Packit Service |
f2f644 |
#define STR(X) STR2(X)
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
static int
|
|
Packit Service |
f2f644 |
do_test (void)
|
|
Packit Service |
f2f644 |
{
|
|
Packit Service |
f2f644 |
int i;
|
|
Packit Service |
f2f644 |
pthread_t *threads;
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
num_threads = get_nprocs ();
|
|
Packit Service |
f2f644 |
if (num_threads <= 1)
|
|
Packit Service |
f2f644 |
num_threads = 2;
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
/* Used to synchronize all the threads after calling each retNumN. */
|
|
Packit Service |
f2f644 |
xpthread_barrier_init (&barrier, NULL, num_threads);
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
|
|
Packit Service |
f2f644 |
for (i = 0; i < num_threads; i++)
|
|
Packit Service |
f2f644 |
threads[i] = xpthread_create(NULL, thread_main, NULL);
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
for (i = 0; i < num_threads; i++)
|
|
Packit Service |
f2f644 |
xpthread_join(threads[i]);
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
free (threads);
|
|
Packit Service |
f2f644 |
|
|
Packit Service |
f2f644 |
return 0;
|
|
Packit Service |
f2f644 |
}
|