Milan Stephan
Fotografie & IT

Zurück zur SP2 Übersicht

cas.c

#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>

#ifdef __STDC_NO_ATOMICS__
	#error No support for C11 Atomics
#endif

static void sleep_one_second(void);
static void handler(int signum);


// _Atomic: Atomare Updates. volatile nicht nötig.
static _Atomic int counter = ATOMIC_VAR_INIT(0);

static void handler(int signum) {
	// Increment (atomic version of counter++)
	// Bitte so verwenden:
	atomic_fetch_add(&counter, 1);
}

int main(void) {

	struct sigaction sa = {
		.sa_handler = handler,
		.sa_flags = SA_RESTART,
	};
	sigemptyset(&sa.sa_mask);
	sigaction(SIGINT, &sa, NULL);

	while (counter < 42) {
		int expected;
		int desired;

		do {

			printf("In CAS loop...\n");

			expected = atomic_load(&counter);

			// !!
			desired = expected + 1;

			sleep_one_second();

		} while (!atomic_compare_exchange_strong(&counter, &expected, desired));

		printf("CAS Loop done, successfully updated counter (%d)\n", counter);
	}

	return EXIT_SUCCESS;
}





static void sleep_one_second(void) {
	struct timespec req = {
		.tv_sec = 1,
		.tv_nsec = 0,
	};
	struct timespec rem;
	int ret;
	do {
		ret = nanosleep(&req, &rem);
		req.tv_sec  = rem.tv_sec ;
		req.tv_nsec = rem.tv_nsec;
	} while (ret);
}