Remove pointers from Genode::Fifo interface
Replace methods of Genode::Fifo returning pointers with methods which call lambdas with references. Ref #3135
This commit is contained in:
parent
328c1ad96e
commit
38ab456c78
|
@ -35,7 +35,7 @@ using namespace Genode;
|
||||||
void Signal_source_component::release(Signal_context_component &context)
|
void Signal_source_component::release(Signal_context_component &context)
|
||||||
{
|
{
|
||||||
if (context.enqueued())
|
if (context.enqueued())
|
||||||
_signal_queue.remove(&context);
|
_signal_queue.remove(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Signal_source_component::submit(Signal_context_component &context,
|
void Signal_source_component::submit(Signal_context_component &context,
|
||||||
|
@ -45,7 +45,7 @@ void Signal_source_component::submit(Signal_context_component &context,
|
||||||
context.increment_signal_cnt(cnt);
|
context.increment_signal_cnt(cnt);
|
||||||
|
|
||||||
if (!context.enqueued()) {
|
if (!context.enqueued()) {
|
||||||
_signal_queue.enqueue(&context);
|
_signal_queue.enqueue(context);
|
||||||
|
|
||||||
/* wake up client */
|
/* wake up client */
|
||||||
Fiasco::l4_irq_trigger(_blocking_semaphore.data()->kcap());
|
Fiasco::l4_irq_trigger(_blocking_semaphore.data()->kcap());
|
||||||
|
@ -61,9 +61,11 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dequeue and return pending signal */
|
/* dequeue and return pending signal */
|
||||||
Signal_context_component &context = *_signal_queue.dequeue();
|
Signal result { };
|
||||||
Signal result(context.imprint(), context.cnt());
|
_signal_queue.dequeue([&result] (Signal_context_component &context) {
|
||||||
context.reset_signal_cnt();
|
result = Signal(context.imprint(), context.cnt());
|
||||||
|
context.reset_signal_cnt();
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* \brief Queue with first-in first-out semantics
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2012-11-30
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2014-2017 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 _CORE__KERNEL__FIFO_H_
|
|
||||||
#define _CORE__KERNEL__FIFO_H_
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <util/fifo.h>
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue with first-in first-out semantics
|
|
||||||
*
|
|
||||||
* \param T queue element type
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class Fifo : public Genode::Fifo<T>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call function 'f' of type 'void (QT *)' for each queue element
|
|
||||||
*/
|
|
||||||
template <typename F> void for_each(F f)
|
|
||||||
{
|
|
||||||
typedef Genode::Fifo<T> B;
|
|
||||||
for (T * e = B::head(); e; e = e->B::Element::next()) { f(e); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _CORE__KERNEL__FIFO_H_ */
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
* Copyright (C) 2012-2019 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.
|
||||||
|
@ -110,15 +110,14 @@ void Ipc_node::_announce_request(Ipc_node &node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cannot receive yet, so queue request */
|
/* cannot receive yet, so queue request */
|
||||||
_request_queue.enqueue(&node);
|
_request_queue.enqueue(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ipc_node::_cancel_request_queue()
|
void Ipc_node::_cancel_request_queue()
|
||||||
{
|
{
|
||||||
Ipc_node * node;
|
_request_queue.dequeue_all([] (Ipc_node &node) {
|
||||||
while ((node = _request_queue.dequeue()))
|
node._outbuf_request_cancelled(); });
|
||||||
node->_outbuf_request_cancelled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ void Ipc_node::_cancel_inbuf_request()
|
||||||
void Ipc_node::_announced_request_cancelled(Ipc_node &node)
|
void Ipc_node::_announced_request_cancelled(Ipc_node &node)
|
||||||
{
|
{
|
||||||
if (_caller == &node) _caller = nullptr;
|
if (_caller == &node) _caller = nullptr;
|
||||||
else _request_queue.remove(&node);
|
else _request_queue.remove(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,15 +210,16 @@ bool Ipc_node::await_request(unsigned rcv_caps)
|
||||||
|
|
||||||
_rcv_caps = rcv_caps;
|
_rcv_caps = rcv_caps;
|
||||||
|
|
||||||
/* if anybody already announced a request receive it */
|
/* if no request announced then wait */
|
||||||
if (!_request_queue.empty()) {
|
bool announced = false;
|
||||||
_receive_request(*_request_queue.dequeue());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no request announced, so wait */
|
|
||||||
_state = AWAIT_REQUEST;
|
_state = AWAIT_REQUEST;
|
||||||
return false;
|
|
||||||
|
/* if anybody already announced a request receive it */
|
||||||
|
_request_queue.dequeue([&] (Ipc_node &ipc) {
|
||||||
|
_receive_request(ipc);
|
||||||
|
announced = true;
|
||||||
|
});
|
||||||
|
return announced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
* Copyright (C) 2012-2019 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,7 +22,6 @@
|
||||||
#include <base/internal/native_utcb.h>
|
#include <base/internal/native_utcb.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/fifo.h>
|
|
||||||
#include <kernel/interface.h>
|
#include <kernel/interface.h>
|
||||||
#include <assertion.h>
|
#include <assertion.h>
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ namespace Kernel
|
||||||
*/
|
*/
|
||||||
class Ipc_node;
|
class Ipc_node;
|
||||||
|
|
||||||
using Ipc_node_queue = Kernel::Fifo<Ipc_node>;
|
using Ipc_node_queue = Genode::Fifo<Ipc_node>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Kernel::Ipc_node : private Ipc_node_queue::Element
|
class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||||
|
@ -56,7 +55,6 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class Core_thread;
|
friend class Core_thread;
|
||||||
friend class Kernel::Fifo<Ipc_node>;
|
|
||||||
friend class Genode::Fifo<Ipc_node>;
|
friend class Genode::Fifo<Ipc_node>;
|
||||||
|
|
||||||
State _state = INACTIVE;
|
State _state = INACTIVE;
|
||||||
|
@ -174,11 +172,11 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||||
template <typename F> void for_each_helper(F f)
|
template <typename F> void for_each_helper(F f)
|
||||||
{
|
{
|
||||||
/* if we have a helper in the receive buffer, call 'f' for it */
|
/* if we have a helper in the receive buffer, call 'f' for it */
|
||||||
if (_caller && _caller->_help) f(_caller);
|
if (_caller && _caller->_help) f(*_caller);
|
||||||
|
|
||||||
/* call 'f' for each helper in our request queue */
|
/* call 'f' for each helper in our request queue */
|
||||||
_request_queue.for_each([f] (Ipc_node * const node) {
|
_request_queue.for_each([f] (Ipc_node &node) {
|
||||||
if (node->_help) f(node); });
|
if (node._help) f(node); });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
* Copyright (C) 2012-2019 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.
|
||||||
|
@ -30,10 +30,6 @@ void Signal_handler::cancel_waiting()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Signal_handler::Signal_handler()
|
|
||||||
: _handlers_fe(this), _receiver(0) { }
|
|
||||||
|
|
||||||
|
|
||||||
Signal_handler::~Signal_handler() { cancel_waiting(); }
|
Signal_handler::~Signal_handler() { cancel_waiting(); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +43,7 @@ void Signal_context_killer::cancel_waiting()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Signal_context_killer::Signal_context_killer() : _context(0) { }
|
Signal_context_killer::Signal_context_killer() : _context(nullptr) { }
|
||||||
|
|
||||||
|
|
||||||
Signal_context_killer::~Signal_context_killer() { cancel_waiting(); }
|
Signal_context_killer::~Signal_context_killer() { cancel_waiting(); }
|
||||||
|
@ -128,14 +124,8 @@ Signal_context::~Signal_context()
|
||||||
|
|
||||||
Signal_context::Signal_context(Signal_receiver * const r, addr_t const imprint)
|
Signal_context::Signal_context(Signal_receiver * const r, addr_t const imprint)
|
||||||
:
|
:
|
||||||
_deliver_fe(this),
|
|
||||||
_contexts_fe(this),
|
|
||||||
_receiver(r),
|
_receiver(r),
|
||||||
_imprint(imprint),
|
_imprint(imprint)
|
||||||
_submits(0),
|
|
||||||
_ack(1),
|
|
||||||
_killed(0),
|
|
||||||
_killer(0)
|
|
||||||
{
|
{
|
||||||
r->_add_context(this);
|
r->_add_context(this);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +138,7 @@ Signal_context::Signal_context(Signal_receiver * const r, addr_t const imprint)
|
||||||
void Signal_receiver::_add_deliverable(Signal_context * const c)
|
void Signal_receiver::_add_deliverable(Signal_context * const c)
|
||||||
{
|
{
|
||||||
if (!c->_deliver_fe.enqueued()) {
|
if (!c->_deliver_fe.enqueued()) {
|
||||||
_deliver.enqueue(&c->_deliver_fe);
|
_deliver.enqueue(c->_deliver_fe);
|
||||||
}
|
}
|
||||||
_listen();
|
_listen();
|
||||||
}
|
}
|
||||||
|
@ -163,40 +153,46 @@ void Signal_receiver::_listen()
|
||||||
|
|
||||||
/* create a signal data-object */
|
/* create a signal data-object */
|
||||||
typedef Genode::Signal_context * Signal_imprint;
|
typedef Genode::Signal_context * Signal_imprint;
|
||||||
auto const context = _deliver.dequeue()->object();
|
|
||||||
Signal_imprint const imprint =
|
|
||||||
reinterpret_cast<Signal_imprint>(context->_imprint);
|
|
||||||
Signal::Data data(imprint, context->_submits);
|
|
||||||
|
|
||||||
/* communicate signal data to handler */
|
_deliver.dequeue([&] (Signal_context::Fifo_element &elem) {
|
||||||
auto const handler = _handlers.dequeue()->object();
|
auto const context = &elem.object();
|
||||||
handler->_receiver = 0;
|
|
||||||
handler->_receive_signal(&data, sizeof(data));
|
Signal_imprint const imprint =
|
||||||
context->_delivered();
|
reinterpret_cast<Signal_imprint>(context->_imprint);
|
||||||
|
Signal::Data data(imprint, context->_submits);
|
||||||
|
|
||||||
|
/* communicate signal data to handler */
|
||||||
|
_handlers.dequeue([&] (Signal_handler::Fifo_element &elem) {
|
||||||
|
auto const handler = &elem.object();
|
||||||
|
handler->_receiver = 0;
|
||||||
|
handler->_receive_signal(&data, sizeof(data));
|
||||||
|
});
|
||||||
|
context->_delivered();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Signal_receiver::_context_destructed(Signal_context * const c)
|
void Signal_receiver::_context_destructed(Signal_context * const c)
|
||||||
{
|
{
|
||||||
_contexts.remove(&c->_contexts_fe);
|
_contexts.remove(c->_contexts_fe);
|
||||||
if (!c->_deliver_fe.enqueued()) { return; }
|
if (!c->_deliver_fe.enqueued()) { return; }
|
||||||
_deliver.remove(&c->_deliver_fe);
|
_deliver.remove(c->_deliver_fe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Signal_receiver::_handler_cancelled(Signal_handler * const h) {
|
void Signal_receiver::_handler_cancelled(Signal_handler * const h) {
|
||||||
_handlers.remove(&h->_handlers_fe); }
|
_handlers.remove(h->_handlers_fe); }
|
||||||
|
|
||||||
|
|
||||||
void Signal_receiver::_add_context(Signal_context * const c) {
|
void Signal_receiver::_add_context(Signal_context * const c) {
|
||||||
_contexts.enqueue(&c->_contexts_fe); }
|
_contexts.enqueue(c->_contexts_fe); }
|
||||||
|
|
||||||
|
|
||||||
int Signal_receiver::add_handler(Signal_handler * const h)
|
int Signal_receiver::add_handler(Signal_handler * const h)
|
||||||
{
|
{
|
||||||
if (h->_receiver) { return -1; }
|
if (h->_receiver) { return -1; }
|
||||||
_handlers.enqueue(&h->_handlers_fe);
|
_handlers.enqueue(h->_handlers_fe);
|
||||||
h->_receiver = this;
|
h->_receiver = this;
|
||||||
h->_await_signal(this);
|
h->_await_signal(this);
|
||||||
_listen();
|
_listen();
|
||||||
|
@ -207,7 +203,6 @@ int Signal_receiver::add_handler(Signal_handler * const h)
|
||||||
Signal_receiver::~Signal_receiver()
|
Signal_receiver::~Signal_receiver()
|
||||||
{
|
{
|
||||||
/* destruct all attached contexts */
|
/* destruct all attached contexts */
|
||||||
while (Signal_context * c = _contexts.dequeue()->object()) {
|
_contexts.dequeue_all([] (Signal_context::Fifo_element &elem) {
|
||||||
c->~Signal_context();
|
elem.object().~Signal_context(); });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ class Kernel::Signal_handler
|
||||||
|
|
||||||
typedef Genode::Fifo_element<Signal_handler> Fifo_element;
|
typedef Genode::Fifo_element<Signal_handler> Fifo_element;
|
||||||
|
|
||||||
Fifo_element _handlers_fe;
|
Fifo_element _handlers_fe { *this };
|
||||||
Signal_receiver * _receiver;
|
Signal_receiver * _receiver { nullptr };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Let the handler block for signal receipt
|
* Let the handler block for signal receipt
|
||||||
|
@ -86,7 +86,7 @@ class Kernel::Signal_handler
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Signal_handler();
|
Signal_handler() { }
|
||||||
virtual ~Signal_handler();
|
virtual ~Signal_handler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,14 +158,14 @@ class Kernel::Signal_context : public Kernel::Object
|
||||||
|
|
||||||
typedef Genode::Fifo_element<Signal_context> Fifo_element;
|
typedef Genode::Fifo_element<Signal_context> Fifo_element;
|
||||||
|
|
||||||
Fifo_element _deliver_fe;
|
Fifo_element _deliver_fe { *this };
|
||||||
Fifo_element _contexts_fe;
|
Fifo_element _contexts_fe { *this };
|
||||||
Signal_receiver * const _receiver;
|
Signal_receiver * const _receiver;
|
||||||
addr_t const _imprint;
|
addr_t const _imprint;
|
||||||
unsigned _submits;
|
Signal_context_killer * _killer { nullptr };
|
||||||
bool _ack;
|
unsigned _submits { 0 };
|
||||||
bool _killed;
|
bool _ack { true };
|
||||||
Signal_context_killer * _killer;
|
bool _killed { false };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell receiver about the submits of the context if any
|
* Tell receiver about the submits of the context if any
|
||||||
|
|
|
@ -151,15 +151,15 @@ void Thread::_await_request_failed()
|
||||||
void Thread::_deactivate_used_shares()
|
void Thread::_deactivate_used_shares()
|
||||||
{
|
{
|
||||||
Cpu_job::_deactivate_own_share();
|
Cpu_job::_deactivate_own_share();
|
||||||
Ipc_node::for_each_helper([&] (Ipc_node * const h) {
|
Ipc_node::for_each_helper([&] (Ipc_node &h) {
|
||||||
static_cast<Thread *>(h)->_deactivate_used_shares(); });
|
static_cast<Thread &>(h)._deactivate_used_shares(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::_activate_used_shares()
|
void Thread::_activate_used_shares()
|
||||||
{
|
{
|
||||||
Cpu_job::_activate_own_share();
|
Cpu_job::_activate_own_share();
|
||||||
Ipc_node::for_each_helper([&] (Ipc_node * const h) {
|
Ipc_node::for_each_helper([&] (Ipc_node &h) {
|
||||||
static_cast<Thread *>(h)->_activate_used_shares(); });
|
static_cast<Thread &>(h)._activate_used_shares(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::_become_active()
|
void Thread::_become_active()
|
||||||
|
|
|
@ -32,7 +32,7 @@ using namespace Genode;
|
||||||
void Signal_source_component::release(Signal_context_component &context)
|
void Signal_source_component::release(Signal_context_component &context)
|
||||||
{
|
{
|
||||||
if (context.enqueued())
|
if (context.enqueued())
|
||||||
_signal_queue.remove(&context);
|
_signal_queue.remove(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ void Signal_source_component::submit(Signal_context_component &context,
|
||||||
if (context.enqueued())
|
if (context.enqueued())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_signal_queue.enqueue(&context);
|
_signal_queue.enqueue(context);
|
||||||
|
|
||||||
seL4_Signal(Capability_space::ipc_cap_data(_notify).sel.value());
|
seL4_Signal(Capability_space::ipc_cap_data(_notify).sel.value());
|
||||||
}
|
}
|
||||||
|
@ -57,13 +57,13 @@ void Signal_source_component::submit(Signal_context_component &context,
|
||||||
|
|
||||||
Signal_source::Signal Signal_source_component::wait_for_signal()
|
Signal_source::Signal Signal_source_component::wait_for_signal()
|
||||||
{
|
{
|
||||||
if (_signal_queue.empty())
|
Signal result(0, 0); /* just a dummy in the case of no signal pending */
|
||||||
return Signal(0, 0); /* just a dummy */
|
|
||||||
|
|
||||||
/* dequeue and return pending signal */
|
/* dequeue and return pending signal */
|
||||||
Signal_context_component &context = *_signal_queue.dequeue();
|
_signal_queue.dequeue([&result] (Signal_context_component &context) {
|
||||||
Signal result(context.imprint(), context.cnt());
|
result = Signal(context.imprint(), context.cnt());
|
||||||
context.reset_signal_cnt();
|
context.reset_signal_cnt();
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
* Copyright (C) 2006-2019 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.
|
||||||
|
@ -73,7 +73,8 @@ class Genode::Semaphore
|
||||||
* Remove element from queue and wake up the corresponding
|
* Remove element from queue and wake up the corresponding
|
||||||
* blocking thread
|
* blocking thread
|
||||||
*/
|
*/
|
||||||
element = _queue.dequeue();
|
_queue.dequeue([&element] (Element &head) {
|
||||||
|
element = &head; });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do not hold the lock while unblocking a waiting thread */
|
/* do not hold the lock while unblocking a waiting thread */
|
||||||
|
@ -94,7 +95,7 @@ class Genode::Semaphore
|
||||||
* in the wait queue.
|
* in the wait queue.
|
||||||
*/
|
*/
|
||||||
Element queue_element;
|
Element queue_element;
|
||||||
_queue.enqueue(&queue_element);
|
_queue.enqueue(queue_element);
|
||||||
_meta_lock.unlock();
|
_meta_lock.unlock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2008-2017 Genode Labs GmbH
|
* Copyright (C) 2008-2019 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.
|
||||||
|
@ -37,71 +37,69 @@ class Genode::Fifo
|
||||||
|
|
||||||
friend class Fifo;
|
friend class Fifo;
|
||||||
|
|
||||||
QT *_next;
|
QT *_next { nullptr };
|
||||||
bool _enqueued;
|
bool _enqueued { false };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Element(): _next(0), _enqueued(false) { }
|
Element() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true is fifo element is enqueued in a fifo
|
* Return true is fifo element is enqueued in a fifo
|
||||||
*/
|
*/
|
||||||
bool enqueued() { return _enqueued; }
|
bool enqueued() { return _enqueued; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true is fifo element is enqueued in a fifo
|
|
||||||
*
|
|
||||||
* \noapi
|
|
||||||
* \deprecated use 'enqueued' instead
|
|
||||||
*/
|
|
||||||
bool is_enqueued() { return enqueued(); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return next element in queue
|
* Return next element in queue
|
||||||
|
*
|
||||||
|
* \deprecated use 'Fifo::for_each' instead
|
||||||
*/
|
*/
|
||||||
QT *next() const { return _next; }
|
QT *next() const { return _next; }
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QT *_head; /* oldest element */
|
QT *_head { nullptr }; /* oldest element */
|
||||||
Element *_tail; /* newest element */
|
Element *_tail { nullptr }; /* newest element */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if queue is empty
|
* Return true if queue is empty
|
||||||
*/
|
*/
|
||||||
bool empty() { return _tail == 0; }
|
bool empty() { return _tail == nullptr; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Fifo(): _head(0), _tail(0) { }
|
Fifo() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return first queue element
|
* If queue is not empty then call
|
||||||
|
* lambda 'func' of type 'void (QT&)'
|
||||||
|
* with the head element
|
||||||
*/
|
*/
|
||||||
QT *head() const { return _head; }
|
template <typename FUNC>
|
||||||
|
void head(FUNC const &func) const {
|
||||||
|
if (_head) func(*_head); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove element explicitely from queue
|
* Remove element explicitely from queue
|
||||||
*/
|
*/
|
||||||
void remove(QT *qe)
|
void remove(QT &qe)
|
||||||
{
|
{
|
||||||
if (empty()) return;
|
if (empty()) return;
|
||||||
|
|
||||||
/* if specified element is the first of the queue */
|
/* if specified element is the first of the queue */
|
||||||
if (qe == _head) {
|
if (&qe == _head) {
|
||||||
_head = qe->Fifo::Element::_next;
|
_head = qe.Fifo::Element::_next;
|
||||||
if (!_head) _tail = 0;
|
if (!_head) _tail = nullptr;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
/* search specified element in the queue */
|
/* search specified element in the queue */
|
||||||
Element *e = _head;
|
Element *e = _head;
|
||||||
while (e->_next && (e->_next != qe))
|
while (e->_next && (e->_next != &qe))
|
||||||
e = e->_next;
|
e = e->_next;
|
||||||
|
|
||||||
/* element is not member of the queue */
|
/* element is not member of the queue */
|
||||||
|
@ -112,50 +110,78 @@ class Genode::Fifo
|
||||||
if (!e->Element::_next) _tail = e;
|
if (!e->Element::_next) _tail = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
qe->Fifo::Element::_next = 0;
|
qe.Fifo::Element::_next = nullptr;
|
||||||
qe->Fifo::Element::_enqueued = 0;
|
qe.Fifo::Element::_enqueued = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach element at the end of the queue
|
* Attach element at the end of the queue
|
||||||
*/
|
*/
|
||||||
void enqueue(QT *e)
|
void enqueue(QT &e)
|
||||||
{
|
{
|
||||||
e->Fifo::Element::_next = 0;
|
e.Fifo::Element::_next = nullptr;
|
||||||
e->Fifo::Element::_enqueued = true;
|
e.Fifo::Element::_enqueued = true;
|
||||||
|
|
||||||
if (empty()) {
|
if (empty()) {
|
||||||
_tail = _head = e;
|
_tail = _head = &e;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_tail->Fifo::Element::_next = e;
|
_tail->Fifo::Element::_next = &e;
|
||||||
_tail = e;
|
_tail = &e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call lambda 'func' of type 'void (QT&)'
|
||||||
|
* for each queue element in order
|
||||||
|
*/
|
||||||
|
template <typename FUNC>
|
||||||
|
void for_each(FUNC const &func) const
|
||||||
|
{
|
||||||
|
QT *elem = _head;
|
||||||
|
while (elem != nullptr) {
|
||||||
|
/* take the next pointer so 'func' cannot modify it */
|
||||||
|
QT *next = elem->Fifo::Element::_next;;
|
||||||
|
func(*elem);
|
||||||
|
elem = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove head element from queue
|
* If queue is not empty then remove head and
|
||||||
*
|
* call lambda 'func' of type 'void (QT&)'
|
||||||
* \return head element or 0 if queue is empty
|
|
||||||
*/
|
*/
|
||||||
QT *dequeue()
|
template <typename FUNC>
|
||||||
|
void dequeue(FUNC const &func)
|
||||||
{
|
{
|
||||||
QT *result = _head;
|
QT *result = _head;
|
||||||
|
|
||||||
/* check if queue has only one last element */
|
/* check if queue has only one last element */
|
||||||
if (_head == _tail) {
|
if (_head == _tail) {
|
||||||
_head = 0;
|
_head = nullptr;
|
||||||
_tail = 0;
|
_tail = nullptr;
|
||||||
} else
|
} else
|
||||||
_head = _head->Fifo::Element::_next;
|
_head = _head->Fifo::Element::_next;
|
||||||
|
|
||||||
/* mark fifo queue element as free */
|
/* mark fifo queue element as free */
|
||||||
if (result) {
|
if (result) {
|
||||||
result->Fifo::Element::_next = 0;
|
result->Fifo::Element::_next = nullptr;
|
||||||
result->Fifo::Element::_enqueued = false;
|
result->Fifo::Element::_enqueued = false;
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
/* pass to caller */
|
||||||
|
func(*result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If queue is not empty then remove elements in order and
|
||||||
|
* call lambda 'func' of type 'void (QT&)'
|
||||||
|
*/
|
||||||
|
template <typename FUNC>
|
||||||
|
void dequeue_all(FUNC const &func)
|
||||||
|
{
|
||||||
|
while (_head != nullptr) dequeue(func);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,26 +200,13 @@ class Genode::Fifo
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Genode::Fifo_element : public Fifo<Fifo_element<T> >::Element
|
class Genode::Fifo_element : public Fifo<Fifo_element<T> >::Element
|
||||||
{
|
{
|
||||||
T *_object;
|
T &_object;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Fifo_element(T *object) : _object(object) { }
|
Fifo_element(T &object) : _object(object) { }
|
||||||
|
|
||||||
/**
|
inline T &object() { return _object; }
|
||||||
* Get typed object pointer
|
|
||||||
*
|
|
||||||
* Zero-pointer save: Returns 0 if this pointer is 0 to
|
|
||||||
* cover the case of accessing an empty FIFO.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* prevent the compiler from optimizing out the 'this' pointer check */
|
|
||||||
__attribute__((optimize("-fno-delete-null-pointer-checks")))
|
|
||||||
inline T *object()
|
|
||||||
{
|
|
||||||
if (this) { return _object; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__UTIL__FIFO_H_ */
|
#endif /* _INCLUDE__UTIL__FIFO_H_ */
|
||||||
|
|
|
@ -131,8 +131,6 @@ class Genode::Rm_faulter : Fifo<Rm_faulter>::Element, Interface
|
||||||
*/
|
*/
|
||||||
explicit Rm_faulter(Pager_object &pager_object) : _pager_object(pager_object) { }
|
explicit Rm_faulter(Pager_object &pager_object) : _pager_object(pager_object) { }
|
||||||
|
|
||||||
using Fifo<Rm_faulter>::Element::next;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign fault state
|
* Assign fault state
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
* Copyright (C) 2006-2019 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.
|
||||||
|
@ -451,18 +451,12 @@ Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||||
dsc->attached_to(region);
|
dsc->attached_to(region);
|
||||||
|
|
||||||
/* check if attach operation resolves any faulting region-manager clients */
|
/* check if attach operation resolves any faulting region-manager clients */
|
||||||
for (Rm_faulter *faulter = _faulters.head(); faulter; ) {
|
_faulters.for_each([&] (Rm_faulter &faulter) {
|
||||||
|
if (faulter.fault_in_addr_range((addr_t)attach_at, size)) {
|
||||||
/* remember next pointer before possibly removing current list element */
|
|
||||||
Rm_faulter *next = faulter->next();
|
|
||||||
|
|
||||||
if (faulter->fault_in_addr_range((addr_t)attach_at, size)) {
|
|
||||||
_faulters.remove(faulter);
|
_faulters.remove(faulter);
|
||||||
faulter->continue_after_resolved_fault();
|
faulter.continue_after_resolved_fault();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
faulter = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return attach_at;
|
return attach_at;
|
||||||
};
|
};
|
||||||
|
@ -606,7 +600,7 @@ void Region_map_component::fault(Rm_faulter &faulter, addr_t pf_addr,
|
||||||
faulter.fault(*this, Region_map::State(pf_type, pf_addr));
|
faulter.fault(*this, Region_map::State(pf_type, pf_addr));
|
||||||
|
|
||||||
/* enqueue faulter */
|
/* enqueue faulter */
|
||||||
_faulters.enqueue(&faulter);
|
_faulters.enqueue(faulter);
|
||||||
|
|
||||||
/* issue fault signal */
|
/* issue fault signal */
|
||||||
_fault_notifier.submit();
|
_fault_notifier.submit();
|
||||||
|
@ -617,9 +611,9 @@ void Region_map_component::discard_faulter(Rm_faulter &faulter, bool do_lock)
|
||||||
{
|
{
|
||||||
if (do_lock) {
|
if (do_lock) {
|
||||||
Lock::Guard lock_guard(_lock);
|
Lock::Guard lock_guard(_lock);
|
||||||
_faulters.remove(&faulter);
|
_faulters.remove(faulter);
|
||||||
} else
|
} else
|
||||||
_faulters.remove(&faulter);
|
_faulters.remove(faulter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -634,15 +628,13 @@ Region_map::State Region_map_component::state()
|
||||||
/* serialize access */
|
/* serialize access */
|
||||||
Lock::Guard lock_guard(_lock);
|
Lock::Guard lock_guard(_lock);
|
||||||
|
|
||||||
/* pick one of the currently faulted threads */
|
|
||||||
Rm_faulter *faulter_ptr = _faulters.head();
|
|
||||||
|
|
||||||
/* return ready state if there are not current faulters */
|
/* return ready state if there are not current faulters */
|
||||||
if (!faulter_ptr)
|
Region_map::State result;
|
||||||
return Region_map::State();
|
|
||||||
|
|
||||||
/* return fault information regarding the first faulter of the list */
|
/* otherwise return fault information regarding the first faulter */
|
||||||
return faulter_ptr->fault_state();
|
_faulters.head([&] (Rm_faulter &faulter) {
|
||||||
|
result = faulter.fault_state(); });
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ using namespace Genode;
|
||||||
void Signal_source_component::release(Signal_context_component &context)
|
void Signal_source_component::release(Signal_context_component &context)
|
||||||
{
|
{
|
||||||
if (context.enqueued())
|
if (context.enqueued())
|
||||||
_signal_queue.remove(&context);
|
_signal_queue.remove(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ void Signal_source_component::submit(Signal_context_component &context,
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!context.enqueued())
|
if (!context.enqueued())
|
||||||
_signal_queue.enqueue(&context);
|
_signal_queue.enqueue(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,10 +78,13 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
|
||||||
return Signal(0, 0); /* just a dummy */
|
return Signal(0, 0); /* just a dummy */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* dequeue and return pending signal */
|
/* dequeue and return pending signal */
|
||||||
Signal_context_component &context = *_signal_queue.dequeue();
|
Signal result { };
|
||||||
Signal result(context.imprint(), context.cnt());
|
_signal_queue.dequeue([&result] (Signal_context_component &context) {
|
||||||
context.reset_signal_cnt();
|
result = Signal(context.imprint(), context.cnt());
|
||||||
|
context.reset_signal_cnt();
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,8 @@ extern "C" void brk(Linker::Debug *, Linker::Link_map *) { }
|
||||||
|
|
||||||
void Linker::dump_link_map(Object const &obj)
|
void Linker::dump_link_map(Object const &obj)
|
||||||
{
|
{
|
||||||
for (Object const *o = &obj; o; o = o->next_obj()) {
|
if (!obj.is_binary())
|
||||||
|
log(" ", Hex(obj.link_map().addr),
|
||||||
if (o->is_binary())
|
" .. ", Hex(obj.link_map().addr + obj.size() - 1),
|
||||||
continue;
|
": ", obj.name());
|
||||||
|
|
||||||
log(" ", Hex(o->link_map().addr),
|
|
||||||
" .. ", Hex(o->link_map().addr + o->size() - 1),
|
|
||||||
": ", o->name());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
* Copyright (C) 2015-2019 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.
|
||||||
|
@ -28,7 +28,7 @@ Linker::Dependency::Dependency(Env &env, Allocator &md_alloc,
|
||||||
_root(root),
|
_root(root),
|
||||||
_md_alloc(&md_alloc)
|
_md_alloc(&md_alloc)
|
||||||
{
|
{
|
||||||
deps.enqueue(this);
|
deps.enqueue(*this);
|
||||||
load_needed(env, *_md_alloc, deps, keep);
|
load_needed(env, *_md_alloc, deps, keep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +47,14 @@ Linker::Dependency::~Dependency()
|
||||||
|
|
||||||
bool Linker::Dependency::in_dep(char const *file, Fifo<Dependency> const &dep)
|
bool Linker::Dependency::in_dep(char const *file, Fifo<Dependency> const &dep)
|
||||||
{
|
{
|
||||||
for (Dependency const *d = dep.head(); d; d = d->next())
|
bool result = false;
|
||||||
if (!strcmp(file, d->obj().name()))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
dep.for_each([&] (Dependency const &d) {
|
||||||
|
if (!result && !strcmp(file, d.obj().name()))
|
||||||
|
result = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,9 +98,8 @@ Linker::Root_object::Root_object(Env &env, Allocator &md_alloc,
|
||||||
Init::list()->initialize(bind, STAGE_SO);
|
Init::list()->initialize(bind, STAGE_SO);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Init::list()->flush();
|
Init::list()->flush();
|
||||||
while (Dependency *d = _deps.dequeue())
|
_deps.dequeue_all([&] (Dependency &d) {
|
||||||
destroy(_md_alloc, d);
|
destroy(_md_alloc, &d); });
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
* Copyright (C) 2015-2019 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.
|
||||||
|
@ -135,7 +135,7 @@ class Linker::Dynamic
|
||||||
throw Fatal();
|
throw Fatal();
|
||||||
}
|
}
|
||||||
Needed *n = new (*_md_alloc) Needed(d->un.ptr);
|
Needed *n = new (*_md_alloc) Needed(d->un.ptr);
|
||||||
_needed.enqueue(n);
|
_needed.enqueue(*n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -199,8 +199,8 @@ class Linker::Dynamic
|
||||||
if (!_md_alloc)
|
if (!_md_alloc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (Needed *n = _needed.dequeue())
|
_needed.dequeue_all([&] (Needed &n) {
|
||||||
destroy(*_md_alloc, n);
|
destroy(*_md_alloc, &n); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void call_init_function() const
|
void call_init_function() const
|
||||||
|
@ -310,8 +310,8 @@ class Linker::Dynamic
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
void for_each_dependency(FUNC const &fn) const
|
void for_each_dependency(FUNC const &fn) const
|
||||||
{
|
{
|
||||||
for (Needed *n = _needed.head(); n; n = n->next())
|
_needed.for_each([&] (Needed &n) {
|
||||||
fn(n->path(_strtab));
|
fn(n.path(_strtab)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void relocate(Bind bind) SELF_RELOC
|
void relocate(Bind bind) SELF_RELOC
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
* Copyright (C) 2014-2019 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.
|
||||||
|
@ -273,18 +273,27 @@ class Linker::Root_object
|
||||||
|
|
||||||
~Root_object()
|
~Root_object()
|
||||||
{
|
{
|
||||||
while (Dependency *d = _deps.dequeue())
|
_deps.dequeue_all([&] (Dependency &d) {
|
||||||
destroy(_md_alloc, d);
|
destroy(_md_alloc, &d); });
|
||||||
}
|
}
|
||||||
|
|
||||||
Link_map const &link_map() const
|
Link_map const &link_map() const
|
||||||
{
|
{
|
||||||
return _deps.head()->obj().link_map();
|
Link_map const *map = nullptr;
|
||||||
|
_deps.head([&] (Dependency &d) {
|
||||||
|
map = &d.obj().link_map(); });
|
||||||
|
return *map;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dependency const *first_dep() const { return _deps.head(); }
|
Dependency const *first_dep() const
|
||||||
|
{
|
||||||
|
Dependency const *dep = nullptr;
|
||||||
|
_deps.head([&] (Dependency const &head) {
|
||||||
|
dep = &head; });
|
||||||
|
return dep;
|
||||||
|
}
|
||||||
|
|
||||||
void enqueue(Dependency &dep) { _deps.enqueue(&dep); }
|
void enqueue(Dependency &dep) { _deps.enqueue(dep); }
|
||||||
|
|
||||||
Fifo<Dependency> &deps() { return _deps; }
|
Fifo<Dependency> &deps() { return _deps; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
* Copyright (C) 2014-2019 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.
|
||||||
|
@ -129,7 +129,7 @@ class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
|
||||||
{
|
{
|
||||||
/* register for static construction and relocation */
|
/* register for static construction and relocation */
|
||||||
Init::list()->insert(this);
|
Init::list()->insert(this);
|
||||||
obj_list()->enqueue(this);
|
obj_list()->enqueue(*this);
|
||||||
|
|
||||||
/* add to link map */
|
/* add to link map */
|
||||||
Debug::state_change(Debug::ADD, nullptr);
|
Debug::state_change(Debug::ADD, nullptr);
|
||||||
|
@ -151,7 +151,7 @@ class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
|
||||||
Debug::state_change(Debug::CONSISTENT, nullptr);
|
Debug::state_change(Debug::CONSISTENT, nullptr);
|
||||||
|
|
||||||
/* remove from loaded objects list */
|
/* remove from loaded objects list */
|
||||||
obj_list()->remove(this);
|
obj_list()->remove(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,7 +314,7 @@ Linker::Ld &Linker::Ld::linker()
|
||||||
{
|
{
|
||||||
Ld_vtable()
|
Ld_vtable()
|
||||||
{
|
{
|
||||||
Elf_object::obj_list()->enqueue(this);
|
Elf_object::obj_list()->enqueue(*this);
|
||||||
plt_setup();
|
plt_setup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -502,24 +502,30 @@ bool Linker::Object::needs_static_construction()
|
||||||
Object &Linker::load(Env &env, Allocator &md_alloc, char const *path,
|
Object &Linker::load(Env &env, Allocator &md_alloc, char const *path,
|
||||||
Dependency &dep, Keep keep)
|
Dependency &dep, Keep keep)
|
||||||
{
|
{
|
||||||
for (Object *e = Elf_object::obj_list()->head(); e; e = e->next_obj()) {
|
Object *result = nullptr;
|
||||||
|
Elf_object::obj_list()->for_each([&] (Object &e) {
|
||||||
|
if (result == nullptr) {
|
||||||
|
if (verbose_loading)
|
||||||
|
log("LOAD: ", Linker::file(path), " == ", e.name());
|
||||||
|
|
||||||
if (verbose_loading)
|
if (!strcmp(Linker::file(path), e.name())) {
|
||||||
log("LOAD: ", Linker::file(path), " == ", e->name());
|
e.load();
|
||||||
|
result = &e;
|
||||||
if (!strcmp(Linker::file(path), e->name())) {
|
}
|
||||||
e->load();
|
|
||||||
return *e;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
if (result == nullptr)
|
||||||
return *new (md_alloc) Elf_object(env, md_alloc, path, dep, keep);
|
result = new (md_alloc) Elf_object(env, md_alloc, path, dep, keep);
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Object *Linker::obj_list_head()
|
Object *Linker::obj_list_head()
|
||||||
{
|
{
|
||||||
return Elf_object::obj_list()->head();
|
Object *result = nullptr;
|
||||||
|
Elf_object::obj_list()->head([&result] (Object &obj) {
|
||||||
|
result = &obj; });
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -704,7 +710,8 @@ void Component::construct(Genode::Env &env)
|
||||||
" .. ", Hex(Thread::stack_area_virtual_base() +
|
" .. ", Hex(Thread::stack_area_virtual_base() +
|
||||||
Thread::stack_area_virtual_size() - 1),
|
Thread::stack_area_virtual_size() - 1),
|
||||||
": stack area");
|
": stack area");
|
||||||
dump_link_map(*Elf_object::obj_list()->head());
|
Elf_object::obj_list()->for_each([] (Object const &obj) {
|
||||||
|
dump_link_map(obj); });
|
||||||
}
|
}
|
||||||
} catch (...) { }
|
} catch (...) { }
|
||||||
|
|
||||||
|
|
|
@ -108,10 +108,12 @@ class Timed_semaphore : public Semaphore
|
||||||
* Iterate through the queue and find the thread,
|
* Iterate through the queue and find the thread,
|
||||||
* with the corresponding timeout.
|
* with the corresponding timeout.
|
||||||
*/
|
*/
|
||||||
Element *first = Semaphore::_queue.dequeue();
|
Element *first = nullptr;
|
||||||
|
Semaphore::_queue.dequeue([&first] (Element &e) {
|
||||||
|
first = &e; });
|
||||||
Element *e = first;
|
Element *e = first;
|
||||||
|
|
||||||
while (true) {
|
while (e) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wakeup the thread.
|
* Wakeup the thread.
|
||||||
|
@ -124,8 +126,10 @@ class Timed_semaphore : public Semaphore
|
||||||
/*
|
/*
|
||||||
* Noninvolved threads are enqueued again.
|
* Noninvolved threads are enqueued again.
|
||||||
*/
|
*/
|
||||||
Semaphore::_queue.enqueue(e);
|
Semaphore::_queue.enqueue(*e);
|
||||||
e = Semaphore::_queue.dequeue();
|
e = nullptr;
|
||||||
|
Semaphore::_queue.dequeue([&e] (Element &next) {
|
||||||
|
e = &next; });
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maybe, the alarm was triggered just after the corresponding
|
* Maybe, the alarm was triggered just after the corresponding
|
||||||
|
@ -210,7 +214,7 @@ class Timed_semaphore : public Semaphore
|
||||||
* in the wait queue.
|
* in the wait queue.
|
||||||
*/
|
*/
|
||||||
Element queue_element;
|
Element queue_element;
|
||||||
Semaphore::_queue.enqueue(&queue_element);
|
Semaphore::_queue.enqueue(queue_element);
|
||||||
Semaphore::_meta_lock.unlock();
|
Semaphore::_meta_lock.unlock();
|
||||||
|
|
||||||
/* Create the timeout */
|
/* Create the timeout */
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct rumpuser_mtx
|
||||||
if (try_enter)
|
if (try_enter)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fifo.enqueue(&applicant);
|
fifo.enqueue(applicant);
|
||||||
}
|
}
|
||||||
applicant.block();
|
applicant.block();
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,8 @@ struct rumpuser_mtx
|
||||||
owner = nullptr;
|
owner = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Applicant *applicant = fifo.dequeue())
|
fifo.dequeue([] (Applicant &applicant) {
|
||||||
applicant->wake_up();
|
applicant.wake_up(); });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -109,10 +109,13 @@ class Libc::Timed_semaphore : public Semaphore
|
||||||
* Iterate through the queue and find the thread,
|
* Iterate through the queue and find the thread,
|
||||||
* with the corresponding timeout.
|
* with the corresponding timeout.
|
||||||
*/
|
*/
|
||||||
Element *first = Semaphore::_queue.dequeue();
|
|
||||||
|
Element *first = nullptr;
|
||||||
|
Semaphore::_queue.dequeue([&first] (Element &e) {
|
||||||
|
first = &e; });
|
||||||
Element *e = first;
|
Element *e = first;
|
||||||
|
|
||||||
while (true) {
|
while (e) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wakeup the thread.
|
* Wakeup the thread.
|
||||||
|
@ -125,8 +128,10 @@ class Libc::Timed_semaphore : public Semaphore
|
||||||
/*
|
/*
|
||||||
* Noninvolved threads are enqueued again.
|
* Noninvolved threads are enqueued again.
|
||||||
*/
|
*/
|
||||||
Semaphore::_queue.enqueue(e);
|
Semaphore::_queue.enqueue(*e);
|
||||||
e = Semaphore::_queue.dequeue();
|
e = nullptr;
|
||||||
|
Semaphore::_queue.dequeue([&e] (Element &next) {
|
||||||
|
e = &next; });
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maybe, the alarm was triggered just after the corresponding
|
* Maybe, the alarm was triggered just after the corresponding
|
||||||
|
@ -211,7 +216,7 @@ class Libc::Timed_semaphore : public Semaphore
|
||||||
* in the wait queue.
|
* in the wait queue.
|
||||||
*/
|
*/
|
||||||
Element queue_element;
|
Element queue_element;
|
||||||
Semaphore::_queue.enqueue(&queue_element);
|
Semaphore::_queue.enqueue(queue_element);
|
||||||
Semaphore::_meta_lock.unlock();
|
Semaphore::_meta_lock.unlock();
|
||||||
|
|
||||||
/* Create the timeout */
|
/* Create the timeout */
|
||||||
|
|
|
@ -64,7 +64,7 @@ class Isoc_packet : Fifo<Isoc_packet>::Element
|
||||||
{
|
{
|
||||||
if (!valid()) return false;
|
if (!valid()) return false;
|
||||||
|
|
||||||
int remaining = _size - _offset;
|
unsigned remaining = _size - _offset;
|
||||||
int copy_size = min(usb_packet->iov.size, remaining);
|
int copy_size = min(usb_packet->iov.size, remaining);
|
||||||
|
|
||||||
usb_packet_copy(usb_packet, _content + _offset, copy_size);
|
usb_packet_copy(usb_packet, _content + _offset, copy_size);
|
||||||
|
@ -202,19 +202,22 @@ struct Dev_info
|
||||||
|
|
||||||
struct Usb_host_device : List<Usb_host_device>::Element
|
struct Usb_host_device : List<Usb_host_device>::Element
|
||||||
{
|
{
|
||||||
|
Usb_host_device(const Usb_host_device&);
|
||||||
|
const Usb_host_device& operator=(const Usb_host_device&);
|
||||||
|
|
||||||
struct Could_not_create_device : Exception { };
|
struct Could_not_create_device : Exception { };
|
||||||
|
|
||||||
bool deleted = false;
|
bool deleted = false;
|
||||||
char const *label = nullptr;
|
char const *label = nullptr;
|
||||||
Dev_info const info;
|
Dev_info const info;
|
||||||
|
|
||||||
USBHostDevice *qemu_dev;
|
USBHostDevice *qemu_dev { nullptr };
|
||||||
|
|
||||||
/* submit queue + ack queue + 1 -> max nr of packets in flight */
|
/* submit queue + ack queue + 1 -> max nr of packets in flight */
|
||||||
enum { NUM_COMPLETIONS = Usb::Session::TX_QUEUE_SIZE * 2 + 1 };
|
enum { NUM_COMPLETIONS = Usb::Session::TX_QUEUE_SIZE * 2 + 1 };
|
||||||
Completion completion[NUM_COMPLETIONS];
|
Completion completion[NUM_COMPLETIONS];
|
||||||
|
|
||||||
Fifo<Isoc_packet> isoc_read_queue;
|
Fifo<Isoc_packet> isoc_read_queue { };
|
||||||
Reconstructible<Isoc_packet> isoc_write_packet { Usb::Packet_descriptor(), nullptr };
|
Reconstructible<Isoc_packet> isoc_write_packet { Usb::Packet_descriptor(), nullptr };
|
||||||
|
|
||||||
Signal_receiver &sig_rec;
|
Signal_receiver &sig_rec;
|
||||||
|
@ -323,7 +326,9 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
||||||
/* isochronous in */
|
/* isochronous in */
|
||||||
free_completion(packet);
|
free_completion(packet);
|
||||||
_isoc_in_pending--;
|
_isoc_in_pending--;
|
||||||
isoc_read_queue.enqueue(new (_alloc) Isoc_packet(packet, content));
|
Isoc_packet *new_packet = new (_alloc)
|
||||||
|
Isoc_packet(packet, content);
|
||||||
|
isoc_read_queue.enqueue(*new_packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,9 +344,12 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isoc_read_queue.head()->copy(packet)) {
|
isoc_read_queue.head([&] (Isoc_packet &head) {
|
||||||
free_packet(isoc_read_queue.dequeue());
|
if (head.copy(packet)) {
|
||||||
}
|
isoc_read_queue.remove(head);
|
||||||
|
free_packet(&head);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -351,9 +359,7 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
||||||
bool isoc_new_packet()
|
bool isoc_new_packet()
|
||||||
{
|
{
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for (Isoc_packet *packet = isoc_read_queue.head(); packet;
|
isoc_read_queue.for_each([&count] (Isoc_packet&) { count++; });
|
||||||
packet = packet->next(), count++);
|
|
||||||
|
|
||||||
return (count + _isoc_in_pending) < 3 ? true : false;
|
return (count + _isoc_in_pending) < 3 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,18 +400,14 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
||||||
void isoc_in_flush(unsigned ep, bool all = false)
|
void isoc_in_flush(unsigned ep, bool all = false)
|
||||||
{
|
{
|
||||||
/* flush finished and stored data */
|
/* flush finished and stored data */
|
||||||
for (Isoc_packet *packet = isoc_read_queue.head(); packet; )
|
isoc_read_queue.for_each([&] (Isoc_packet &packet) {
|
||||||
{
|
if (!all && (!packet.valid() || packet.packet().transfer.ep != ep)) {
|
||||||
if (!all && (!packet->valid() || packet->packet().transfer.ep != ep)) {
|
return;
|
||||||
packet = packet->next();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Isoc_packet *next = packet->next();
|
|
||||||
isoc_read_queue.remove(packet);
|
isoc_read_queue.remove(packet);
|
||||||
free_packet(packet);
|
free_packet(&packet);
|
||||||
packet = next;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/* flush in flight packets */
|
/* flush in flight packets */
|
||||||
flush_completion(ep);
|
flush_completion(ep);
|
||||||
|
|
|
@ -702,7 +702,7 @@ class Lwip::Udp_socket_dir final :
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16_t peek(void *dst, size_t count)
|
u16_t peek(void *dst, size_t count) const
|
||||||
{
|
{
|
||||||
count = min((size_t)buf->tot_len, count);
|
count = min((size_t)buf->tot_len, count);
|
||||||
return pbuf_copy_partial(buf, dst, count, offset);
|
return pbuf_copy_partial(buf, dst, count, offset);
|
||||||
|
@ -763,7 +763,7 @@ class Lwip::Udp_socket_dir final :
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Packet *pkt = new (_packet_slab) Packet(addr, port, buf);
|
Packet *pkt = new (_packet_slab) Packet(addr, port, buf);
|
||||||
_packet_queue.enqueue(pkt);
|
_packet_queue.enqueue(*pkt);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Genode::warning("failed to queue UDP packet, dropping");
|
Genode::warning("failed to queue UDP packet, dropping");
|
||||||
pbuf_free(buf);
|
pbuf_free(buf);
|
||||||
|
@ -794,25 +794,28 @@ class Lwip::Udp_socket_dir final :
|
||||||
char *dst, file_size count,
|
char *dst, file_size count,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
|
Read_result result = Read_result::READ_ERR_INVALID;
|
||||||
|
|
||||||
switch(handle.kind) {
|
switch(handle.kind) {
|
||||||
|
|
||||||
case Lwip_file_handle::DATA: {
|
case Lwip_file_handle::DATA: {
|
||||||
if (Packet *pkt = _packet_queue.head()) {
|
result = Read_result::READ_QUEUED;
|
||||||
out_count = pkt->read(dst, count);
|
_packet_queue.head([&] (Packet &pkt) {
|
||||||
if (pkt->empty()) {
|
out_count = pkt.read(dst, count);
|
||||||
destroy(_packet_slab, _packet_queue.dequeue());
|
if (pkt.empty()) {
|
||||||
|
_packet_queue.remove(pkt);
|
||||||
|
destroy(_packet_slab, &pkt);
|
||||||
}
|
}
|
||||||
return Read_result::READ_OK;
|
result = Read_result::READ_OK;
|
||||||
}
|
});
|
||||||
return Read_result::READ_QUEUED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Lwip_file_handle::PEEK: {
|
case Lwip_file_handle::PEEK:
|
||||||
if (Packet *pkt = _packet_queue.head()) {
|
_packet_queue.head([&] (Packet const &pkt) {
|
||||||
out_count = pkt->peek(dst, count);
|
out_count = pkt.peek(dst, count);
|
||||||
}
|
result = Read_result::READ_OK;
|
||||||
return Read_result::READ_OK;
|
});
|
||||||
}
|
break;
|
||||||
|
|
||||||
case Lwip_file_handle::LOCAL:
|
case Lwip_file_handle::LOCAL:
|
||||||
case Lwip_file_handle::BIND: {
|
case Lwip_file_handle::BIND: {
|
||||||
|
@ -834,28 +837,27 @@ class Lwip::Udp_socket_dir final :
|
||||||
return Read_result::READ_OK;
|
return Read_result::READ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Lwip_file_handle::REMOTE: {
|
case Lwip_file_handle::REMOTE:
|
||||||
if (count < ENDPOINT_STRLEN_MAX) {
|
if (count < ENDPOINT_STRLEN_MAX) {
|
||||||
Genode::error("VFS LwIP: accept file read buffer is too small");
|
Genode::error("VFS LwIP: accept file read buffer is too small");
|
||||||
return Read_result::READ_ERR_INVALID;
|
result = Read_result::READ_ERR_INVALID;
|
||||||
}
|
} else
|
||||||
if (ip_addr_isany(&_pcb->remote_ip)) {
|
if (ip_addr_isany(&_pcb->remote_ip)) {
|
||||||
if (Packet *pkt = _packet_queue.head()) {
|
_packet_queue.head([&] (Packet &pkt) {
|
||||||
char const *ip_str = ipaddr_ntoa(&pkt->addr);
|
char const *ip_str = ipaddr_ntoa(&pkt.addr);
|
||||||
/* TODO: IPv6 */
|
/* TODO: IPv6 */
|
||||||
out_count = Genode::snprintf(dst, count, "%s:%d\n",
|
out_count = Genode::snprintf(dst, count, "%s:%d\n",
|
||||||
ip_str, pkt->port);
|
ip_str, pkt.port);
|
||||||
return Read_result::READ_OK;
|
result = Read_result::READ_OK;
|
||||||
}
|
});
|
||||||
} else {
|
} else {
|
||||||
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
|
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
|
||||||
/* TODO: [IPv6]:port */
|
/* TODO: [IPv6]:port */
|
||||||
out_count = Genode::snprintf(dst, count, "%s:%d\n",
|
out_count = Genode::snprintf(dst, count, "%s:%d\n",
|
||||||
ip_str, _pcb->remote_port);
|
ip_str, _pcb->remote_port);
|
||||||
return Read_result::READ_OK;
|
result = Read_result::READ_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case Lwip_file_handle::LOCATION:
|
case Lwip_file_handle::LOCATION:
|
||||||
/*
|
/*
|
||||||
|
@ -869,7 +871,7 @@ class Lwip::Udp_socket_dir final :
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Read_result::READ_ERR_INVALID;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Write_result write(Lwip_file_handle &handle,
|
Write_result write(Lwip_file_handle &handle,
|
||||||
|
|
|
@ -190,26 +190,25 @@ struct Test::Main
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Genode::Reporter::Xml_generator xml(_result_reporter, [&] () {
|
Genode::Reporter::Xml_generator xml(_result_reporter, [&] () {
|
||||||
for (Test_result *tr = _results.head(); tr;
|
_results.for_each([&] (Test_result &tr) {
|
||||||
tr = tr->next()) {
|
|
||||||
xml.node("result", [&] () {
|
xml.node("result", [&] () {
|
||||||
xml.attribute("test", tr->name);
|
xml.attribute("test", tr.name);
|
||||||
xml.attribute("rx", tr->result.rx);
|
xml.attribute("rx", tr.result.rx);
|
||||||
xml.attribute("tx", tr->result.tx);
|
xml.attribute("tx", tr.result.tx);
|
||||||
xml.attribute("bytes", tr->result.bytes);
|
xml.attribute("bytes", tr.result.bytes);
|
||||||
xml.attribute("size", tr->result.request_size);
|
xml.attribute("size", tr.result.request_size);
|
||||||
xml.attribute("bsize", tr->result.block_size);
|
xml.attribute("bsize", tr.result.block_size);
|
||||||
xml.attribute("duration", tr->result.duration);
|
xml.attribute("duration", tr.result.duration);
|
||||||
|
|
||||||
if (_calculate) {
|
if (_calculate) {
|
||||||
/* XXX */
|
/* XXX */
|
||||||
xml.attribute("mibs", (unsigned)(tr->result.mibs * (1<<20u)));
|
xml.attribute("mibs", (unsigned)(tr.result.mibs * (1<<20u)));
|
||||||
xml.attribute("iops", (unsigned)(tr->result.iops + 0.5f));
|
xml.attribute("iops", (unsigned)(tr.result.iops + 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
xml.attribute("result", tr->result.success ? 0 : 1);
|
xml.attribute("result", tr.result.success ? 0 : 1);
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
} catch (...) { Genode::warning("could generate results report"); }
|
} catch (...) { Genode::warning("could generate results report"); }
|
||||||
}
|
}
|
||||||
|
@ -235,7 +234,7 @@ struct Test::Main
|
||||||
if (_report) {
|
if (_report) {
|
||||||
Test_result *tr = new (&_heap) Test_result(_current->name());
|
Test_result *tr = new (&_heap) Test_result(_current->name());
|
||||||
tr->result = r;
|
tr->result = r;
|
||||||
_results.enqueue(tr);
|
_results.enqueue(*tr);
|
||||||
|
|
||||||
_generate_report();
|
_generate_report();
|
||||||
}
|
}
|
||||||
|
@ -249,25 +248,22 @@ struct Test::Main
|
||||||
|
|
||||||
/* execute next test */
|
/* execute next test */
|
||||||
if (!_current) {
|
if (!_current) {
|
||||||
while (true) {
|
_tests.dequeue([&] (Test_base &head) {
|
||||||
_current = _tests.dequeue();
|
if (_verbose) { Genode::log("start ", head.name()); }
|
||||||
if (_current) {
|
try {
|
||||||
if (_verbose) { Genode::log("start ", _current->name()); }
|
head.start(_stop_on_error);
|
||||||
|
_current = &head;
|
||||||
try {
|
} catch (...) {
|
||||||
_current->start(_stop_on_error);
|
Genode::log("Could not start ", head.name());
|
||||||
break;
|
Genode::destroy(&_heap, &head);
|
||||||
} catch (...) {
|
|
||||||
Genode::log("Could not start ", _current->name());
|
|
||||||
Genode::destroy(&_heap, _current);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* execution is finished */
|
|
||||||
Genode::log("--- all tests finished ---");
|
|
||||||
_env.parent().exit(_success ? 0 : 1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_current) {
|
||||||
|
/* execution is finished */
|
||||||
|
Genode::log("--- all tests finished ---");
|
||||||
|
_env.parent().exit(_success ? 0 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,25 +279,25 @@ struct Test::Main
|
||||||
if (node.has_type("ping_pong")) {
|
if (node.has_type("ping_pong")) {
|
||||||
Test_base *t = new (&_heap)
|
Test_base *t = new (&_heap)
|
||||||
Ping_pong(_env, _heap, node, _finished_sigh);
|
Ping_pong(_env, _heap, node, _finished_sigh);
|
||||||
_tests.enqueue(t);
|
_tests.enqueue(*t);
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (node.has_type("random")) {
|
if (node.has_type("random")) {
|
||||||
Test_base *t = new (&_heap)
|
Test_base *t = new (&_heap)
|
||||||
Random(_env, _heap, node, _finished_sigh);
|
Random(_env, _heap, node, _finished_sigh);
|
||||||
_tests.enqueue(t);
|
_tests.enqueue(*t);
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (node.has_type("replay")) {
|
if (node.has_type("replay")) {
|
||||||
Test_base *t = new (&_heap)
|
Test_base *t = new (&_heap)
|
||||||
Replay(_env, _heap, node, _finished_sigh);
|
Replay(_env, _heap, node, _finished_sigh);
|
||||||
_tests.enqueue(t);
|
_tests.enqueue(*t);
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (node.has_type("sequential")) {
|
if (node.has_type("sequential")) {
|
||||||
Test_base *t = new (&_heap)
|
Test_base *t = new (&_heap)
|
||||||
Sequential(_env, _heap, node, _finished_sigh);
|
Sequential(_env, _heap, node, _finished_sigh);
|
||||||
_tests.enqueue(t);
|
_tests.enqueue(*t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (...) { Genode::error("invalid tests"); }
|
} catch (...) { Genode::error("invalid tests"); }
|
||||||
|
@ -326,10 +322,8 @@ struct Test::Main
|
||||||
|
|
||||||
~Main()
|
~Main()
|
||||||
{
|
{
|
||||||
Test_result * tr = nullptr;
|
_results.dequeue_all([&] (Test_result &tr) {
|
||||||
while ((tr = _results.dequeue())) {
|
Genode::destroy(&_heap, &tr); });
|
||||||
Genode::destroy(&_heap, tr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -66,27 +66,25 @@ struct Test::Replay : Test_base
|
||||||
try {
|
try {
|
||||||
while (_block->tx()->ready_to_submit() && more) {
|
while (_block->tx()->ready_to_submit() && more) {
|
||||||
/* peak at head ... */
|
/* peak at head ... */
|
||||||
Request *req = requests.head();
|
more = false;
|
||||||
if (!req) { return; }
|
requests.dequeue([&] (Request &req) {
|
||||||
|
Block::Packet_descriptor p(
|
||||||
|
_block->tx()->alloc_packet(req.count * _block_size),
|
||||||
|
req.op, req.nr, req.count);
|
||||||
|
|
||||||
Block::Packet_descriptor p(
|
bool const write = req.op == Block::Packet_descriptor::WRITE;
|
||||||
_block->tx()->alloc_packet(req->count * _block_size),
|
|
||||||
req->op, req->nr, req->count);
|
|
||||||
|
|
||||||
bool const write = req->op == Block::Packet_descriptor::WRITE;
|
/* simulate write */
|
||||||
|
if (write) {
|
||||||
|
char * const content = _block->tx()->packet_content(p);
|
||||||
|
Genode::memcpy(content, _scratch_buffer, p.size());
|
||||||
|
}
|
||||||
|
|
||||||
/* simulate write */
|
_block->tx()->submit_packet(p);
|
||||||
if (write) {
|
|
||||||
char * const content = _block->tx()->packet_content(p);
|
|
||||||
Genode::memcpy(content, _scratch_buffer, p.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
_block->tx()->submit_packet(p);
|
Genode::destroy(&alloc, &req);
|
||||||
|
more = _bulk;
|
||||||
/* ... and only remove it if we could submit it */
|
});
|
||||||
req = requests.dequeue();
|
|
||||||
Genode::destroy(&alloc, req);
|
|
||||||
more = _bulk;
|
|
||||||
}
|
}
|
||||||
} catch (...) { }
|
} catch (...) { }
|
||||||
}
|
}
|
||||||
|
@ -161,7 +159,7 @@ struct Test::Replay : Test_base
|
||||||
else if (type == "write") { op = Block::Packet_descriptor::WRITE; }
|
else if (type == "write") { op = Block::Packet_descriptor::WRITE; }
|
||||||
else { throw -1; }
|
else { throw -1; }
|
||||||
|
|
||||||
requests.enqueue(new (&alloc) Request(op, nr, count));
|
requests.enqueue(*(new (&alloc) Request(op, nr, count)));
|
||||||
++request_num;
|
++request_num;
|
||||||
});
|
});
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
|
@ -853,10 +853,10 @@ struct Igd::Device
|
||||||
|
|
||||||
bool _vgpu_already_scheduled(Vgpu &vgpu) const
|
bool _vgpu_already_scheduled(Vgpu &vgpu) const
|
||||||
{
|
{
|
||||||
for (Vgpu *v = _vgpu_list.head(); v; v = v->next()) {
|
bool result = false;
|
||||||
if (v == &vgpu) { return true; }
|
_vgpu_list.for_each([&] (Vgpu const &v) {
|
||||||
}
|
result |= (&v == &vgpu); });
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _submit_execlist(Engine<Rcs_context> &engine)
|
void _submit_execlist(Engine<Rcs_context> &engine)
|
||||||
|
@ -881,11 +881,19 @@ struct Igd::Device
|
||||||
|
|
||||||
Vgpu *_unschedule_current_vgpu()
|
Vgpu *_unschedule_current_vgpu()
|
||||||
{
|
{
|
||||||
Vgpu *gpu = _vgpu_list.dequeue();
|
Vgpu *result = nullptr;
|
||||||
return gpu;
|
_vgpu_list.dequeue([&] (Vgpu &head) {
|
||||||
|
result = &head; });
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vgpu *_current_vgpu() { return _vgpu_list.head(); }
|
Vgpu *_current_vgpu()
|
||||||
|
{
|
||||||
|
Vgpu *result = nullptr;
|
||||||
|
_vgpu_list.head([&] (Vgpu &head) {
|
||||||
|
result = &head; });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void _schedule_current_vgpu()
|
void _schedule_current_vgpu()
|
||||||
{
|
{
|
||||||
|
@ -1189,7 +1197,7 @@ struct Igd::Device
|
||||||
|
|
||||||
Vgpu const *pending = _current_vgpu();
|
Vgpu const *pending = _current_vgpu();
|
||||||
|
|
||||||
_vgpu_list.enqueue(&vgpu);
|
_vgpu_list.enqueue(vgpu);
|
||||||
|
|
||||||
if (pending) { return; }
|
if (pending) { return; }
|
||||||
|
|
||||||
|
@ -1211,9 +1219,11 @@ struct Igd::Device
|
||||||
*/
|
*/
|
||||||
bool vgpu_active(Vgpu const &vgpu) const
|
bool vgpu_active(Vgpu const &vgpu) const
|
||||||
{
|
{
|
||||||
Vgpu const *curr = _vgpu_list.head();
|
bool result = false;
|
||||||
if (!curr) { return false; }
|
_vgpu_list.head([&] (Vgpu const &curr) {
|
||||||
return &vgpu == curr ? true : false;
|
result = (&vgpu == &curr);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
|
|
Loading…
Reference in New Issue