@@ -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;
0 commit comments