1
0
mirror of https://gitlab.com/80486DX2-66/gists synced 2024-12-27 05:40:17 +05:30
gists/c-programming/clock-malfunction-imitation.c

189 lines
3.9 KiB
C

/*
* clock-malfunction-imitation.c
*
* Author: Intel A80486DX2-66
* License: Creative Commons Zero 1.0 Universal
*/
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#define EXIT_IN 2U
#define SECOND_PRECISION 1L
#define TIME_BEFORE_ACCIDENT 2UL
#define TEST_LABEL(s) { \
printf("Test: %s\n", s); \
fflush(stdout); \
}
#define CLOCK_FUN_BEGIN \
static unsigned ticks_before_accident = TIME_BEFORE_ACCIDENT; \
time_t y;
#define CLOCK_FUN_END \
if (x != NULL) { \
*x = y; \
} \
return y;
time_t clock_change_time(time_t* x);
time_t clock_exponential_growth(time_t* x);
time_t clock_hang(time_t* x);
time_t clock_overflow(time_t* x);
time_t clock_reverse(time_t* x);
void time_flow_test(time_t (*time_function)(time_t*));
time_t clock_change_time(time_t* x) {
CLOCK_FUN_BEGIN
time(&y);
if (ticks_before_accident == 0) {
y = 0;
size_t max = sizeof(time(NULL)) / sizeof(int);
printf("max of clock_change_time = %zu\n", max);
size_t intmax_plus_1 = (size_t) INT_MAX + 1;
for (size_t i = 0; i < max; i++)
y |= (rand() & INT_MAX) * intmax_plus_1;
} else
ticks_before_accident--;
CLOCK_FUN_END
}
time_t clock_exponential_growth(time_t* x) {
CLOCK_FUN_BEGIN
static time_t counter = 1;
time(&y);
if (ticks_before_accident == 0) {
y += counter++;
counter *= counter;
} else {
ticks_before_accident--;
}
CLOCK_FUN_END
}
time_t clock_hang(time_t* x) {
CLOCK_FUN_BEGIN
static time_t last_time;
if (ticks_before_accident == 0)
y = last_time;
else {
time(&y);
last_time = y;
ticks_before_accident--;
}
CLOCK_FUN_END
}
time_t clock_overflow(time_t* x) {
CLOCK_FUN_BEGIN
time(&y);
if (ticks_before_accident == 0)
y = LONG_MAX - y;
else
ticks_before_accident--;
CLOCK_FUN_END
}
time_t clock_reverse(time_t* x) {
CLOCK_FUN_BEGIN
static time_t counter = 1, old_time;
if (ticks_before_accident == 0) {
y = old_time - counter++;
} else {
time(&y);
old_time = y;
ticks_before_accident--;
}
CLOCK_FUN_END
}
void time_flow_test(time_t (*time_function)(time_t*)) {
time_t current_time, previous_time;
double time_diff;
// Get the current time
time(&current_time);
previous_time = current_time;
bool first_time_passed = false;
unsigned i = 0;
for (;;) {
// Get the current time
time_function(&current_time);
// Calculate the time difference in seconds
time_diff = difftime(current_time, previous_time);
if (!first_time_passed) {
time_diff = (double) SECOND_PRECISION;
first_time_passed = true;
}
printf("time difference: %f", time_diff);
fflush(stdout);
// Check if the time difference exceeds a threshold (e.g., 1 second)
if (time_diff != (double) SECOND_PRECISION) {
printf(" -> Abnormal time flow detected!");
fflush(stdout);
if (++i >= EXIT_IN) {
printf("\nAborting\n");
fflush(stdout);
break;
}
}
printf("\n");
fflush(stdout);
// Update the previous time
previous_time = current_time;
usleep(SECOND_PRECISION * 1000000L);
first_time_passed = true;
}
printf("\n");
fflush(stdout);
}
int main(void) {
TEST_LABEL("clock_change_time")
time_flow_test(&clock_change_time);
TEST_LABEL("clock_exponential_growth")
time_flow_test(&clock_exponential_growth);
TEST_LABEL("clock_hang")
time_flow_test(&clock_hang);
TEST_LABEL("clock_overflow")
time_flow_test(&clock_overflow);
TEST_LABEL("clock_reverse")
time_flow_test(&clock_reverse);
return 0;
}