mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-11 20:01:48 +00:00
committed by
Christian Helmuth
parent
ae0e0c118e
commit
c14007f559
129
repos/gems/src/lib/vfs/trace/directory_dictionary.h
Normal file
129
repos/gems/src/lib/vfs/trace/directory_dictionary.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* \brief A dictionary of dictionaries that form a directory structure
|
||||||
|
* \author Sebastian Sumpf
|
||||||
|
* \date 2023-03-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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 _DIRECTORY_DICTIONARY_H_
|
||||||
|
#define _DIRECTORY_DICTIONARY_H_
|
||||||
|
|
||||||
|
#include <util/dictionary.h>
|
||||||
|
#include "session_label.h"
|
||||||
|
|
||||||
|
namespace Vfs {
|
||||||
|
class Label;
|
||||||
|
class Trace_node;
|
||||||
|
class Trace_directory;
|
||||||
|
|
||||||
|
using Dictionary = Genode::Dictionary<Vfs::Trace_node, Vfs::Label>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Vfs::Label : Genode::String<32>
|
||||||
|
{
|
||||||
|
using String::String;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Vfs::Trace_node : public Dictionary::Element
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Allocator &_alloc;
|
||||||
|
Trace::Subject_id const _id;
|
||||||
|
Dictionary _dict { };
|
||||||
|
|
||||||
|
/* add version to duplicates (like "idle" or "cross" */
|
||||||
|
Label _thread_name(Session_label const &thread_name)
|
||||||
|
{
|
||||||
|
if (!_dict.exists(thread_name)) return Label(thread_name);
|
||||||
|
|
||||||
|
unsigned version { 0 };
|
||||||
|
while (true) {
|
||||||
|
Label label { thread_name, ".", ++version };
|
||||||
|
if (!_dict.exists(label)) return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Trace_node(Allocator &alloc, Dictionary &dict, Session_label const &label,
|
||||||
|
Trace::Subject_id const id = 0)
|
||||||
|
:
|
||||||
|
Dictionary::Element(dict, Label(label)),
|
||||||
|
_alloc(alloc), _id(id)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void insert(Session_label const &label,
|
||||||
|
Session_label const &thread_name,
|
||||||
|
Trace::Subject_id const id)
|
||||||
|
{
|
||||||
|
/* leaf node -> thread_name<.version> */
|
||||||
|
if (!label.valid()) {
|
||||||
|
new (_alloc) Trace_node(_alloc, _dict, _thread_name(thread_name), id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dict.with_element(label.first_element(),
|
||||||
|
[&] (Trace_node &node) {
|
||||||
|
node.insert(label.suffix(), thread_name, id); },
|
||||||
|
[&]() {
|
||||||
|
/* no match add first element of label to this dict */
|
||||||
|
Trace_node *node = new (_alloc) Trace_node(_alloc, _dict, label.first_element());
|
||||||
|
node->insert(label.suffix(), thread_name, id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xml(Xml_generator &xml) const
|
||||||
|
{
|
||||||
|
_dict.for_each([&] (Trace_node const &node) {
|
||||||
|
if (node.id() == 0)
|
||||||
|
xml.node("dir", [&] () {
|
||||||
|
xml.attribute("name", node.name);
|
||||||
|
node.xml(xml);
|
||||||
|
});
|
||||||
|
else
|
||||||
|
xml.node("trace_node", [&] () {
|
||||||
|
xml.attribute("name", node.name);
|
||||||
|
xml.attribute("id", node.id().id);
|
||||||
|
node.xml(xml);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace::Subject_id const &id() const { return _id; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Vfs::Trace_directory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Allocator &_alloc;
|
||||||
|
Dictionary _root_dict { };
|
||||||
|
Trace_node _root { _alloc, _root_dict, Session_label() };
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Trace_directory(Allocator &alloc) : _alloc(alloc) { }
|
||||||
|
|
||||||
|
void insert(Trace::Subject_info const &info, Trace::Subject_id const id)
|
||||||
|
{
|
||||||
|
_root.insert(info.session_label(), info.thread_name(), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xml(Xml_generator &xml)
|
||||||
|
{
|
||||||
|
_root.xml(xml);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _DIRECTORY_DICTIONARY_H_ */
|
@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief A tree of AVL trees that forms a directory structure
|
|
||||||
* \author Sebastian Sumpf
|
|
||||||
* \date 2019-06-14
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2019 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 _DIRECTORY_TREE_H_
|
|
||||||
#define _DIRECTORY_TREE_H_
|
|
||||||
|
|
||||||
#include <util/avl_string.h>
|
|
||||||
#include "session_label.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Vfs {
|
|
||||||
class Directory_tree;
|
|
||||||
class Trace_node;
|
|
||||||
struct Label;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Genode {
|
|
||||||
template <typename> class Avl_node_tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename NT>
|
|
||||||
class Genode::Avl_node_tree : public NT
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
using Tree = Avl_tree<NT>;
|
|
||||||
using Node = Avl_node<NT>;
|
|
||||||
|
|
||||||
Tree _tree { };
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using NT::NT;
|
|
||||||
|
|
||||||
void insert(Node *node) { _tree.insert(node); }
|
|
||||||
|
|
||||||
Tree &tree() { return _tree; }
|
|
||||||
|
|
||||||
Node *find_by_name(char const *name)
|
|
||||||
{
|
|
||||||
if (!_tree.first()) return nullptr;
|
|
||||||
|
|
||||||
Node *node = _tree.first()->find_by_name(name);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Vfs::Label : Genode::String<32>
|
|
||||||
{
|
|
||||||
using String::String;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Vfs::Trace_node : public Vfs::Label,
|
|
||||||
public Avl_node_tree<Genode::Avl_string_base>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
Allocator &_alloc;
|
|
||||||
Trace::Subject_id const _id;
|
|
||||||
|
|
||||||
Trace_node *_find_by_name(char const *name)
|
|
||||||
{
|
|
||||||
Node *node = find_by_name(name);
|
|
||||||
return node ? static_cast<Trace_node *>(node) : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Trace_node(Genode::Allocator &alloc, Session_label const &label,
|
|
||||||
Trace::Subject_id const id = 0)
|
|
||||||
: Vfs::Label(label), Avl_node_tree(string()),
|
|
||||||
_alloc(alloc), _id(id)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Trace_node &insert(Session_label const &label)
|
|
||||||
{
|
|
||||||
if (!label.valid()) return *this;
|
|
||||||
|
|
||||||
Trace_node *node = _find_by_name(label.first_element().string());
|
|
||||||
if (!node) {
|
|
||||||
node = new(_alloc) Trace_node(_alloc, label.first_element());
|
|
||||||
Avl_node_tree::insert(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node->insert(label.suffix());
|
|
||||||
}
|
|
||||||
|
|
||||||
void xml(Genode::Xml_generator &xml) const
|
|
||||||
{
|
|
||||||
_tree.for_each([&] (Genode::Avl_string_base const &name) {
|
|
||||||
Trace_node const &node = static_cast<Trace_node const &>(name);
|
|
||||||
|
|
||||||
if (node.id() == 0)
|
|
||||||
xml.node("dir", [&] () {
|
|
||||||
xml.attribute("name", node.name());
|
|
||||||
node.xml(xml);
|
|
||||||
});
|
|
||||||
else
|
|
||||||
xml.node("trace_node", [&] () {
|
|
||||||
xml.attribute("name", node.name());
|
|
||||||
xml.attribute("id", node.id().id);
|
|
||||||
node.xml(xml);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace::Subject_id const &id() const { return _id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Vfs::Directory_tree : public Genode::Avl_tree<Trace_node>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
Allocator &_alloc;
|
|
||||||
Trace_node _root { _alloc, Session_label() };
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Directory_tree(Genode::Allocator &alloc)
|
|
||||||
: _alloc(alloc) { }
|
|
||||||
|
|
||||||
void insert(Trace::Subject_info const &info, Trace::Subject_id const id)
|
|
||||||
{
|
|
||||||
Trace_node &leaf = _root.insert(info.session_label());
|
|
||||||
Trace_node *node = new (_alloc) Trace_node(_alloc, info.thread_name(), id);
|
|
||||||
leaf.Avl_node_tree::insert(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void xml(Genode::Xml_generator &xml)
|
|
||||||
{
|
|
||||||
_root.xml(xml);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _DIRECTORY_TREE_H_ */
|
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 Genode Labs GmbH
|
* Copyright (C) 2023 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
@ -22,8 +22,7 @@
|
|||||||
#include <trace_session/connection.h>
|
#include <trace_session/connection.h>
|
||||||
#include <trace/trace_buffer.h>
|
#include <trace/trace_buffer.h>
|
||||||
|
|
||||||
#include "directory_tree.h"
|
#include "directory_dictionary.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Vfs_trace {
|
namespace Vfs_trace {
|
||||||
|
|
||||||
@ -349,7 +348,7 @@ struct Vfs_trace::Local_factory : File_system_factory
|
|||||||
|
|
||||||
Trace::Connection _trace;
|
Trace::Connection _trace;
|
||||||
Trace::Policy_id _policy_id { 0 };
|
Trace::Policy_id _policy_id { 0 };
|
||||||
Directory_tree _tree { _env.alloc() };
|
Trace_directory _directory { _env.alloc() };
|
||||||
|
|
||||||
void _install_null_policy()
|
void _install_null_policy()
|
||||||
{
|
{
|
||||||
@ -392,7 +391,7 @@ struct Vfs_trace::Local_factory : File_system_factory
|
|||||||
if (info.state() == Trace::Subject_info::DEAD)
|
if (info.state() == Trace::Subject_info::DEAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_tree.insert(info, id);
|
_directory.insert(info, id);
|
||||||
});
|
});
|
||||||
|
|
||||||
_install_null_policy();
|
_install_null_policy();
|
||||||
@ -415,11 +414,11 @@ class Vfs_trace::File_system : private Local_factory,
|
|||||||
|
|
||||||
typedef String<512*1024> Config;
|
typedef String<512*1024> Config;
|
||||||
|
|
||||||
static char const *_config(Vfs::Env &vfs_env, Directory_tree &tree)
|
static char const *_config(Vfs::Env &vfs_env, Trace_directory &directory)
|
||||||
{
|
{
|
||||||
char *buf = (char *)vfs_env.alloc().alloc(Config::capacity());
|
char *buf = (char *)vfs_env.alloc().alloc(Config::capacity());
|
||||||
Xml_generator xml(buf, Config::capacity(), "node", [&] () {
|
Xml_generator xml(buf, Config::capacity(), "node", [&] () {
|
||||||
tree.xml(xml);
|
directory.xml(xml);
|
||||||
});
|
});
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
@ -429,7 +428,7 @@ class Vfs_trace::File_system : private Local_factory,
|
|||||||
|
|
||||||
File_system(Vfs::Env &vfs_env, Genode::Xml_node node)
|
File_system(Vfs::Env &vfs_env, Genode::Xml_node node)
|
||||||
: Local_factory(vfs_env, node),
|
: Local_factory(vfs_env, node),
|
||||||
Vfs::Dir_file_system(vfs_env, Xml_node(_config(vfs_env, _tree)), *this)
|
Vfs::Dir_file_system(vfs_env, Xml_node(_config(vfs_env, _directory)), *this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
char const *type() override { return "trace"; }
|
char const *type() override { return "trace"; }
|
||||||
|
Reference in New Issue
Block a user