53 lines
1.4 KiB
C
53 lines
1.4 KiB
C
|
|
#pragma once
|
||
|
|
#include <cstdint>
|
||
|
|
#include <string>
|
||
|
|
#include <string_view>
|
||
|
|
#include "pico/time.h"
|
||
|
|
|
||
|
|
struct log_entry {
|
||
|
|
uint32_t timestamp_us;
|
||
|
|
std::string message;
|
||
|
|
};
|
||
|
|
|
||
|
|
class log_iterator {
|
||
|
|
const log_entry* data;
|
||
|
|
uint16_t base;
|
||
|
|
uint16_t cap;
|
||
|
|
uint16_t pos;
|
||
|
|
public:
|
||
|
|
log_iterator(const log_entry* d, uint16_t b, uint16_t c, uint16_t p)
|
||
|
|
: data(d), base(b), cap(c), pos(p) {}
|
||
|
|
const log_entry& operator*() const { return data[(base + pos) % cap]; }
|
||
|
|
log_iterator& operator++() { ++pos; return *this; }
|
||
|
|
bool operator!=(const log_iterator& o) const { return pos != o.pos; }
|
||
|
|
};
|
||
|
|
|
||
|
|
class log_view {
|
||
|
|
const log_entry* data;
|
||
|
|
uint16_t base;
|
||
|
|
uint16_t cap;
|
||
|
|
uint16_t count;
|
||
|
|
public:
|
||
|
|
log_view(const log_entry* d, uint16_t b, uint16_t c, uint16_t n)
|
||
|
|
: data(d), base(b), cap(c), count(n) {}
|
||
|
|
log_iterator begin() const { return {data, base, cap, 0}; }
|
||
|
|
log_iterator end() const { return {data, base, cap, count}; }
|
||
|
|
};
|
||
|
|
|
||
|
|
log_view log_entries();
|
||
|
|
|
||
|
|
void dlog(std::string_view msg);
|
||
|
|
|
||
|
|
__attribute__((format(printf, 1, 2)))
|
||
|
|
void dlogf(const char* fmt, ...);
|
||
|
|
|
||
|
|
template <typename F>
|
||
|
|
inline void dlog_if_slow(std::string_view label, uint32_t threshold_us, F&& fn) {
|
||
|
|
uint32_t t0 = time_us_32();
|
||
|
|
fn();
|
||
|
|
uint32_t elapsed = time_us_32() - t0;
|
||
|
|
if (elapsed > threshold_us) {
|
||
|
|
dlogf("%.*s %luus", static_cast<int>(label.size()), label.data(), static_cast<unsigned long>(elapsed));
|
||
|
|
}
|
||
|
|
}
|