Blame source/vdo/base/trace.c

Packit Service d40955
/*
Packit Service d40955
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service d40955
 *
Packit Service d40955
 * This program is free software; you can redistribute it and/or
Packit Service d40955
 * modify it under the terms of the GNU General Public License
Packit Service d40955
 * as published by the Free Software Foundation; either version 2
Packit Service d40955
 * of the License, or (at your option) any later version.
Packit Service d40955
 * 
Packit Service d40955
 * This program is distributed in the hope that it will be useful,
Packit Service d40955
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d40955
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d40955
 * GNU General Public License for more details.
Packit Service d40955
 * 
Packit Service d40955
 * You should have received a copy of the GNU General Public License
Packit Service d40955
 * along with this program; if not, write to the Free Software
Packit Service d40955
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service d40955
 * 02110-1301, USA. 
Packit Service d40955
 *
Packit Service d40955
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/trace.c#1 $
Packit Service d40955
 */
Packit Service d40955
Packit Service d40955
#include "trace.h"
Packit Service d40955
Packit Service d40955
#include "logger.h"
Packit Service d40955
#include "stringUtils.h"
Packit Service d40955
#include "timeUtils.h"
Packit Service d40955
Packit Service d40955
TRACE_LOCATION_SECTION TraceLocationRecord baseTraceLocation[] = {
Packit Service d40955
  {
Packit Service d40955
    .function = "<none>",
Packit Service d40955
    .line     = 0,
Packit Service d40955
  },
Packit Service d40955
};
Packit Service d40955
Packit Service d40955
/**********************************************************************/
Packit Service d40955
void addTraceRecord(Trace *trace, TraceLocation location)
Packit Service d40955
{
Packit Service d40955
  if (trace->used < NUM_TRACE_RECORDS) {
Packit Service d40955
    TraceRecord *record = &trace->records[trace->used];
Packit Service d40955
    trace->used++;
Packit Service d40955
Packit Service d40955
    record->when     = nowUsec();
Packit Service d40955
    record->tid      = getThreadId();
Packit Service d40955
    record->location = location - baseTraceLocation;
Packit Service d40955
  }
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/*
Packit Service d40955
 * The record display format used is a comma-separated list, each item
Packit Service d40955
 * containing: optional function name; "@" + timestamp with seconds
Packit Service d40955
 * and microseconds for the first record; if not the first record, "+"
Packit Service d40955
 * and offset in microseconds from previous timestamp.
Packit Service d40955
 *
Packit Service d40955
 * If the buffer's too small, it'll end with an ellipsis.
Packit Service d40955
 */
Packit Service d40955
void formatTrace(Trace  *trace,
Packit Service d40955
                 char   *buffer,
Packit Service d40955
                 size_t  bufferLength,
Packit Service d40955
                 size_t *msgLen)
Packit Service d40955
{
Packit Service d40955
  if (trace == NULL) {
Packit Service d40955
    return;
Packit Service d40955
  }
Packit Service d40955
  memset(buffer, 0, bufferLength);
Packit Service d40955
  char *buf = buffer;
Packit Service d40955
  char *bufferEnd = buffer + bufferLength - 1;
Packit Service d40955
  if (trace->used > 0) {
Packit Service d40955
    TraceRecord *record = &trace->records[0];
Packit Service d40955
    TraceLocationRecord *location = baseTraceLocation + record->location;
Packit Service d40955
    snprintf(buf, bufferEnd - buf, "Trace[%s@%llu.%06llu",
Packit Service d40955
             location->function, record->when / 1000000,
Packit Service d40955
             record->when % 1000000);
Packit Service d40955
    buf += strlen(buf);
Packit Service d40955
Packit Service d40955
    for (unsigned int i = 1; i < trace->used; i++) {
Packit Service d40955
      TraceRecord *prev = record;
Packit Service d40955
      record++;
Packit Service d40955
Packit Service d40955
      snprintf(buf, bufferEnd - buf, ",");
Packit Service d40955
      buf += strlen(buf);
Packit Service d40955
Packit Service d40955
      location = baseTraceLocation + record->location;
Packit Service d40955
      unsigned long timeDiff = record->when - prev->when;
Packit Service d40955
      snprintf(buf, bufferEnd - buf, "%s+%lu",
Packit Service d40955
               location->function, timeDiff);
Packit Service d40955
      buf += strlen(buf);
Packit Service d40955
    }
Packit Service d40955
    if (bufferLength > 7) {
Packit Service d40955
      if (buffer[bufferLength-5] != '\0') {
Packit Service d40955
        // too long
Packit Service d40955
        strcpy(buffer+bufferLength-5, "...]");
Packit Service d40955
      } else {
Packit Service d40955
        strcpy(buf, "]");
Packit Service d40955
      }
Packit Service d40955
    }
Packit Service d40955
  }
Packit Service d40955
  *msgLen = (buf - buffer);
Packit Service d40955
}