criu/test/zdtm/static/pthread01.c
Pavel Emelyanov 2e13f1f029 test: Get rid of live directory
Move static and transition into zdtm top. We can't move all the micro
tests themselves, as we need to distinguish static from non static (zdtm.py
makes additional checks on static ones).

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-02-20 13:40:52 +03:00

209 lines
5.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include "zdtmtst.h"
#define gettid() pthread_self()
const char *test_doc = "Create a few pthreads and test TLS + blocked signals\n";
const char *test_author = "Cyrill Gorcunov <gorcunov@openvz.org";
static __thread struct tls_data_s {
char *rand_string[10];
sigset_t blk_sigset;
} tls_data;
static task_waiter_t t1;
static task_waiter_t t2;
static char *decode_signal(const sigset_t *s, char *buf)
{
buf[0] = '\0';
#define COLLECT(sig) \
do { \
if ((long)s->__val[0] & (long)sigmask(sig)) \
strcat(buf, #sig " "); \
} while (0)
COLLECT(SIGHUP); COLLECT(SIGINT); COLLECT(SIGQUIT); COLLECT(SIGILL); COLLECT(SIGTRAP);
COLLECT(SIGABRT); COLLECT(SIGIOT); COLLECT(SIGBUS); COLLECT(SIGFPE); COLLECT(SIGKILL);
COLLECT(SIGUSR1); COLLECT(SIGSEGV); COLLECT(SIGUSR2); COLLECT(SIGPIPE); COLLECT(SIGALRM);
COLLECT(SIGTERM); COLLECT(SIGSTKFLT); COLLECT(SIGCHLD); COLLECT(SIGCONT); COLLECT(SIGSTOP);
COLLECT(SIGTSTP); COLLECT(SIGTTIN); COLLECT(SIGTTOU); COLLECT(SIGURG); COLLECT(SIGXCPU);
COLLECT(SIGXFSZ); COLLECT(SIGVTALRM); COLLECT(SIGPROF); COLLECT(SIGWINCH); COLLECT(SIGIO);
COLLECT(SIGPOLL); COLLECT(SIGPWR); COLLECT(SIGSYS); COLLECT(SIGUNUSED);
#undef COLLECT
return buf;
}
static void __show_sigset(int line, const sigset_t *s)
{
char buf[sizeof(sigset_t) * 2 + 1] = { };
decode_signal(s, buf);
test_msg("sigset at %4d: %s\n", line, buf);
}
#define show_sigset(set) __show_sigset(__LINE__, set)
static void *ch_thread_2(void *arg)
{
char __tls_data[sizeof(tls_data.rand_string)] = "XM5o:?B*[a";
int *results_map = arg;
sigset_t blk_sigset = { };
sigset_t new = { };
memcpy(tls_data.rand_string, __tls_data, sizeof(tls_data.rand_string));
sigemptyset(&blk_sigset);
pthread_sigmask(SIG_SETMASK, NULL, &blk_sigset);
sigaddset(&blk_sigset, SIGFPE);
pthread_sigmask(SIG_SETMASK, &blk_sigset, NULL);
memcpy(&tls_data.blk_sigset, &blk_sigset, sizeof(tls_data.blk_sigset));
show_sigset(&blk_sigset);
show_sigset(&tls_data.blk_sigset);
task_waiter_complete(&t2, 1);
task_waiter_wait4(&t2, 2);
if (memcmp(tls_data.rand_string, __tls_data, sizeof(tls_data.rand_string))) {
pr_perror("Failed to restore tls_data.rand_string in thread 2");
results_map[2] = -1;
} else
results_map[2] = 1;
if (memcmp(&tls_data.blk_sigset, &blk_sigset, sizeof(tls_data.blk_sigset))) {
pr_perror("Failed to restore tls_data.blk_sigset in thread 2");
results_map[4] = -1;
} else
results_map[4] = 1;
pthread_sigmask(SIG_SETMASK, NULL, &new);
if (memcmp(&tls_data.blk_sigset, &new, sizeof(tls_data.blk_sigset))) {
pr_perror("Failed to restore blk_sigset in thread 2");
results_map[6] = -1;
show_sigset(&tls_data.blk_sigset);
show_sigset(&new);
} else
results_map[6] = 1;
return NULL;
}
static void *ch_thread_1(void *arg)
{
char __tls_data[sizeof(tls_data.rand_string)] = "pffYQSBo?6";
int *results_map = arg;
sigset_t blk_sigset = { };
sigset_t new = { };
memcpy(tls_data.rand_string, __tls_data, sizeof(tls_data.rand_string));
sigemptyset(&blk_sigset);
pthread_sigmask(SIG_SETMASK, NULL, &blk_sigset);
sigaddset(&blk_sigset, SIGWINCH);
sigaddset(&blk_sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK, &blk_sigset, NULL);
memcpy(&tls_data.blk_sigset, &blk_sigset, sizeof(tls_data.blk_sigset));
show_sigset(&blk_sigset);
show_sigset(&tls_data.blk_sigset);
task_waiter_complete(&t1, 1);
task_waiter_wait4(&t1, 2);
if (memcmp(tls_data.rand_string, __tls_data, sizeof(tls_data.rand_string))) {
pr_perror("Failed to restore tls_data.rand_string in thread 1");
results_map[1] = -1;
} else
results_map[1] = 1;
if (memcmp(&tls_data.blk_sigset, &blk_sigset, sizeof(tls_data.blk_sigset))) {
pr_perror("Failed to restore tls_data.blk_sigset in thread 1");
results_map[3] = -1;
} else
results_map[3] = 1;
sigemptyset(&new);
pthread_sigmask(SIG_SETMASK, NULL, &new);
if (memcmp(&tls_data.blk_sigset, &new, sizeof(tls_data.blk_sigset))) {
pr_perror("Failed to restore blk_sigset in thread 1");
results_map[5] = -1;
show_sigset(&tls_data.blk_sigset);
show_sigset(&new);
} else
results_map[5] = 1;
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread_1, thread_2;
int *results_map;
int rc1, rc2;
test_init(argc, argv);
task_waiter_init(&t1);
task_waiter_init(&t2);
test_msg("%s pid %d\n", argv[0], getpid());
results_map = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if ((void *)results_map == MAP_FAILED) {
fail("Can't map");
exit(1);
}
rc1 = pthread_create(&thread_1, NULL, &ch_thread_1, results_map);
rc2 = pthread_create(&thread_2, NULL, &ch_thread_2, results_map);
if (rc1 | rc2) {
fail("Can't pthread_create");
exit(1);
}
test_msg("Waiting until all threads are created\n");
task_waiter_wait4(&t1, 1);
task_waiter_wait4(&t2, 1);
test_daemon();
test_waitsig();
task_waiter_complete(&t1, 2);
task_waiter_complete(&t2, 2);
test_msg("Waiting while all threads are joined\n");
pthread_join(thread_1, NULL);
pthread_join(thread_2, NULL);
if (results_map[1] == 1 &&
results_map[2] == 1 &&
results_map[3] == 1 &&
results_map[4] == 1 &&
results_map[5] == 1 &&
results_map[6] == 1)
pass();
else
fail();
return 0;
}