drd/tests/swapcontext: Improve the portability of this test further

- Remove the VALGRIND_STACK_REGISTER() invocation for the initial thread
  stack since it is superfluous. Remove the pthread_attr_getstack() call
  that became superfluous by this change.
- Change SIGINT into SIGALRM for FreeBSD since pthread_kill(..., SIGINT)
  causes the application to return a SIGINT status.
- Reduce the stack size of the threads created by this test.
This commit is contained in:
Bart Van Assche 2021-02-23 11:49:14 -08:00
parent ea98cccb4d
commit caf05d5ca9
2 changed files with 21 additions and 32 deletions

View File

@ -2,7 +2,8 @@
#define _GNU_SOURCE
#include <poll.h>
#include <assert.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
@ -13,6 +14,8 @@
#include <unistd.h>
#include "valgrind.h"
#define STACKSIZE (PTHREAD_STACK_MIN + 4096)
typedef struct thread_local {
ucontext_t uc[3];
size_t nrsw;
@ -21,7 +24,6 @@ typedef struct thread_local {
static void f(void *data, int n)
{
enum { NR_SWITCHES = 200000 };
struct pollfd pfd;
thread_local_t *tlocal = data;
while (1) {
@ -33,29 +35,9 @@ static void f(void *data, int n)
}
}
void __valgrind_register_current_stack(void)
{
pthread_attr_t attr;
size_t stacksize;
void *stack;
if (pthread_getattr_np(pthread_self(), &attr) != 0)
abort();
if (pthread_attr_getstack(&attr, &stack, &stacksize) != 0)
abort();
VALGRIND_STACK_REGISTER(stack, stack + stacksize);
}
#define STACKSIZE 8192
void *worker(void *data)
{
thread_local_t *tlocal = data;
struct itimerspec it;
__valgrind_register_current_stack();
if (getcontext(&(tlocal->uc[1])) < 0)
abort();
@ -66,17 +48,17 @@ void *worker(void *data)
tlocal->uc[1].uc_stack.ss_sp = malloc(STACKSIZE);
tlocal->uc[1].uc_stack.ss_size = STACKSIZE;
makecontext(&tlocal->uc[1], (void (*)(void))f, 2, tlocal, 1);
VALGRIND_STACK_REGISTER(tlocal->uc[1].uc_stack.ss_sp,
tlocal->uc[1].uc_stack.ss_sp +
tlocal->uc[1].uc_stack.ss_size);
(void)VALGRIND_STACK_REGISTER(tlocal->uc[1].uc_stack.ss_sp,
tlocal->uc[1].uc_stack.ss_sp +
tlocal->uc[1].uc_stack.ss_size);
tlocal->uc[2].uc_link = &tlocal->uc[0];
tlocal->uc[2].uc_stack.ss_sp = malloc(STACKSIZE);
tlocal->uc[2].uc_stack.ss_size = STACKSIZE;
makecontext(&tlocal->uc[2], (void (*)(void))f, 2, tlocal, 2);
VALGRIND_STACK_REGISTER(tlocal->uc[2].uc_stack.ss_sp,
tlocal->uc[2].uc_stack.ss_sp +
tlocal->uc[2].uc_stack.ss_size);
(void)VALGRIND_STACK_REGISTER(tlocal->uc[2].uc_stack.ss_sp,
tlocal->uc[2].uc_stack.ss_sp +
tlocal->uc[2].uc_stack.ss_size);
swapcontext(&tlocal->uc[0], &tlocal->uc[1]);
return NULL;
@ -87,17 +69,24 @@ int main(int argc, char *argv[])
enum { NR = 32 };
thread_local_t tlocal[NR];
pthread_t thread[NR];
int i;
pthread_attr_t attr;
int i, res;
memset(tlocal, 0, sizeof(tlocal));
pthread_attr_init(&attr);
res = pthread_attr_setstacksize(&attr, STACKSIZE);
assert(res == 0);
for (i = 0; i < NR; i++)
pthread_create(&thread[i], NULL, worker, &tlocal[i]);
pthread_create(&thread[i], &attr, worker, &tlocal[i]);
pthread_attr_destroy(&attr);
// Wait until the threads have been created.
sleep(1);
for (i = 0; i < NR; i++)
pthread_kill(thread[i], SIGINT);
pthread_kill(thread[i], SIGALRM);
for (i = 0; i < NR; i++)
pthread_join(thread[i], NULL);

View File

@ -1,6 +1,6 @@
Process terminating with default action of signal 2 (SIGINT)
Process terminating with default action of signal 14 (SIGALRM)
at 0x........: swapcontext (in /...libc...)
by 0x........: f (swapcontext.c:?)