// SPDX-License-Identifier: LGPL-2.1
#define _GNU_SOURCE
#include <assert.h>
#include <linux/membarrier.h>
#include <pthread.h>
#include <sched.h>
#include <stdatomic.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <unistd.h>
#include <poll.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <stddef.h>
#include <stdbool.h>
static inline pid_t rseq_gettid(void)
{
return syscall(__NR_gettid);
}
#define NR_INJECT 9
static int loop_cnt[NR_INJECT + 1];
static int loop_cnt_1 asm("asm_loop_cnt_1") __attribute__((used));
static int loop_cnt_2 asm("asm_loop_cnt_2") __attribute__((used));
static int loop_cnt_3 asm("asm_loop_cnt_3") __attribute__((used));
static int loop_cnt_4 asm("asm_loop_cnt_4") __attribute__((used));
static int loop_cnt_5 asm("asm_loop_cnt_5") __attribute__((used));
static int loop_cnt_6 asm("asm_loop_cnt_6") __attribute__((used));
static int opt_modulo, verbose;
static int opt_yield, opt_signal, opt_sleep,
opt_disable_rseq, opt_threads = 200,
opt_disable_mod = 0, opt_test = 's';
static long long opt_reps = 5000;
static __thread __attribute__((tls_model("initial-exec")))
unsigned int signals_delivered;
#ifndef BENCHMARK
static __thread __attribute__((tls_model("initial-exec"), unused))
unsigned int yield_mod_cnt, nr_abort;
#define printf_verbose(fmt, ...) \
do { \
if (verbose) \
printf(fmt, ## __VA_ARGS__); \
} while (0)
#ifdef __i386__
#define INJECT_ASM_REG "eax"
#define RSEQ_INJECT_CLOBBER \
, INJECT_ASM_REG
#define RSEQ_INJECT_ASM(n) \
"mov asm_loop_cnt_" #n ", %%" INJECT_ASM_REG "\n\t" \
"test %%" INJECT_ASM_REG ",%%" INJECT_ASM_REG "\n\t" \
"jz 333f\n\t" \
"222:\n\t" \
"dec %%" INJECT_ASM_REG "\n\t" \
"jnz 222b\n\t" \
"333:\n\t"
#elif defined(__x86_64__)
#define INJECT_ASM_REG_P "rax"
#define INJECT_ASM_REG "eax"
#define RSEQ_INJECT_CLOBBER \
, INJECT_ASM_REG_P \
, INJECT_ASM_REG
#define RSEQ_INJECT_ASM(n) \
"lea asm_loop_cnt_" #n "(%%rip), %%" INJECT_ASM_REG_P "\n\t" \
"mov (%%" INJECT_ASM_REG_P "), %%" INJECT_ASM_REG "\n\t" \
"test %%" INJECT_ASM_REG ",%%" INJECT_ASM_REG "\n\t" \
"jz 333f\n\t" \
"222:\n\t" \
"dec %%" INJECT_ASM_REG "\n\t" \
"jnz 222b\n\t" \
"333:\n\t"
#elif defined(__s390__)
#define RSEQ_INJECT_INPUT \
, [loop_cnt_1]"m"(loop_cnt[1]) \
, [loop_cnt_2]"m"(loop_cnt[2]) \
, [loop_cnt_3]"m"(loop_cnt[3]) \
, [loop_cnt_4]"m"(loop_cnt[4]) \
, [loop_cnt_5]"m"(loop_cnt[5]) \
, [loop_cnt_6]"m"(loop_cnt[6])
#define INJECT_ASM_REG "r12"
#define RSEQ_INJECT_CLOBBER \
, INJECT_ASM_REG
#define RSEQ_INJECT_ASM(n) \
"l %%" INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t" \
"ltr %%" INJECT_ASM_REG ", %%" INJECT_ASM_REG "\n\t" \
"je 333f\n\t" \
"222:\n\t" \
"ahi %%" INJECT_ASM_REG ", -1\n\t" \
"jnz 222b\n\t" \
"333
|