xlap.h 7.3 KB
Newer Older
Andreas Schmidt's avatar
Andreas Schmidt committed
1
2
3
4
5
6
7
8
9
10
11
12
#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 {
13
14
15
16
17
    struct XlapActualTimestamp {
        uint64_t c;
        struct timespec t;
    } actual;
    char _cacheline[64];
Andreas Schmidt's avatar
Andreas Schmidt committed
18
19
20
21
22
23
24
25
} XlapTimestamp;

#include "pp.h"

/*
 * Comma-separated list of timestamp IDs
 */
#define TIMESTAMP_ID_LIST \
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    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
49
50
51
52
53
54
55

#define TIMESSTAMP_ID_TO_NAME(id) ts_##id

/*
 * enum containing all timestamp IDs
 */
typedef enum XlapTimestampId {
56
57
    PP_foreach(PP_join_comma, TIMESSTAMP_ID_TO_NAME, TIMESTAMP_ID_LIST),
    ts_count
Andreas Schmidt's avatar
Andreas Schmidt committed
58
59
60
61
62
63
} XlapTimestampId;

/*
 * enum to distinguish between data and redundancy packet timstamps
 */
typedef enum XlapTimestampPacketKind {
64
65
66
    ts_data_packet = 0,
    ts_any_packet = 0,
    ts_redundancy_packet = 1,
Andreas Schmidt's avatar
Andreas Schmidt committed
67
68
69
70
71
72
} XlapTimestampPacketKind;

/*
 * Table that stores timestamps for each timestamp ID
 */
typedef struct XlapTimestampTableRow {
73
    XlapTimestamp time[ts_count];
Andreas Schmidt's avatar
Andreas Schmidt committed
74
75
76
77
78
79
80
81
82
83
84
85
} 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
86
#ifdef XLAP
87
88
89
typedef struct XlapTimestampTable {
    XlapTimestampTableRow rows[TS_ROWS];
} XlapTimestampTable;
Stefan Reif's avatar
Stefan Reif committed
90
#else /* XLAP */
91
typedef char XlapTimestampTable;
Stefan Reif's avatar
Stefan Reif committed
92
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
93
94
95
96

/*
 * Dummy data structure to store a single timestamp table row.
 */
Stefan Reif's avatar
Stefan Reif committed
97
#ifdef XLAP
98
99
100
101
typedef struct XlapTimestampPlaceholder {
    _Atomic(XlapTimestampTable *) tstable[1];
    XlapTimestampTableRow rows[1];
} XlapTimestampPlaceholder;
Stefan Reif's avatar
Stefan Reif committed
102
#else /* XLAP */
103
typedef char XlapTimestampPlaceholder;
Stefan Reif's avatar
Stefan Reif committed
104
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
105

106
107
108
109
110
111
112
113
114
/*
 * 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 { \
115
116
            atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.t = value; \
        } while (0)
117
118
#else /* XLAP */
#	define XlapTimeStampValue(sck, kind, seqno, id, value) do { \
119
            (void) (sck); \
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
            (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); \
141
142
143
144
145
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
            (void) (value); \
        } while (0)
146
147
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
148
149
150
151
152
153
/*
 * 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
154
155
#ifdef XLAP
#	define XlapTimeStampClock(sck, kind, seqno, id) do { \
Andreas Schmidt's avatar
Andreas Schmidt committed
156
            clock_gettime(CLOCK_REALTIME, &atomic_load_explicit(&(sck)->tstable[kind], memory_order_acquire)->rows[(seqno) % TS_ROWS].time[ts_##id].actual.t); \
157
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
158
159
#else /* XLAP */
#	define XlapTimeStampClock(sck, kind, seqno, id) do { \
160
161
162
163
164
            (void) (sck); \
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
165
166
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
167
168
169
170
171
172
173

/*
 * 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
174
175
#ifdef XLAP
#	define XlapTimeStampCycle(sck, kind, seqno, id) do { \
176
177
            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
178
179
#else /* XLAP */
#	define XlapTimeStampCycle(sck, kind, seqno, id) do { \
180
181
182
183
184
            (void) (sck); \
            (void) (kind); \
            (void) (seqno); \
            (void) (ts_##id); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
185
186
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
187
188
189
190

/*
 * install a time stamp table to a socket
 */
Stefan Reif's avatar
Stefan Reif committed
191
192
#ifdef XLAP
#	define XlapTimestampTableInstall(sck, kind, tstp) do { \
193
194
195
196
            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
197
198
#else /* XLAP */
#	define XlapTimestampTableInstall(sck, kind, tstp) do { \
199
200
201
202
            (void) (sck); \
            (void) (kind); \
            (void) (tstp); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
203
204
#endif

Andreas Schmidt's avatar
Andreas Schmidt committed
205
206
207
208

/*
 * print a timestamp dump header
 */
Stefan Reif's avatar
Stefan Reif committed
209
#ifdef XLAP
210
extern void XlapTimestampTableDumpHeader(FILE *);
Stefan Reif's avatar
Stefan Reif committed
211
212
#else
#	define XlapTimestampTableDumpHeader(f) do { \
213
214
            (void) (f); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
215
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
216
217
218
219

/*
 * dump a timestamp table
 */
Stefan Reif's avatar
Stefan Reif committed
220
#ifdef XLAP
221
extern void XlapTimestampTableDump(FILE *, XlapTimestampPacketKind, XlapTimestampTable *);
Stefan Reif's avatar
Stefan Reif committed
222
223
#else
#	define XlapTimestampTableDump(f, k, t) do { \
224
225
226
227
            (void) (f); \
            (void) (k); \
            (void) (t); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
228
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
229
230
231
232

/*
 * intialize a timestamp table placeholder
 */
Stefan Reif's avatar
Stefan Reif committed
233
234
#ifdef XLAP
#	define XlapTimestampPlaceholderInitialize(ph) do { \
235
236
237
238
            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
239
240
#else
#	define XlapTimestampPlaceholderInitialize(ph) do { \
241
242
            (void) (ph); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
243
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
244
245
246
247
248
249
250

/*
 * 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
251
252
#ifdef XLAP
#	define XlapTimestampPlaceholderUse(sck, kind, seqno, ph) do { \
253
254
255
256
257
258
259
260
            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
261
262
#else
#	define XlapTimestampPlaceholderUse(sck, kind, seqno, ph) do { \
263
264
265
266
267
            (void) (sck); \
            (void) (kind); \
            (void) (seqno); \
            (void) (ph); \
        } while (0)
Stefan Reif's avatar
Stefan Reif committed
268
#endif
Andreas Schmidt's avatar
Andreas Schmidt committed
269
270

#endif // XLAP_H