165 lines
3.5 KiB
C++
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_ */
|