mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-10 21:01:49 +00:00
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
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -22,8 +22,7 @@
|
||||
#include <trace_session/connection.h>
|
||||
#include <trace/trace_buffer.h>
|
||||
|
||||
#include "directory_tree.h"
|
||||
|
||||
#include "directory_dictionary.h"
|
||||
|
||||
namespace Vfs_trace {
|
||||
|
||||
@ -349,7 +348,7 @@ struct Vfs_trace::Local_factory : File_system_factory
|
||||
|
||||
Trace::Connection _trace;
|
||||
Trace::Policy_id _policy_id { 0 };
|
||||
Directory_tree _tree { _env.alloc() };
|
||||
Trace_directory _directory { _env.alloc() };
|
||||
|
||||
void _install_null_policy()
|
||||
{
|
||||
@ -392,7 +391,7 @@ struct Vfs_trace::Local_factory : File_system_factory
|
||||
if (info.state() == Trace::Subject_info::DEAD)
|
||||
return;
|
||||
|
||||
_tree.insert(info, id);
|
||||
_directory.insert(info, id);
|
||||
});
|
||||
|
||||
_install_null_policy();
|
||||
@ -415,11 +414,11 @@ class Vfs_trace::File_system : private Local_factory,
|
||||
|
||||
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());
|
||||
Xml_generator xml(buf, Config::capacity(), "node", [&] () {
|
||||
tree.xml(xml);
|
||||
directory.xml(xml);
|
||||
});
|
||||
|
||||
return buf;
|
||||
@ -429,7 +428,7 @@ class Vfs_trace::File_system : private Local_factory,
|
||||
|
||||
File_system(Vfs::Env &vfs_env, Genode::Xml_node 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"; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user