Commit a7483af8 authored by Stefan Reif's avatar Stefan Reif Committed by Andreas Schmidt

Add timestamps

 - Implement PrrtTimestamp data structures and functions
 - Add PrrtTimeStampClock and PrrtTimeStampCycle macros where desired
 - Dump timestamp results to stdout
parent fe78cd66
Pipeline #797 failed with stages
in 7 seconds
......@@ -6,6 +6,7 @@ add_library(PRRT ../defines.h
packet.c packet.h
receiver.c receiver.h
socket.c socket.h
timestamp.c timestamp.h
applicationConstraints.c applicationConstraints.h
vdmcode/block_code.c vdmcode/block_code.h
stores/forwardPacketTable.c stores/forwardPacketTable.h
......@@ -15,4 +16,4 @@ add_library(PRRT ../defines.h
processes/dataTransmitter.c processes/dataTransmitter.h processes/cleaner.c processes/cleaner.h stores/repairBlockStore.c stores/repairBlockStore.h stores/packetTimeoutTable.c stores/packetTimeoutTable.h stores/dataPacketStore.c stores/dataPacketStore.h)
set_property(TARGET PRRT PROPERTY C_STANDARD 99)
target_link_libraries(PRRT rt)
\ No newline at end of file
target_link_libraries(PRRT rt)
......@@ -191,6 +191,8 @@ void *receive_data_loop(void *ptr)
memset(buffer, 0, MAX_PAYLOAD_LENGTH);
n = recvfrom(sock_ptr->dataSocketFd, buffer, MAX_PAYLOAD_LENGTH, 0, (struct sockaddr *) &remote, &addrlen);
sock_ptr->lastReceivedTimestamp = PrrtClock_get_current_time_us();
PrrtTimeStampClock(sock_ptr, LinkReceive);
PrrtTimeStampCycle(sock_ptr, LinkReceive);
PrrtPacket *packet = (PrrtPacket *) calloc(1, sizeof(PrrtPacket));
check_mem(packet);
......
......@@ -20,6 +20,7 @@ bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet)
check(PrrtPacket_encode(buf, MAX_PAYLOAD_LENGTH, packet), "Buffer too small.");
// SENDING TO ALL RECEIVERS
PrrtTimeStampCycle(sock_ptr, LinkTransmitStart);
LIST_FOREACH(sock_ptr->receivers, first, next, cur) {
PrrtReceiver *recv = cur->value;
......@@ -39,6 +40,8 @@ bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet)
length, "Sendto failed.");
usleep(1);
}
PrrtTimeStampClock(sock_ptr, LinkTransmitEnd);
PrrtTimeStampCycle(sock_ptr, LinkTransmitEnd);
PrrtPacket_destroy(packet);
......@@ -92,7 +95,9 @@ void *send_data_loop(void *ptr)
// TODO: redundancy should only be sent when necessary
if(PrrtBlock_encode_ready(block)) {
uint32_t j = 0;
PrrtTimeStampCycle(sock_ptr, PrrtEncodeStart);
PrrtBlock_encode(block, &sock_ptr->sequenceNumberRedundancy);
PrrtTimeStampCycle(sock_ptr, PrrtEncodeEnd);
uint32_t redundancyBlocks = List_count(block->redundancyPackets);
for(j = 0; j < redundancyBlocks; j++) {
......
......@@ -119,7 +119,10 @@ int PrrtSocket_connect(PrrtSocket *sock_ptr, const char *host, const uint16_t po
}
int PrrtSocket_send(PrrtSocket *sock_ptr, const uint8_t *data, const size_t data_len) {
check(sock_ptr->isSender, "Cannot send on receiver socket.")
PrrtTimeStampClock(sock_ptr, PrrtSendStart);
PrrtTimeStampCycle(sock_ptr, PrrtSendStart);
PrrtPacket *packet = PrrtPacket_create_data_packet(5, data, (prrtPacketLength_t) data_len, 0, PrrtApplicationConstraints_get_target_delay(sock_ptr->applicationConstraints));
check(pthread_mutex_lock(&sock_ptr->outQueueFilledMutex) == 0, "Lock failed.");
......@@ -127,6 +130,8 @@ int PrrtSocket_send(PrrtSocket *sock_ptr, const uint8_t *data, const size_t data
check(pthread_cond_signal(&sock_ptr->outQueueFilledCv) == 0, "Signal failed.");
check(pthread_mutex_unlock(&sock_ptr->outQueueFilledMutex) == 0, "Unlock failed");
PrrtTimeStampClock(sock_ptr, PrrtSendEnd);
PrrtTimeStampCycle(sock_ptr, PrrtSendEnd);
return 0;
error:
PERROR("There was a failure while sending from socket.%s", "");
......@@ -154,6 +159,8 @@ int32_t PrrtSocket_recv(PrrtSocket *sock_ptr, void *buf_ptr) {
PrrtPacket_destroy(packet);
check(pthread_mutex_unlock(&sock_ptr->inQueueFilledMutex) == 0, "Unlock failed.");
PrrtTimeStampClock(sock_ptr, PrrtDeliver);
PrrtTimeStampCycle(sock_ptr, PrrtDeliver);
return len;
}
error:
......
......@@ -12,6 +12,7 @@
#include "stores/packetTimeoutTable.h"
#include "stores/repairBlockStore.h"
#include "clock.h"
#include "timestamp.h"
typedef struct prrtSocket {
......@@ -60,6 +61,8 @@ typedef struct prrtSocket {
PrrtChannelStateInformation* csi;
PrrtApplicationConstraints *applicationConstraints;
_Atomic(PrrtTimestampTable *) tstable;
} PrrtSocket;
......
#include "timestamp.h"
#include <stdatomic.h>
void PrrtTimestampTableDumpHeader(FILE *out)
{
fprintf(out, "SeqNo" );
# define OUT(id) fprintf(out, ",%s_T,%s_C", #id, #id);
PP_foreach(PP_join_space, OUT, TIMESTAMP_ID_LIST)
# undef OUT
fprintf(out, "\n");
}
static inline unsigned long long timestampByTime(struct timespec *ts)
{
// convert timespec to microseconds
unsigned long long x = ts->tv_sec;
x *= 1000000ULL;
x += ts->tv_nsec / 1000;
return x;
}
void PrrtTimestampTableDump(FILE *out, unsigned int seqno, PrrtTimestampTable *table)
{
fprintf(out, "%u", seqno);
# define OUT(id) fprintf(out, ",%llu,%llu", timestampByTime(&table->time[ts_##id].actual.t), (unsigned long long) table->time[ts_##id].actual.c);
PP_foreach(PP_join_space, OUT, TIMESTAMP_ID_LIST)
# undef OUT
fprintf(out, "\n");
}
#ifndef PRRT_TIMESTAMP_H
#define PRRT_TIMESTAMP_H
#include <stdio.h>
#include <stdint.h>
#include <time.h>
/*
* Each timestamp contains both a cycle value and a time value, but some values
* might remain zero
*/
typedef union PrrtTimestamp {
struct PrrtActualTimestamp {
uint64_t c;
struct timespec t;
} actual;
char _cacheline[64];
} PrrtTimestamp;
#include "../util/pp.h"
/*
* Comma-separated list of timestamp IDs
*/
#define TIMESTAMP_ID_LIST \
PrrtSendStart, \
PrrtSendEnd, \
PrrtEncodeStart, \
PrrtEncodeEnd, \
LinkTransmitStart, \
LinkTransmitEnd, \
LinkReceive, \
PrrtDeliver \
#define TIMESSTAMP_ID_TO_NAME(id) ts_##id
/*
* enum containing all timestamp IDs
*/
typedef enum PrrtTimestampId {
PP_foreach(PP_join_comma, TIMESSTAMP_ID_TO_NAME, TIMESTAMP_ID_LIST),
ts_count
} PrrtTimestampId;
/*
* Table that stores timestamps for each timestamp ID
*/
typedef struct PrrtTimestampTable {
PrrtTimestamp time[ts_count];
} PrrtTimestampTable;
/*
* update the clock value of a timestamp
*
* This macro will cause a SIGSEGV if the application does not install a
* timestamp table to the prrt socket.
*/
#define PrrtTimeStampClock(sck, id) do { \
clock_gettime(CLOCK_MONOTONIC, &atomic_load_explicit(&(sck)->tstable, memory_order_acquire)->time[ts_##id].actual.t); \
} while (0);
/*
* update the cycle value of a timestamp
*
* This macro will cause a SIGSEGV if the application does not install a
* timestamp table to the prrt socket.
*/
#define PrrtTimeStampCycle(sck, id) do { \
atomic_load_explicit(&(sck)->tstable, memory_order_acquire)->time[ts_##id].actual.c = __builtin_ia32_rdtsc(); \
} while (0);
/*
* install a time stamp table to a socket
*/
#define PrrtTimestampTableInstall(sck, tstp) do { \
PrrtTimestampTable *__tstp = (tstp); \
memset(__tstp, 0, sizeof(PrrtTimestampTable)); \
atomic_store_explicit(&(sck)->tstable, __tstp, memory_order_release); \
} while (0)
/*
* print a timestamp dump header
*/
extern void PrrtTimestampTableDumpHeader(FILE *);
/*
* dump a timestamp table
*/
extern void PrrtTimestampTableDump(FILE *, unsigned int, PrrtTimestampTable *);
/*
* use a specific timestamp table
*/
extern void PrrtTimestampTableUse(PrrtTimestampTable *);
#endif // PRRT_TIMESTAMP_H
......@@ -29,16 +29,19 @@ int main(int argc, char* const argv[]) {
PrrtSocket_bind(sock, "127.0.0.1", port);
check(sock != NULL, "Could not create socket.");
PrrtTimestampTable tstable;
PrrtTimestampTableDumpHeader(stdout);
int i = 1;
while(keepRunning) {
unsigned char buffer[MAX_PAYLOAD_LENGTH];
prrtTimestamp_t ts = PrrtClock_get_current_time_us();
uint64_t cyc = rdtsc();
printf("TIME: %lu, CYC: %llu\n", ts, cyc);
PrrtTimestampTableInstall(sock, &tstable);
int n = PrrtSocket_recv(sock, buffer);
if(n < 0 ) {
continue;
}
PrrtTimestampTableDump(stdout, (unsigned int) i, &tstable);
buffer[n] = '\0';
//printf("[B (n: %3d, i: %3d)] %s\n", n, i, buffer);
i++;
......
......@@ -31,11 +31,19 @@ int main(int argc, char *const argv[]) {
debug("SENDING\n");
PrrtTimestampTable tstable;
PrrtTimestampTableDumpHeader(stdout);
uint32_t j = 0;
while(j < rounds) {
char buf[MAX_PAYLOAD_LENGTH];
sprintf(buf, "%10d", j+1);
PrrtSocket_send(socket, buf, strlen(buf));
PrrtTimestampTableInstall(socket, &tstable);
PrrtSocket_send(socket, (unsigned char *) buf, strlen(buf));
PrrtTimestampTableDump(stdout, (unsigned int) j, &tstable);
j++;
usleep(50);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment