99 lines
1.9 KiB
C++
99 lines
1.9 KiB
C++
/*
|
|
* utility_asynclogger.hpp
|
|
*
|
|
* Created on: Apr 1, 2021
|
|
* Author: erki
|
|
*/
|
|
|
|
#ifndef SKULLC_UTILITY_ASYNCLOGGER_HPP_
|
|
#define SKULLC_UTILITY_ASYNCLOGGER_HPP_
|
|
|
|
#include "utility_atomicscopeguard.hpp"
|
|
#include "utility_ilogger.hpp"
|
|
#include "utility_ringbuffer.hpp"
|
|
|
|
#include <array>
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
|
|
namespace Utility
|
|
{
|
|
|
|
template<typename T, typename H, std::size_t BufferCount,
|
|
std::size_t BufferSize>
|
|
class AsyncLogger : public ILogger
|
|
{
|
|
public:
|
|
using serial_interface = T;
|
|
using hal = H;
|
|
|
|
AsyncLogger() = delete;
|
|
explicit AsyncLogger(const serial_interface& serial) : serial_(serial) {}
|
|
|
|
AsyncLogger(const AsyncLogger&) = delete;
|
|
AsyncLogger(AsyncLogger&&) = delete;
|
|
AsyncLogger& operator=(const AsyncLogger&) = delete;
|
|
AsyncLogger& operator=(AsyncLogger&&) = delete;
|
|
|
|
void log(const char* format, ...)
|
|
{
|
|
{
|
|
AtomicScopeGuard<hal> s;
|
|
|
|
if (buffer_queue_.size() == buffer_queue_.max_size())
|
|
return;
|
|
}
|
|
|
|
std::va_list args;
|
|
va_start(args, format);
|
|
|
|
Data_& tail = (*buffer_queue_.end());
|
|
tail.length =
|
|
vsnprintf(tail.buffer.data(), tail.buffer.size(), format, args);
|
|
|
|
{
|
|
AtomicScopeGuard<hal> s;
|
|
buffer_queue_.increment_tail();
|
|
|
|
if (!in_flight_)
|
|
sendNextLog_();
|
|
}
|
|
|
|
va_end(args);
|
|
}
|
|
|
|
void txCompleteCallback()
|
|
{
|
|
if (!buffer_queue_.empty())
|
|
sendNextLog_();
|
|
else
|
|
in_flight_ = false;
|
|
}
|
|
|
|
private:
|
|
struct Data_
|
|
{
|
|
std::array<char, BufferSize> buffer;
|
|
std::int32_t length = 0;
|
|
};
|
|
|
|
Ringbuffer<Data_, BufferCount> buffer_queue_;
|
|
serial_interface serial_;
|
|
/// @todo: thread safety
|
|
bool in_flight_ = false;
|
|
|
|
void sendNextLog_()
|
|
{
|
|
in_flight_ = true;
|
|
|
|
Data_& head = buffer_queue_.front();
|
|
serial_.transmit(reinterpret_cast<uint8_t*>(head.buffer.data()),
|
|
head.length);
|
|
buffer_queue_.pop_front();
|
|
}
|
|
};
|
|
|
|
}// namespace Utility
|
|
|
|
#endif /* SKULLC_UTILITY_ASYNCLOGGER_HPP_ */
|