genode/base/src/core/include/trace/source_registry.h

165 lines
3.5 KiB
C++

/*
* \brief Registry containing possible sources of tracing data
* \author Norman Feske
* \date 2013-08-09
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__TRACE__SOURCE_REGISTRY_H_
#define _CORE__INCLUDE__TRACE__SOURCE_REGISTRY_H_
#include <util/list.h>
#include <util/string.h>
#include <base/lock.h>
#include <base/trace/types.h>
/* core includes */
#include <lifetime.h>
/* base-internal include */
#include <trace/control.h>
namespace Genode { namespace Trace {
class Source;
class Source_owner;
class Source_registry;
} }
struct Genode::Trace::Source_owner { };
/**
* Source of tracing data
*
* There is one instance per thread.
*/
class Genode::Trace::Source
:
public Genode::Volatile_object<Genode::Trace::Source>,
public Genode::List<Genode::Trace::Source>::Element
{
private:
unsigned const _unique_id;
Session_label const &_label;
Thread_name const _name;
Control &_control;
Dataspace_capability _policy;
Dataspace_capability _buffer;
Source_owner const *_owner;
static unsigned _alloc_unique_id();
public:
Source(Session_label const &label, Thread_name const &name,
Control &control)
:
_unique_id(_alloc_unique_id()),
_label(label), _name(name), _control(control), _owner(0)
{ }
/*************************************
** Interface used by TRACE service **
*************************************/
Session_label const &label() const { return _label; }
Thread_name const &name() const { return _name; }
void trace(Dataspace_capability policy, Dataspace_capability buffer)
{
_buffer = buffer;
_policy = policy;
_control.trace();
}
void enable() { _control.enable(); }
void disable() { _control.disable(); }
bool try_acquire(Source_owner const *new_owner)
{
if (_owner && _owner != new_owner)
return false;
_owner = new_owner;
return true;
}
bool is_owned_by(Source_owner const *owner) { return owner == _owner; }
void release_ownership(Source_owner const *owner)
{
if (is_owned_by(owner))
_owner = 0;
}
bool error() const { return _control.has_error(); }
bool enabled() const { return _control.is_enabled(); }
/***********************************
** Interface used by CPU service **
***********************************/
Dataspace_capability buffer() const { return _buffer; }
Dataspace_capability policy() const { return _policy; }
unsigned unique_id() const { return _unique_id; }
};
/**
* Registry to tracing sources
*
* There is a single instance within core.
*/
class Genode::Trace::Source_registry
{
private:
Lock _lock;
List<Source> _entries;
public:
/***********************************
** Interface used by CPU service **
***********************************/
void insert(Source *entry)
{
Lock::Guard guard(_lock);
_entries.insert(entry);
}
void remove(Source *entry)
{
Lock::Guard guard(_lock);
_entries.remove(entry);
}
/*************************************
** Interface used by TRACE service **
*************************************/
template <typename TEST, typename INSERT>
void export_sources(TEST &test, INSERT &insert)
{
for (Source *s = _entries.first(); s; s = s->next())
if (!test(s->unique_id()))
insert(s->unique_id(), s->weak_ptr(), s->label(), s->name());
}
};
#endif /* _CORE__INCLUDE__TRACE__SOURCE_REGISTRY_H_ */