rusefi-1/firmware/development/perf_trace.cpp

93 lines
1.6 KiB
C++
Raw Normal View History

2019-10-11 17:43:21 -07:00
2019-10-14 23:34:12 -07:00
#include "efifeatures.h"
2019-10-11 17:43:21 -07:00
#include "perf_trace.h"
#include "efitime.h"
#include "os_util.h"
2019-10-14 23:34:12 -07:00
#define TRACE_BUFFER_LENGTH 2048
2019-10-11 17:43:21 -07:00
2019-10-14 23:34:12 -07:00
enum class EPhase : char
2019-10-11 17:43:21 -07:00
{
Start,
End,
InstantThread,
InstantGlobal,
};
struct TraceEntry
{
PE Event;
2019-10-14 23:34:12 -07:00
EPhase Phase;
2019-10-11 17:43:21 -07:00
uint8_t Data;
uint8_t ThreadId;
uint32_t Timestamp;
};
static_assert(sizeof(TraceEntry) == 8);
static TraceEntry s_traceBuffer[TRACE_BUFFER_LENGTH];
static size_t s_nextIdx = 0;
2019-10-14 23:34:12 -07:00
static bool s_isTracing = true;
void perfEventImpl(PE event, EPhase phase, uint8_t data)
2019-10-11 17:43:21 -07:00
{
2019-10-14 23:34:12 -07:00
if constexpr (!ENABLE_PERF_TRACE) {
return;
}
if (!s_isTracing) {
2019-10-11 17:43:21 -07:00
return;
}
uint32_t timestamp = getTimeNowLowerNt();
size_t idx;
// Critical section: reserve index under lock
{
bool wasLocked = lockAnyContext();
idx = s_nextIdx++;
2019-10-14 23:34:12 -07:00
if (s_nextIdx >= TRACE_BUFFER_LENGTH) {
2019-10-11 17:43:21 -07:00
s_nextIdx = 0;
2019-10-14 23:34:12 -07:00
s_isTracing = false;
2019-10-11 17:43:21 -07:00
}
if (!wasLocked) {
unlockAnyContext();
}
}
// We can safely write data out of the lock, our spot is reserved
2019-10-14 23:34:12 -07:00
volatile TraceEntry& entry = s_traceBuffer[idx];
2019-10-11 17:43:21 -07:00
entry.Event = event;
2019-10-14 23:34:12 -07:00
entry.Phase = phase;
entry.ThreadId = static_cast<uint8_t>(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
2019-10-11 17:43:21 -07:00
entry.Timestamp = timestamp;
entry.Data = data;
}
2019-10-14 23:34:12 -07:00
void perfEventBegin(PE event, uint8_t data) {
perfEventImpl(event, EPhase::Start, data);
2019-10-11 17:43:21 -07:00
}
2019-10-14 23:34:12 -07:00
void perfEventEnd(PE event, uint8_t data) {
perfEventImpl(event, EPhase::End, data);
2019-10-11 17:43:21 -07:00
}
2019-10-14 23:34:12 -07:00
void perfEventInstantGlobal(PE event, uint8_t data) {
perfEventImpl(event, EPhase::InstantGlobal, data);
2019-10-11 17:43:21 -07:00
}
2019-10-14 23:34:12 -07:00
size_t perfTraceEnable() {
s_isTracing = true;
return sizeof(s_traceBuffer);
}
const uint8_t* getTraceBuffer() {
return reinterpret_cast<const uint8_t*>(s_traceBuffer);
2019-10-11 17:43:21 -07:00
}