aboutsummaryrefslogtreecommitdiffstats
path: root/analysis/rtt/src/logger.c
diff options
context:
space:
mode:
Diffstat (limited to 'analysis/rtt/src/logger.c')
-rw-r--r--analysis/rtt/src/logger.c151
1 files changed, 96 insertions, 55 deletions
diff --git a/analysis/rtt/src/logger.c b/analysis/rtt/src/logger.c
index ed5f6e5..e1dd2f3 100644
--- a/analysis/rtt/src/logger.c
+++ b/analysis/rtt/src/logger.c
@@ -1,4 +1,3 @@
1
2#include "logger.h" 1#include "logger.h"
3#include <stdio.h> 2#include <stdio.h>
4#include <stdlib.h> 3#include <stdlib.h>
@@ -9,78 +8,120 @@
9#define WINDOW_SEC 1 8#define WINDOW_SEC 1
10#define MAX_TIMES 1000 9#define MAX_TIMES 1000
11 10
11#define ISO_TIME_BUF_SIZE 32
12
13#define MICROSECONDS_IN_SECOND 1000000
14#define MICROSECONDS_IN_MILLISECOND 1000
15
16#define CSV_HEADER "timestamp,sent_ms,received_ms,rtt_ms,throughput_msg_per_s\n"
17#define CSV_LINE_FORMAT "%s,%lld,%lld,%lld,%d\n"
18
12static FILE *csv_file = NULL; 19static FILE *csv_file = NULL;
13static double msg_times[MAX_TIMES]; 20static double msg_times[MAX_TIMES];
14static int msg_count = 0; 21static int msg_count = 0;
15 22
16static long long current_time_ms() { 23/**
17 struct timeval tv; 24 * @brief Returns the current time in milliseconds since the Epoch.
18 gettimeofday(&tv, NULL); 25 *
19 return ((long long)tv.tv_sec * 1000) + (tv.tv_usec / 1000); 26 * @return Current time in milliseconds (int64).
27 */
28static long long current_time_ms(void);
29
30/**
31 * @brief Returns the current time in seconds (with microsecond precision) since
32 * the Epoch.
33 *
34 * @return Current time in seconds (double).
35 */
36static double current_time_sec(void);
37
38/**
39 * @brief Updates the sliding window of message timestamps and returns the count
40 * of messages within WINDOW_SEC.
41 *
42 * @param now Current timestamp in seconds.
43 * @return Number of messages in the last WINDOW_SEC seconds.
44 */
45static int update_throughput_window(double now);
46
47static long long current_time_ms(void)
48{
49 struct timeval tv;
50 gettimeofday(&tv, NULL);
51 return ((long long)tv.tv_sec * 1000) +
52 (tv.tv_usec / MICROSECONDS_IN_MILLISECOND);
20} 53}
21 54
22static double current_time_sec() { 55static double current_time_sec(void)
23 struct timeval tv; 56{
24 gettimeofday(&tv, NULL); 57 struct timeval tv;
25 return (double)tv.tv_sec + (tv.tv_usec / 1e6); 58 gettimeofday(&tv, NULL);
59 return (double)tv.tv_sec +
60 (tv.tv_usec / (double)MICROSECONDS_IN_SECOND);
26} 61}
27 62
28static int update_throughput_window(double now) { 63static int update_throughput_window(double current_time)
29 int i, new_count = 0; 64{
30 for (i = 0; i < msg_count; i++) { 65 int msg_index, window_count = 0;
31 if (now - msg_times[i] < WINDOW_SEC) { 66 for (msg_index = 0; msg_index < msg_count; msg_index++) {
32 msg_times[new_count++] = msg_times[i]; 67 if (current_time - msg_times[msg_index] < WINDOW_SEC)
33 } 68 msg_times[window_count++] = msg_times[msg_index];
34 } 69 }
35 msg_times[new_count++] = now; 70 msg_times[window_count++] = current_time;
36 msg_count = new_count; 71 msg_count = window_count;
37 return msg_count; 72 return msg_count;
38} 73}
39 74
40void logger_init(const char *filename) { 75void logger_init(const char *filename)
41 csv_file = fopen(filename, "w"); 76{
42 if (!csv_file) { 77 csv_file = fopen(filename, "w");
43 perror("Cannot open CSV file"); 78 if (!csv_file) {
44 exit(EXIT_FAILURE); 79 perror("Cannot open CSV file");
45 } 80 exit(EXIT_FAILURE);
46 fprintf(csv_file, 81 }
47 "timestamp,sent_ms,received_ms,rtt_ms,throughput_msg_per_s\n"); 82 fprintf(csv_file, CSV_HEADER);
48 fflush(csv_file); 83 fflush(csv_file);
49} 84}
50 85
51void logger_cleanup() { 86void logger_cleanup(void)
52 if (csv_file) { 87{
53 fclose(csv_file); 88 if (csv_file) {
54 csv_file = NULL; 89 fclose(csv_file);
55 } 90 csv_file = NULL;
91 }
56} 92}
57 93
58void logger_handle_message(const void *payload, int payloadlen) { 94void logger_handle_message(const void *payload, int payloadlen)
59 char *payload_str = malloc(payloadlen + 1); 95{
60 if (!payload_str) 96 if (payloadlen <= 0)
61 return; 97 return;
62 memcpy(payload_str, payload, payloadlen); 98
63 payload_str[payloadlen] = '\0'; 99 char *payload_str = malloc(payloadlen + 1);
100 if (!payload_str)
101 return;
102
103 memcpy(payload_str, payload, payloadlen);
104 payload_str[payloadlen] = '\0';
64 105
65 long long sent_ms = atoll(payload_str); 106 long long sent_ms = atoll(payload_str);
66 free(payload_str); 107 free(payload_str);
67 108
68 long long received_ms = current_time_ms(); 109 long long received_ms = current_time_ms();
69 long long rtt = received_ms - sent_ms; 110 long long rtt = received_ms - sent_ms;
70 111
71 double now_sec = current_time_sec(); 112 double now_sec = current_time_sec();
72 int throughput = update_throughput_window(now_sec); 113 int throughput = update_throughput_window(now_sec);
73 114
74 time_t now = time(NULL); 115 time_t now = time(NULL);
75 struct tm *tm_info = localtime(&now); 116 struct tm *tm_info = localtime(&now);
76 char iso_time[32]; 117 char iso_time[ISO_TIME_BUF_SIZE];
77 strftime(iso_time, sizeof(iso_time), "%Y-%m-%dT%H:%M:%S", tm_info); 118 strftime(iso_time, sizeof(iso_time), "%Y-%m-%dT%H:%M:%S", tm_info);
78 119
79 if (csv_file) { 120 if (csv_file) {
80 fprintf(csv_file, "%s,%lld,%lld,%lld,%d\n", iso_time, sent_ms, received_ms, 121 fprintf(csv_file, CSV_LINE_FORMAT, iso_time, sent_ms,
81 rtt, throughput); 122 received_ms, rtt, throughput);
82 fflush(csv_file); 123 fflush(csv_file);
83 } 124 }
84 125
85 printf("RTT: %lld ms | Throughput: %d msg/s\n", rtt, throughput); 126 printf("RTT: %lld ms | Throughput: %d msg/s\n", rtt, throughput);
86} 127}