/* SPDX-FileCopyrightText: 2021 John Scott <jscott@posteo.net>
 * SPDX-License-Identifier: GPL-3.0-or-later */
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <errno.h>
#include <signal.h>
#if __STDC_NO_ATOMICS__
#error atomics support seems to be missing
#endif
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Using atomic types is not strictly necessary since these signals
 * are currently only received and dealt with syncronously. We ought
 * to test asyncronous signal handling, but there doesn't seem to
 * be a supported way to do that with Newlib and the simulator. */
static atomic_flag flag = ATOMIC_FLAG_INIT;
static atomic_uint count;

static void handler(int a) {
	if(!atomic_flag_test_and_set(&flag)) {
		count++;
	}
	if(signal(SIGUSR1, handler) == SIG_ERR) {
		perror("Failed to establish signal handler");
		abort();
	}
}

int main(void) {
	assert(atomic_is_lock_free(&count));
	if(signal(SIGUSR1, handler) == SIG_ERR) {
		perror("Failed to establish signal handler");
		abort();
	}
	for(int i = 0; i < 10; i++) {
		if(raise(SIGUSR1)) {
			perror("Failed to raise SIGUSR1");
			abort();
		}
	}
	assert(count == 1U);
}
