[CT420]: Finish Assignment 2

This commit is contained in:
2025-03-19 22:57:22 +00:00
parent b0f5a495c0
commit a96f6f5cd9
29 changed files with 80310 additions and 40034 deletions

View File

@ -1,25 +1,28 @@
// Compile code with gcc -o bm1 bm1.c -lrt -Wall -O2
// Execute code with sudo ./bm1
// Compile code with gcc -o merged merged.c -lrt -Wall -O2
// Execute code with sudo ./merged
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <stdio.h> // Standard I/O functions
#include <stdlib.h> // Standard library functions
#include <time.h> // Time-related functions
#include <signal.h> // Signal handling
#include <sys/mman.h> // Memory locking
#include <unistd.h> // POSIX standard functions
#include <sched.h> // Scheduling policies
#include <errno.h> // Error handling
#include <string.h> // String manipulation
#include <limits.h> // Limits of integral types
#define ITERATIONS 10000
#define NS_PER_SEC 1000000000L
// Constants
#define ITERATIONS 10000 // Number of benchmark iterations
#define NS_PER_SEC 1000000000L // Nanoseconds per second
timer_t timer_id;
volatile sig_atomic_t timer_expired = 0;
volatile sig_atomic_t signal_received = 0;
struct timespec start, end, sleep_time;
// Global Variables
timer_t timer_id; // Timer identifier
volatile sig_atomic_t timer_expired = 0; // Flag for timer expiration
volatile sig_atomic_t signal_received = 0; // Flag for signal reception
struct timespec start, end, sleep_time; // Time structures for benchmarking
// Function to save benchmark results to a CSV file
void save_results(const char *filename, long long *data) {
FILE *file = fopen(filename, "w");
if (!file) {
@ -33,16 +36,19 @@ void save_results(const char *filename, long long *data) {
fclose(file);
}
// Signal handler for signal-based latency measurement
void signal_handler(int signum) {
signal_received = 1;
clock_gettime(CLOCK_MONOTONIC, &end);
signal_received = 1; // Mark signal as received
clock_gettime(CLOCK_MONOTONIC, &end); // Capture end time
}
// Timer signal handler
void timer_handler(int signum) {
timer_expired = 1;
clock_gettime(CLOCK_MONOTONIC, &end);
timer_expired = 1; // Mark timer as expired
clock_gettime(CLOCK_MONOTONIC, &end); // Capture end time
}
// Configures real-time scheduling with FIFO priority
void configure_realtime_scheduling() {
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
@ -52,6 +58,7 @@ void configure_realtime_scheduling() {
}
}
// Locks memory to prevent paging for real-time performance
void lock_memory() {
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
perror("mlockall");
@ -59,10 +66,11 @@ void lock_memory() {
}
}
// Measures jitter of nanosleep function
void benchmark_nanosleep() {
long long jitter_data[ITERATIONS];
sleep_time.tv_sec = 0;
sleep_time.tv_nsec = 1000000; // 1 ms
sleep_time.tv_nsec = 1000000; // 1 ms sleep
for (int i = 0; i < ITERATIONS; i++) {
clock_gettime(CLOCK_MONOTONIC, &start);
@ -74,14 +82,15 @@ void benchmark_nanosleep() {
save_results("nanosleep.csv", jitter_data);
}
// Measures latency of sending and handling a signal
void benchmark_signal_latency() {
long long latency_data[ITERATIONS];
signal(SIGUSR1, signal_handler);
signal(SIGUSR1, signal_handler); // Register signal handler
for (int i = 0; i < ITERATIONS; i++) {
clock_gettime(CLOCK_MONOTONIC, &start);
kill(getpid(), SIGUSR1);
while (!signal_received);
kill(getpid(), SIGUSR1); // Send signal to itself
while (!signal_received); // Wait for signal to be handled
latency_data[i] = (end.tv_sec - start.tv_sec) * NS_PER_SEC + (end.tv_nsec - start.tv_nsec);
signal_received = 0;
@ -89,6 +98,7 @@ void benchmark_signal_latency() {
save_results("signal_latency.csv", latency_data);
}
// Measures jitter of a real-time timer
void benchmark_timer() {
long long jitter_data[ITERATIONS];
struct sigevent sev;
@ -126,12 +136,13 @@ void benchmark_timer() {
save_results("timer.csv", jitter_data);
}
// Measures jitter of usleep function
void benchmark_usleep() {
long long jitter_data[ITERATIONS];
for (int i = 0; i < ITERATIONS; i++) {
clock_gettime(CLOCK_MONOTONIC, &start);
usleep(1000); // 1 ms
usleep(1000); // Sleep for 1 ms
clock_gettime(CLOCK_MONOTONIC, &end);
jitter_data[i] = ((end.tv_sec - start.tv_sec) * NS_PER_SEC + (end.tv_nsec - start.tv_nsec)) - 1000000;
@ -139,9 +150,10 @@ void benchmark_usleep() {
save_results("usleep.csv", jitter_data);
}
// Main function to execute all benchmarks
int main() {
configure_realtime_scheduling();
lock_memory();
configure_realtime_scheduling(); // Set high priority scheduling
lock_memory(); // Prevent memory paging
printf("Getting nanosleep benchmark\n");
benchmark_nanosleep();