tools/testing/selftests/timers/posix_timers.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/timers/posix_timers.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/timers/posix_timers.c
Extension
.c
Size
18177 bytes
Lines
726
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tmrsig {
	int	signals;
	int	overruns;
};

static void siginfo_handler(int sig, siginfo_t *si, void *uc)
{
	struct tmrsig *tsig = si ? si->si_ptr : NULL;

	if (tsig) {
		tsig->signals++;
		tsig->overruns += si->si_overrun;
	}
}

static void *ignore_thread(void *arg)
{
	unsigned int *tid = arg;
	sigset_t set;

	sigemptyset(&set);
	sigaddset(&set, SIGUSR1);
	if (sigprocmask(SIG_BLOCK, &set, NULL))
		fatal_error(NULL, "sigprocmask(SIG_BLOCK)");

	*tid = gettid();
	sleep(100);

	if (sigprocmask(SIG_UNBLOCK, &set, NULL))
		fatal_error(NULL, "sigprocmask(SIG_UNBLOCK)");
	return NULL;
}

static void check_sig_ign(int thread)
{
	struct tmrsig tsig = { };
	struct itimerspec its;
	unsigned int tid = 0;
	struct sigaction sa;
	struct sigevent sev;
	pthread_t pthread;
	timer_t timerid;
	sigset_t set;

	if (thread) {
		if (pthread_create(&pthread, NULL, ignore_thread, &tid))
			fatal_error(NULL, "pthread_create()");
		sleep(1);
	}

	sa.sa_flags = SA_SIGINFO;
	sa.sa_sigaction = siginfo_handler;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGUSR1, &sa, NULL))
		fatal_error(NULL, "sigaction()");

	/* Block the signal */
	sigemptyset(&set);
	sigaddset(&set, SIGUSR1);
	if (sigprocmask(SIG_BLOCK, &set, NULL))
		fatal_error(NULL, "sigprocmask(SIG_BLOCK)");

	memset(&sev, 0, sizeof(sev));
	sev.sigev_notify = SIGEV_SIGNAL;
	sev.sigev_signo = SIGUSR1;
	sev.sigev_value.sival_ptr = &tsig;
	if (thread) {
		sev.sigev_notify = SIGEV_THREAD_ID;
		sev._sigev_un._tid = tid;
	}

	if (timer_create(CLOCK_MONOTONIC, &sev, &timerid))
		fatal_error(NULL, "timer_create()");

	/* Start the timer to expire in 100ms and 100ms intervals */
	its.it_value.tv_sec = 0;
	its.it_value.tv_nsec = 100000000;
	its.it_interval.tv_sec = 0;
	its.it_interval.tv_nsec = 100000000;
	timer_settime(timerid, 0, &its, NULL);

	sleep(1);

	/* Set the signal to be ignored */
	if (signal(SIGUSR1, SIG_IGN) == SIG_ERR)
		fatal_error(NULL, "signal(SIG_IGN)");

	sleep(1);

	if (thread) {

Annotation

Implementation Notes