2019-04-11 09:20:48 +00:00
|
|
|
/*
|
|
|
|
* \brief Wrapper for Trace::Buffer that adds some convenient functionality
|
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2018-01-12
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 Genode Labs GmbH
|
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
|
|
*/
|
|
|
|
|
2021-08-23 15:00:01 +00:00
|
|
|
#ifndef _TRACE__TRACE_BUFFER_H_
|
|
|
|
#define _TRACE__TRACE_BUFFER_H_
|
2019-04-11 09:20:48 +00:00
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <base/trace/buffer.h>
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper for Trace::Buffer that adds some convenient functionality
|
|
|
|
*/
|
|
|
|
class Trace_buffer
|
|
|
|
{
|
|
|
|
private:
|
2022-05-20 10:00:09 +00:00
|
|
|
using Entry = Genode::Trace::Buffer::Entry;
|
2019-04-11 09:20:48 +00:00
|
|
|
|
|
|
|
Genode::Trace::Buffer &_buffer;
|
2022-05-20 10:00:09 +00:00
|
|
|
Entry _curr { Entry::invalid() };
|
2022-02-18 15:43:03 +00:00
|
|
|
unsigned long long _lost_count { 0 };
|
2019-04-11 09:20:48 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
Trace_buffer(Genode::Trace::Buffer &buffer) : _buffer(buffer) { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call functor for each entry that wasn't yet processed
|
|
|
|
*/
|
|
|
|
template <typename FUNC>
|
|
|
|
void for_each_new_entry(FUNC && functor, bool update = true)
|
|
|
|
{
|
|
|
|
using namespace Genode;
|
|
|
|
|
2022-05-20 10:00:09 +00:00
|
|
|
if (!_buffer.initialized())
|
|
|
|
return;
|
|
|
|
|
2022-02-18 15:43:03 +00:00
|
|
|
bool lost = _buffer.lost_entries() != _lost_count;
|
|
|
|
if (lost) {
|
|
|
|
warning("lost ", _buffer.lost_entries() - _lost_count,
|
|
|
|
", entries; you might want to raise buffer size");
|
|
|
|
_lost_count = (unsigned)_buffer.lost_entries();
|
2021-08-23 15:00:01 +00:00
|
|
|
}
|
2019-04-11 09:20:48 +00:00
|
|
|
|
2022-05-20 10:00:09 +00:00
|
|
|
Entry entry { _curr };
|
2021-08-06 15:13:43 +00:00
|
|
|
|
|
|
|
/**
|
2022-02-04 15:56:21 +00:00
|
|
|
* Iterate over all entries that were not processed yet.
|
2021-08-06 15:13:43 +00:00
|
|
|
*
|
2022-02-04 15:56:21 +00:00
|
|
|
* A note on terminology: The head of the buffer marks the write
|
|
|
|
* position. The first entry is the one that starts at the lowest
|
2022-05-20 10:00:09 +00:00
|
|
|
* memory address. The next entry returns an invalid entry
|
|
|
|
* if the 'last' entry of the buffer (highest address) was reached.
|
2021-08-06 15:13:43 +00:00
|
|
|
*/
|
2022-02-04 15:56:21 +00:00
|
|
|
for (; !entry.head(); entry = _buffer.next(entry)) {
|
|
|
|
/* continue at first entry if we hit the end of the buffer */
|
|
|
|
if (entry.last())
|
2021-08-06 15:13:43 +00:00
|
|
|
entry = _buffer.first();
|
2022-02-07 14:57:52 +00:00
|
|
|
|
2022-02-04 15:56:21 +00:00
|
|
|
/* skip empty entries */
|
|
|
|
if (entry.empty())
|
2022-02-07 14:57:52 +00:00
|
|
|
continue;
|
2019-04-11 09:20:48 +00:00
|
|
|
|
2022-02-04 15:56:21 +00:00
|
|
|
/* functor may return false to continue processing later on */
|
|
|
|
if (!functor(entry))
|
2019-04-11 09:20:48 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-02-04 15:56:21 +00:00
|
|
|
/* remember the next to be processed entry in _curr */
|
|
|
|
if (update) _curr = entry;
|
2019-04-11 09:20:48 +00:00
|
|
|
}
|
|
|
|
|
2022-03-11 14:13:39 +00:00
|
|
|
void * address() const { return &_buffer; }
|
2019-04-11 09:20:48 +00:00
|
|
|
|
2023-04-04 12:14:36 +00:00
|
|
|
bool empty() const { return !_buffer.initialized() || _curr.head(); }
|
2022-03-11 14:13:39 +00:00
|
|
|
};
|
2019-04-11 09:20:48 +00:00
|
|
|
|
2021-08-23 15:00:01 +00:00
|
|
|
#endif /* _TRACE__TRACE_BUFFER_H_ */
|