115 lines
2.5 KiB
C
115 lines
2.5 KiB
C
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
|
|
#define ITERATIONS 100000
|
|
|
|
// Shared variables
|
|
pthread_mutex_t lock;
|
|
pthread_cond_t cond;
|
|
int signal_flag = 0; // 0 = LOW, 1 = HIGH
|
|
int counter = 0;
|
|
|
|
// set up an array of timespec structs to store timestamps
|
|
struct timespec timestamps[ITERATIONS];
|
|
|
|
void* high_thread(void* arg) {
|
|
while (1) {
|
|
|
|
if (counter >= ITERATIONS) {
|
|
pthread_cond_signal(&cond);
|
|
return NULL;
|
|
}
|
|
|
|
pthread_mutex_lock(&lock);
|
|
|
|
// Wait for turn
|
|
while (signal_flag != 1) {
|
|
pthread_cond_wait(&cond, &lock);
|
|
}
|
|
#ifdef DEBUG
|
|
printf("%d: HIGH\n", counter);
|
|
#endif
|
|
counter++;
|
|
signal_flag = 0;
|
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, ×tamps[counter]) != 0) {
|
|
perror("clock_gettime failed");
|
|
exit(1);
|
|
}
|
|
|
|
// Signal the other thread
|
|
pthread_mutex_unlock(&lock);
|
|
pthread_cond_signal(&cond);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void* low_thread(void* arg) {
|
|
while (1) {
|
|
if (counter >= ITERATIONS) {
|
|
pthread_cond_signal(&cond);
|
|
return NULL;
|
|
}
|
|
|
|
pthread_mutex_lock(&lock);
|
|
|
|
// Wait for turn
|
|
while (signal_flag != 0) {
|
|
pthread_cond_wait(&cond, &lock);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
printf("%d: LOW\n", counter);
|
|
#endif
|
|
counter++;
|
|
signal_flag = 1;
|
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, ×tamps[counter]) != 0) {
|
|
perror("clock_gettime failed");
|
|
exit(1);
|
|
}
|
|
|
|
// Signal the other thread
|
|
pthread_mutex_unlock(&lock);
|
|
pthread_cond_signal(&cond);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int main() {
|
|
pthread_t high_tid, low_tid;
|
|
|
|
// Initialize synchronization primitives
|
|
pthread_mutex_init(&lock, NULL);
|
|
pthread_cond_init(&cond, NULL);
|
|
|
|
// Create threads
|
|
pthread_create(&high_tid, NULL, high_thread, NULL);
|
|
pthread_create(&low_tid, NULL, low_thread, NULL);
|
|
|
|
|
|
printf("Start threads:\n");
|
|
|
|
// Wait for threads to finish
|
|
pthread_join(high_tid, NULL);
|
|
pthread_join(low_tid, NULL);
|
|
|
|
// Cleanup
|
|
pthread_mutex_destroy(&lock);
|
|
pthread_cond_destroy(&cond);
|
|
|
|
|
|
for (int i = 1; i < ITERATIONS; i++) {
|
|
printf("Period %zu: %ld.%09ld seconds\n",
|
|
i,
|
|
timestamps[i].tv_sec - timestamps[i-1].tv_sec,
|
|
timestamps[i].tv_nsec) - timestamps[i-1].tv_nsec;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|