xlap.h 7.44 KB
Newer Older
Andreas Schmidt's avatar
Andreas Schmidt committed
1 2 3 4 5 6 7
#ifndef XLAP_H
#define XLAP_H

#include <stdio.h>
#include <stdint.h>
#include <time.h>

8 9 10 11 12 13 14
#ifndef __cplusplus
# include <stdatomic.h>
#else
# include <atomic>
# define _Atomic(X) std::atomic< X >
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
15 16 17 18 19
/*
 * Each timestamp contains both a cycle value and a time value, but some values
 * might remain zero
 */
typedef union XlapTimestamp {
20 21 22 23 24
    struct XlapActualTimestamp {
        uint64_t c;
        struct timespec t;
    } actual;
    char _cacheline[64];
Andreas Schmidt's avatar
Andreas Schmidt committed
25 26 27 28 29 30 31 32
} XlapTimestamp;

#include "pp.h"

/*
 * Comma-separated list of timestamp IDs
 */
#define TIMESTAMP_ID_LIST \
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
    PrrtSendStart, \
    PrrtSendEnd, \
    PrrtSubmitPackage, \
    PrrtEncodeStart, \
    PrrtEncodeEnd, \
    PrrtTransmitStart, \
    PrrtTransmitEnd, \
    LinkTransmitStart, \
    LinkTransmitEnd, \
    ChannelTransmit, \
    ChannelReceive, \
    LinkReceive, \
    DecodeStart, \
    DecodeEnd, \
    HandlePacketStart, \
    HandlePacketEnd, \
    CopyOutputStart, \
    CopyOutputEnd, \
    SendFeedbackStart, \
    SendFeedbackEnd, \
    PrrtReturnPackage, \
    PrrtReceivePackage, \
    PrrtDeliver \
Andreas Schmidt's avatar
Andreas Schmidt committed
56 57 58 59 60 61 62

#define TIMESSTAMP_ID_TO_NAME(id) ts_##id

/*
 * enum containing all timestamp IDs
 */
typedef enum XlapTimestampId {
63 64
    PP_foreach(PP_join_comma, TIMESSTAMP_ID_TO_NAME, TIMESTAMP_ID_LIST),
    ts_count
Andreas Schmidt's avatar
Andreas Schmidt committed
65 66 67 68 69 70
} XlapTimestampId;

/*
 * enum to distinguish between data and redundancy packet timstamps
 */
typedef enum XlapTimestampPacketKind {
71 72 73
    ts_data_packet = 0,
    ts_any_packet = 0,
    ts_redundancy_packet = 1,
74
    ts_feedback_packet = 2
Andreas Schmidt's avatar
Andreas Schmidt committed
75 76 77 78 79 80
} XlapTimestampPacketKind;

/*
 * Table that stores timestamps for each timestamp ID
 */
typedef struct XlapTimestampTableRow {
81
    XlapTimestamp time[ts_count];
Andreas Schmidt's avatar
Andreas Schmidt committed
82 83 84 85 86 87 88 89 90 91 92 93
} XlapTimestampTableRow;

/*
 * by default, store timestamps for 128 packages
 */
#ifndef TS_ROWS
#define TS_ROWS (1u<<12)
#endif

/*
 * Table that stores timestamp table rows
 */
Stefan Reif's avatar
Stefan Reif committed
94
#ifdef XLAP
95 96 97
typedef struct XlapTimestampTable {
    XlapTimestampTableRow rows[TS_ROWS];
} XlapTimestampTable;
Stefan Reif's avatar
Stefan Reif committed
98
#else /* XLAP */
99
typedef char XlapTimestampTable;
Stefan Reif's avatar
Stefan Reif committed
100
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
101 102 103 104

/*
 * Dummy data structure to store a single timestamp table row.
 */
Stefan Reif's avatar
Stefan Reif committed
105
#ifdef XLAP
106 107 108 109
typedef struct XlapTimestampPlaceholder {
    _Atomic(XlapTimestampTable *) tstable[1];
    XlapTimestampTableRow rows[1];
} XlapTimestampPlaceholder;
Stefan Reif's avatar
Stefan Reif committed
110
#else /* XLAP */
111
typedef char XlapTimestampPlaceholder;
Stefan Reif's avatar
Stefan Reif committed
112
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
113

114 115 116 117 118 119 120 121 122
/*
 * update the clock value of a timestamp by setting an explicit value
 *
 * This macro will cause a SIGSEGV if the application does not install a
 * timestamp table to the socket.
 */

#ifdef XLAP
#	define XlapTimeStampValue(sck, kind, seqno, id, value) do { \
123 124
            atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.t = value; \
        } while (0)
125 126
#else /* XLAP */
#	define XlapTimeStampValue(sck, kind, seqno, id, value) do { \
127
            (void) (sck); \
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
            (void) (value); \
        } while (0)
#endif

/*
 * update the clock value of a cyclestamp by setting an explicit value
 *
 * This macro will cause a SIGSEGV if the application does not install a
 * timestamp table to the socket.
 */

#ifdef XLAP
#	define XlapCycleStampValue(sck, kind, seqno, id, value) do { \
            atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.c = value; \
        } while (0)
#else /* XLAP */
#	define XlapCycleStampValue(sck, kind, seqno, id, value) do { \
            (void) (sck); \
149 150 151 152 153
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
            (void) (value); \
        } while (0)
154 155
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
156 157 158 159 160 161
/*
 * 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.
 */
Stefan Reif's avatar
Stefan Reif committed
162 163
#ifdef XLAP
#	define XlapTimeStampClock(sck, kind, seqno, id) do { \
Andreas Schmidt's avatar
Andreas Schmidt committed
164
            clock_gettime(CLOCK_MONOTONIC, &atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.t); \
165
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
166 167
#else /* XLAP */
#	define XlapTimeStampClock(sck, kind, seqno, id) do { \
168 169 170 171 172
            (void) (sck); \
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
173 174
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
175 176 177 178 179 180 181

/*
 * 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.
 */
Stefan Reif's avatar
Stefan Reif committed
182 183
#ifdef XLAP
#	define XlapTimeStampCycle(sck, kind, seqno, id) do { \
184 185
            atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.c = __builtin_ia32_rdtsc(); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
186 187
#else /* XLAP */
#	define XlapTimeStampCycle(sck, kind, seqno, id) do { \
188 189 190 191 192
            (void) (sck); \
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
193 194
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
195 196 197 198

/*
 * install a time stamp table to a socket
 */
Stefan Reif's avatar
Stefan Reif committed
199 200
#ifdef XLAP
#	define XlapTimestampTableInstall(sck, kind, tstp) do { \
201 202 203 204
            XlapTimestampTable *__tstp = (tstp); \
            memset(__tstp, 0, sizeof(XlapTimestampTable)); \
            atomic_store_explicit(&(sck)->tstable[kind], __tstp, memory_order_release); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
205 206
#else /* XLAP */
#	define XlapTimestampTableInstall(sck, kind, tstp) do { \
207 208 209 210
            (void) (sck); \
            (void) (kind); \
            (void) (tstp); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
211 212
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
213 214 215 216

/*
 * print a timestamp dump header
 */
Stefan Reif's avatar
Stefan Reif committed
217
#ifdef XLAP
218
extern void XlapTimestampTableDumpHeader(FILE *);
Stefan Reif's avatar
Stefan Reif committed
219 220
#else
#	define XlapTimestampTableDumpHeader(f) do { \
221 222
            (void) (f); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
223
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
224 225 226 227

/*
 * dump a timestamp table
 */
Stefan Reif's avatar
Stefan Reif committed
228
#ifdef XLAP
229
extern void XlapTimestampTableDump(FILE *, XlapTimestampPacketKind, XlapTimestampTable *);
Stefan Reif's avatar
Stefan Reif committed
230 231
#else
#	define XlapTimestampTableDump(f, k, t) do { \
232 233 234 235
            (void) (f); \
            (void) (k); \
            (void) (t); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
236
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
237 238 239 240

/*
 * intialize a timestamp table placeholder
 */
Stefan Reif's avatar
Stefan Reif committed
241 242
#ifdef XLAP
#	define XlapTimestampPlaceholderInitialize(ph) do { \
243 244 245 246
            XlapTimestampPlaceholder *__ph = (ph); \
            atomic_store_explicit(&__ph->tstable[0], (XlapTimestampTable *) &__ph->rows, memory_order_release); \
            memset(&__ph->rows, 0x0, sizeof(XlapTimestampTableRow)); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
247 248
#else
#	define XlapTimestampPlaceholderInitialize(ph) do { \
249 250
            (void) (ph); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
251
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
252 253 254 255 256 257 258

/*
 * 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).
 */
Stefan Reif's avatar
Stefan Reif committed
259 260
#ifdef XLAP
#	define XlapTimestampPlaceholderUse(sck, kind, seqno, ph) do { \
261 262 263 264 265 266 267 268
            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)
Stefan Reif's avatar
Stefan Reif committed
269 270
#else
#	define XlapTimestampPlaceholderUse(sck, kind, seqno, ph) do { \
271 272 273 274 275
            (void) (sck); \
            (void) (kind); \
            (void) (seqno); \
            (void) (ph); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
276
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
277 278

#endif // XLAP_H