realtime/lab/square_wave_semaphores_timed.c

94 lines
2.3 KiB
C

// Description: This program uses semaphores to create a square wave between two threads.
// The period of the square wave is timed and displayed after the threads have finished.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <time.h>
#define DEBUG 0
#define NUM_PERIODS 100e3
sem_t high_sem, low_sem;
struct timespec start_time, end_time;
// Array to store timestamps of each period
struct timespec timestamps[NUM_PERIODS];
void* high() {
for (int i = 0; i < NUM_PERIODS; i++) {
sem_wait(&high_sem);
if (clock_gettime(CLOCK_MONOTONIC, &timestamps[i]) != 0) {
perror("clock_gettime failed");
exit(1);
}
#if DEBUG
printf("%d: HIGH\n", i);
#endif
sem_post(&low_sem);
}
return NULL;
}
void* low() {
for (int i = 0; i < NUM_PERIODS; i++) {
sem_wait(&low_sem);
#if DEBUG
printf("%d: LOW\n", i);
#endif
sem_post(&high_sem);
}
return NULL;
}
int main() {
pthread_t high_thread, low_thread;
sem_init(&high_sem, 0, 1); // high_sem starts
sem_init(&low_sem, 0, 0);
pthread_create(&high_thread, NULL, high, NULL);
pthread_create(&low_thread, NULL, low, NULL);
pthread_join(high_thread, NULL);
pthread_join(low_thread, NULL);
sem_destroy(&high_sem);
sem_destroy(&low_sem);
int period;
int min_period;
int max_period;
int sum_of_periods = 0;
// Print periods for each iteration
for (int i = 1; i < NUM_PERIODS; i++) {
sum_of_periods += period;
period = (timestamps[i].tv_sec - timestamps[i - 1].tv_sec) * 1e9 + (timestamps[i].tv_nsec - timestamps[i - 1].tv_nsec);
if (i == 1) {
min_period = period;
max_period = period;
} else {
if (period < min_period) {
min_period = period;
}
if (period > max_period) {
max_period = period;
}
}
//printf("Period %d: %lld nanoseconds\n", i, periods[i]);
//printf("%lld\n", periods[i]);
}
printf("Minimum period: %d nanoseconds\n", min_period);
printf("Maximum period: %d nanoseconds\n", max_period);
printf("Average period: %f nanoseconds\n", (float)sum_of_periods / (NUM_PERIODS - 1));
return 0;
}