Commit 53cce0dd authored by Andreas Schmidt's avatar Andreas Schmidt

Add xlap C-files.

parent 00888d45
This source diff could not be displayed because it is too large. You can view the blob instead.
#include "xlap.h"
#include <stdatomic.h>
void XlapTimestampTableDumpHeader(FILE *out)
{
fprintf(out, "SeqNo,Kind" );
# 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 XlapTimestampTableDump(FILE *out, XlapTimestampPacketKind kind, XlapTimestampTable *table)
{
# define OUT(id) fprintf(out, ",%llu,%llu", timestampByTime(&table->rows[row].time[ts_##id].actual.t), (unsigned long long) table->rows[row].time[ts_##id].actual.c);
for (unsigned int row = 0; row < TS_ROWS; row++) {
fprintf(out, "%u,%u", row, (unsigned) kind);
PP_foreach(PP_join_space, OUT, TIMESTAMP_ID_LIST)
fprintf(out, "\n");
}
# undef OUT
}
#ifndef XLAP_H
#define XLAP_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 XlapTimestamp {
struct XlapActualTimestamp {
uint64_t c;
struct timespec t;
} actual;
char _cacheline[64];
} XlapTimestamp;
#include "pp.h"
/*
* Comma-separated list of timestamp IDs
*/
#define TIMESTAMP_ID_LIST \
PrrtSendStart, \
PrrtSendEnd, \
PrrtSubmitPackage, \
PrrtEncodeStart, \
PrrtEncodeEnd, \
PrrtTransmitStart, \
PrrtTransmitEnd, \
LinkTransmitStart, \
LinkTransmitEnd, \
LinkReceive, \
DecodeStart, \
DecodeEnd, \
HandlePacketStart, \
HandlePacketEnd, \
CopyOutputStart, \
CopyOutputEnd, \
SendFeedbackStart, \
SendFeedbackEnd, \
PrrtReturnPackage, \
PrrtReceivePackage, \
PrrtDeliver \
#define TIMESSTAMP_ID_TO_NAME(id) ts_##id
/*
* enum containing all timestamp IDs
*/
typedef enum XlapTimestampId {
PP_foreach(PP_join_comma, TIMESSTAMP_ID_TO_NAME, TIMESTAMP_ID_LIST),
ts_count
} XlapTimestampId;
/*
* enum to distinguish between data and redundancy packet timstamps
*/
typedef enum XlapTimestampPacketKind {
ts_data_packet = 0,
ts_any_packet = 0,
ts_redundancy_packet = 1,
} XlapTimestampPacketKind;
/*
* Table that stores timestamps for each timestamp ID
*/
typedef struct XlapTimestampTableRow {
XlapTimestamp time[ts_count];
} XlapTimestampTableRow;
/*
* by default, store timestamps for 128 packages
*/
#ifndef TS_ROWS
#define TS_ROWS (1u<<12)
#endif
/*
* Table that stores timestamp table rows
*/
typedef struct XlapTimestampTable {
XlapTimestampTableRow rows[TS_ROWS];
} XlapTimestampTable;
/*
* Dummy data structure to store a single timestamp table row.
*/
typedef struct XlapTimestampPlaceholder {
_Atomic(XlapTimestampTable *) tstable[1];
XlapTimestampTableRow rows[1];
} XlapTimestampPlaceholder;
/*
* update the clock value of a timestamp
*
* This macro will cause a SIGSEGV if the application does not install a
* timestamp table to the socket.
*/
#define XlapTimeStampClock(sck, kind, seqno, id) do { \
clock_gettime(CLOCK_MONOTONIC, &atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].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 socket.
*/
#define XlapTimeStampCycle(sck, kind, seqno, id) do { \
atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.c = __builtin_ia32_rdtsc(); \
} while (0);
/*
* install a time stamp table to a socket
*/
#define XlapTimestampTableInstall(sck, kind, tstp) do { \
XlapTimestampTable *__tstp = (tstp); \
memset(__tstp, 0, sizeof(XlapTimestampTable)); \
atomic_store_explicit(&(sck)->tstable[kind], __tstp, memory_order_release); \
} while (0)
/*
* print a timestamp dump header
*/
extern void XlapTimestampTableDumpHeader(FILE *);
/*
* dump a timestamp table
*/
extern void XlapTimestampTableDump(FILE *, XlapTimestampPacketKind, XlapTimestampTable *);
/*
* use a specific timestamp table
*/
extern void XlapTimestampTableUse(XlapTimestampTable *);
/*
* intialize a timestamp table placeholder
*/
#define XlapTimestampPlaceholderInitialize(ph) do { \
XlapTimestampPlaceholder *__ph = (ph); \
atomic_store_explicit(&__ph->tstable[0], (XlapTimestampTable *) &__ph->rows, memory_order_release); \
memset(&__ph->rows, 0x0, sizeof(XlapTimestampTableRow)); \
} while (0);
/*
* copy a timestamp table placeholder into an actual timestamp table
*
* Since every timestamp is taken at most once, either the timestamptable or
* the placeholder value must be zero (for each timestamp).
*/
#define XlapTimestampPlaceholderUse(sck, kind, seqno, ph) do { \
XlapTimestampPlaceholder *__ph = (ph); \
XlapTimestampTable *__ts = atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire); \
for (unsigned int __t = 0; __t < ts_count; __t++) { \
__ts->rows[seqno % TS_ROWS].time[__t].actual.t.tv_sec += __ph->rows[0].time[__t].actual.t.tv_sec; \
__ts->rows[seqno % TS_ROWS].time[__t].actual.t.tv_nsec += __ph->rows[0].time[__t].actual.t.tv_nsec; \
__ts->rows[seqno % TS_ROWS].time[__t].actual.c += __ph->rows[0].time[__t].actual.c; \
} \
} while (0)
#endif // XLAP_H
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