trace: add types for ctf tracing

genodelabs/genode#4352
This commit is contained in:
Johannes Schlatow 2022-05-20 15:28:21 +02:00 committed by Christian Helmuth
parent 810bbc0484
commit 062881a484
6 changed files with 261 additions and 0 deletions

View File

@ -0,0 +1,45 @@
/*
* \brief Generic type for CTF event headers
* \author Johannes Schlatow
* \date 2021-08-03
*/
/*
* Copyright (C) 2021 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.
*/
#ifndef _CTF__EVENT_HEADER_H_
#define _CTF__EVENT_HEADER_H_
#include <base/fixed_stdint.h>
#include <trace/timestamp.h>
#include <ctf/timestamp.h>
namespace Ctf {
using namespace Genode::Trace;
struct Event_header_base;
}
/**
* Base type for CTF trace events. The event type is identifed by its id.
*/
struct Ctf::Event_header_base
{
const uint8_t _id;
Timestamp_base _timestamp { (Timestamp_base)Trace::timestamp() };
Timestamp_base timestamp() const { return _timestamp; }
void timestamp(Timestamp_base ts) { _timestamp = ts; }
Event_header_base(uint8_t id)
: _id(id)
{ }
} __attribute__((packed));
#endif /* _CTF__EVENT_HEADER_H_ */

View File

@ -0,0 +1,34 @@
/*
* \brief Ctf trace event for logging names
* \author Johannes Schlatow
* \date 2021-08-03
*/
/*
* Copyright (C) 2021 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.
*/
#ifndef _CTF__EVENTS__NAMED_H_
#define _CTF__EVENTS__NAMED_H_
#include <util/string.h>
namespace Ctf {
struct Named_event;
}
/**
* Base type for CTF trace events with a string as payload.
*/
struct Ctf::Named_event
{
char _name[0];
Named_event(const char *name, size_t len) {
Genode::copy_cstring(_name, name, len); }
} __attribute__((packed));
#endif /* _CTF__EVENTS__NAMED_H_ */

View File

@ -0,0 +1,133 @@
/*
* \brief Packet header and context types
* \author Johannes Schlatow
* \date 2021-08-04
*/
/*
* Copyright (C) 2021 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.
*/
#ifndef _CTF__PACKET_TYPES_H_
#define _CTF__PACKET_TYPES_H_
#include <base/trace/types.h>
#include <ctf/timestamp.h>
#include <util/register.h>
namespace Ctf {
using namespace Genode;
using Genode::Trace::Thread_name;
struct Packet_header;
}
/**
* Definition of our CTF packet header. A CTF stream may contain multiple
* packets that bundle an arbitrary number of events. In order to reduce the
* payload for every CTF event, we put shared information (such as session and
* thread name) into the packet header.
*
* See https://diamon.org/ctf/ for the CTF spec.
*/
struct Ctf::Packet_header
{
uint32_t _magic { 0xC1FC1FC1 };
uint32_t _stream_id { };
Timestamp_base _timestamp_start { };
Timestamp_base _timestamp_end { };
uint32_t _total_length { };
uint16_t _hdr_length { sizeof(Packet_header) * 8 };
uint16_t _affinity { };
uint8_t _priority { };
char _session_and_thread[0] { };
struct Affinity : Register<16>
{
struct Xpos : Bitfield<0,4> { };
struct Ypos : Bitfield<4,4> { };
struct Width : Bitfield<8,4> { };
struct Height : Bitfield<12,4> { };
};
Packet_header(Session_label const &label,
Thread_name const &thread,
Genode::Affinity::Location const &affinity,
unsigned priority,
Genode::size_t buflen,
unsigned streamid=0)
: _stream_id(streamid),
_affinity(Affinity::Xpos::bits((uint16_t)affinity.xpos()) |
Affinity::Ypos::bits((uint16_t)affinity.ypos()) |
Affinity::Width::bits((uint16_t)affinity.width()) |
Affinity::Height::bits((uint16_t)affinity.height())),
_priority((uint8_t)priority)
{
Genode::size_t char_offset = 0;
if (_hdr_length/8 < buflen) {
Genode::size_t sess_len = Genode::min(label.length(), buflen - _hdr_length/8);
Genode::copy_cstring(&_session_and_thread[char_offset], label.string(), sess_len);
_hdr_length += (uint16_t)(sess_len * 8);
char_offset = sess_len;
}
if (_hdr_length/8 < buflen) {
Genode::size_t thread_len = Genode::min(thread.length(), buflen - _hdr_length/8);
Genode::copy_cstring(&_session_and_thread[char_offset], thread.string(), thread_len);
_hdr_length += (uint16_t)(thread_len * 8);
}
_total_length = _hdr_length;
}
void reset()
{
_total_length = _hdr_length;
_timestamp_start = 0;
_timestamp_end = 0;
}
/**
* If event fits into provided buffer, update struct with timestamp and
* length of new event. Makes sure that timestamps are monotonically
* increasing and calls the provided functor(char * ptr, Timestamp_base ts),
* where ptr is the target address and ts is the updated timestamp.
*/
template <typename FUNC>
void append_event(char * buffer,
Genode::size_t bufsz,
Timestamp_base timestamp,
Genode::size_t length,
FUNC && fn)
{
using Ctf::Timestamp;
/* check whether event fits into buffer */
if (total_length_bytes()+length > bufsz)
return;
/* update timestamps */
if (_timestamp_start == 0)
_timestamp_start = timestamp;
else if (Timestamp::extended() &&
Timestamp::Base::get(_timestamp_end) > Timestamp::Base::get(timestamp)) {
/* timer wrapped, increase manually managed offset */
Timestamp::Extension::set(_timestamp_end, Timestamp::Extension::get(_timestamp_end)+1);
}
Timestamp::Base::set(_timestamp_end, timestamp);
/* call provided functor with target address and modified timestamp */
fn(&buffer[total_length_bytes()], _timestamp_end);
_total_length += (uint32_t)(length * 8);
}
uint32_t total_length_bytes() const { return _total_length / 8; }
bool empty() const { return _total_length <= _hdr_length; }
} __attribute__((packed));
#endif /* _CTF__PACKET_TYPES_H_ */

View File

@ -0,0 +1,40 @@
/*
* \brief Generic timestamp for CTF traces
* \author Johannes Schlatow
* \date 2021-08-04
*/
/*
* Copyright (C) 2021 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.
*/
#ifndef _CTF__TIMESTAMP_H_
#define _CTF__TIMESTAMP_H_
#include <base/fixed_stdint.h>
#include <util/register.h>
namespace Ctf {
using namespace Genode;
/* generic fixed-width timestamp type for different Trace::Timestamp widths */
template <int PWIDTH>
struct _Timestamp : Register<64> {
static constexpr bool extended() { return PWIDTH < 64; }
/* define _PWIDTH to get a valid Extension Bitfield even for 64-bit */
enum { _PWIDTH = PWIDTH < 64 ? PWIDTH : 0 };
struct Base : Bitfield<0, PWIDTH> { };
struct Extension : Bitfield<_PWIDTH, 64-_PWIDTH> { };
};
typedef _Timestamp<sizeof(Trace::Timestamp)*8> Timestamp;
typedef uint64_t __attribute__((aligned(1))) Timestamp_base;
}
#endif /* _CTF__TIMESTAMP_H_ */

View File

@ -0,0 +1,8 @@
content: include/ctf LICENSE
include/ctf:
$(mirror_from_rep_dir)
LICENSE:
cp $(GENODE_DIR)/LICENSE $@

View File

@ -0,0 +1 @@
2022-05-11 73fe945a53926f04e8062293aa2c2ce39541fc85