Skip to content

Commit 93c4594

Browse files
committed
Implement TimeTrace::recordIfNotDup that collapses duplicate messages.
Similar to RAMCLOUD_CLOG but more limited: * Only support messages with no printf format specifiers. * Only collapse identical messages that appear consecutively in the buffer.
1 parent b6bce4a commit 93c4594

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

cwrapper/timetrace_wrapper.cc

+11
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ timetrace_record_ts(uint64_t timestamp, const char* format, uint32_t arg0,
6565
TimeTrace::record(timestamp, format, arg0, arg1, arg2, arg3);
6666
}
6767

68+
/**
69+
* This function is the wrapper for TimeTrace::recordIfNotDup.
70+
*
71+
* Since we cannot separate definition and declaration of inline function, so
72+
* this function cannot be inline function.
73+
*/
74+
void
75+
timetrace_record_if_not_dup(const char* message) {
76+
TimeTrace::recordIfNotDup(message);
77+
}
78+
6879
/**
6980
* This function is used to set TimeTrace::keepOldEvents
7081
*/

cwrapper/timetrace_wrapper.h

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ void timetrace_record();
4444
* uint32_t arg3);
4545
*/
4646
void timetrace_record_ts();
47+
/**
48+
* The real signature of this function is the following. The message string is
49+
* mandatory.
50+
* void timetrace_record_if_not_dup(const char* message);
51+
*/
52+
void timetrace_record_if_not_dup();
4753
void timetrace_set_keepoldevents(bool keep);
4854

4955
#ifdef __cplusplus

src/TimeTrace.cc

+43
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,39 @@ TimeTrace::Buffer::record(uint64_t timestamp, const char* format, uint32_t arg0,
145145
event->arg3 = arg3;
146146
}
147147

148+
/**
149+
* Similar to TimeTrace::Buffer::record but collapse consecutive messages that
150+
* are identical.
151+
*
152+
* \param timestamp
153+
* Identifies the time at which the event occurred.
154+
* \param message
155+
* A message string with no printf format specifiers.
156+
*/
157+
void
158+
TimeTrace::Buffer::recordIfNotDup(uint64_t timestamp, const char* message) {
159+
if (activeReaders > 0) {
160+
return;
161+
}
162+
163+
Event* lastEvent = &events[nextIndex > 0 ? nextIndex - 1 : BUFFER_SIZE - 1];
164+
if (lastEvent->format == message) {
165+
lastEvent->timestamp = timestamp;
166+
lastEvent->arg0++;
167+
return;
168+
}
169+
170+
Event* event = &events[nextIndex];
171+
nextIndex = (nextIndex + 1) & BUFFER_MASK;
172+
173+
event->timestamp = timestamp;
174+
event->format = message;
175+
event->arg0 = 1;
176+
event->arg1 = ~0u;
177+
event->arg2 = ~0u;
178+
event->arg3 = ~0u;
179+
}
180+
148181
/**
149182
* Return a string containing a printout of the records in the buffer.
150183
*/
@@ -319,6 +352,8 @@ TimeTrace::printInternal(std::vector<TimeTrace::Buffer*>* buffers, string* s) {
319352
(current[currentBuffer] + 1) & Buffer::BUFFER_MASK;
320353

321354
char message[1000];
355+
const char* repeatedTimes = " (repeated %u times)";
356+
#define IS_REPEATED_EVENT(x) ((x->arg0 > 1) && (x->arg1 == ~0u))
322357
double ns = Cycles::toSeconds(event->timestamp - startTime) * 1e09;
323358
if (s != NULL) {
324359
if (s->length() != 0) {
@@ -333,6 +368,11 @@ TimeTrace::printInternal(std::vector<TimeTrace::Buffer*>* buffers, string* s) {
333368
event->arg1, event->arg2, event->arg3);
334369
#pragma GCC diagnostic pop
335370
s->append(message);
371+
if (IS_REPEATED_EVENT(event)) {
372+
char m[100];
373+
snprintf(m, sizeof(m), repeatedTimes, event->arg0);
374+
s->append(m);
375+
}
336376
} else {
337377
#pragma GCC diagnostic push
338378
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
@@ -341,6 +381,9 @@ TimeTrace::printInternal(std::vector<TimeTrace::Buffer*>* buffers, string* s) {
341381
#pragma GCC diagnostic pop
342382
fprintf(output, "%8.1f ns (+%6.1f ns): %s", ns, ns - prevTime,
343383
message);
384+
if (IS_REPEATED_EVENT(event)) {
385+
fprintf(output, repeatedTimes, event->arg0);
386+
}
344387
fputc('\n', output);
345388
}
346389
prevTime = ns;

src/TimeTrace.h

+16
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ class TimeTrace {
8989
uint32_t arg3 = 0) {
9090
record(Cycles::rdtsc(), format, arg0, arg1, arg2, arg3);
9191
}
92+
93+
/**
94+
* Similar to TimeTrace::record but collapse consecutive messages that are
95+
* identical. To simplify the detection of duplicate messages, this function
96+
* currently doesn't support messages with printf format specifiers.
97+
*
98+
* \param message
99+
* A message string with no printf format specifiers.
100+
*/
101+
static inline void recordIfNotDup(const char* message) {
102+
if (threadBuffer == NULL) {
103+
createThreadBuffer();
104+
}
105+
threadBuffer->recordIfNotDup(Cycles::rdtsc(), message);
106+
}
92107
static void reset();
93108
/**
94109
* When this bool is set, the print method in TimeTrace will use the
@@ -153,6 +168,7 @@ class TimeTrace {
153168
uint32_t arg2 = 0, uint32_t arg3 = 0) {
154169
record(Cycles::rdtsc(), format, arg0, arg1, arg2, arg3);
155170
}
171+
void recordIfNotDup(uint64_t timestamp, const char* format);
156172
void reset();
157173

158174
protected:

0 commit comments

Comments
 (0)