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)
|
||||
{
|
||||
if (context.enqueued())
|
||||
_signal_queue.remove(&context);
|
||||
_signal_queue.remove(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);
|
||||
|
||||
if (!context.enqueued()) {
|
||||
_signal_queue.enqueue(&context);
|
||||
_signal_queue.enqueue(context);
|
||||
|
||||
/* wake up client */
|
||||
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 */
|
||||
Signal_context_component &context = *_signal_queue.dequeue();
|
||||
Signal result(context.imprint(), context.cnt());
|
||||
Signal result { };
|
||||
_signal_queue.dequeue([&result] (Signal_context_component &context) {
|
||||
result = Signal(context.imprint(), context.cnt());
|
||||
context.reset_signal_cnt();
|
||||
});
|
||||
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
|
||||
* 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 */
|
||||
_request_queue.enqueue(&node);
|
||||
_request_queue.enqueue(node);
|
||||
}
|
||||
|
||||
|
||||
void Ipc_node::_cancel_request_queue()
|
||||
{
|
||||
Ipc_node * node;
|
||||
while ((node = _request_queue.dequeue()))
|
||||
node->_outbuf_request_cancelled();
|
||||
_request_queue.dequeue_all([] (Ipc_node &node) {
|
||||
node._outbuf_request_cancelled(); });
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,7 +142,7 @@ void Ipc_node::_cancel_inbuf_request()
|
|||
void Ipc_node::_announced_request_cancelled(Ipc_node &node)
|
||||
{
|
||||
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;
|
||||
|
||||
/* if anybody already announced a request receive it */
|
||||
if (!_request_queue.empty()) {
|
||||
_receive_request(*_request_queue.dequeue());
|
||||
return true;
|
||||
}
|
||||
|
||||
/* no request announced, so wait */
|
||||
/* if no request announced then wait */
|
||||
bool announced = false;
|
||||
_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
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
|
@ -22,7 +22,6 @@
|
|||
#include <base/internal/native_utcb.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/fifo.h>
|
||||
#include <kernel/interface.h>
|
||||
#include <assertion.h>
|
||||
|
||||
|
@ -37,7 +36,7 @@ namespace Kernel
|
|||
*/
|
||||
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
|
||||
|
@ -56,7 +55,6 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
|||
private:
|
||||
|
||||
friend class Core_thread;
|
||||
friend class Kernel::Fifo<Ipc_node>;
|
||||
friend class Genode::Fifo<Ipc_node>;
|
||||
|
||||
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)
|
||||
{
|
||||
/* 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 */
|
||||
_request_queue.for_each([f] (Ipc_node * const node) {
|
||||
if (node->_help) f(node); });
|
||||
_request_queue.for_each([f] (Ipc_node &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
|
||||
* 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(); }
|
||||
|
||||
|
||||
|
@ -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(); }
|
||||
|
@ -128,14 +124,8 @@ Signal_context::~Signal_context()
|
|||
|
||||
Signal_context::Signal_context(Signal_receiver * const r, addr_t const imprint)
|
||||
:
|
||||
_deliver_fe(this),
|
||||
_contexts_fe(this),
|
||||
_receiver(r),
|
||||
_imprint(imprint),
|
||||
_submits(0),
|
||||
_ack(1),
|
||||
_killed(0),
|
||||
_killer(0)
|
||||
_imprint(imprint)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!c->_deliver_fe.enqueued()) {
|
||||
_deliver.enqueue(&c->_deliver_fe);
|
||||
_deliver.enqueue(c->_deliver_fe);
|
||||
}
|
||||
_listen();
|
||||
}
|
||||
|
@ -163,40 +153,46 @@ void Signal_receiver::_listen()
|
|||
|
||||
/* create a signal data-object */
|
||||
typedef Genode::Signal_context * Signal_imprint;
|
||||
auto const context = _deliver.dequeue()->object();
|
||||
|
||||
_deliver.dequeue([&] (Signal_context::Fifo_element &elem) {
|
||||
auto const context = &elem.object();
|
||||
|
||||
Signal_imprint const imprint =
|
||||
reinterpret_cast<Signal_imprint>(context->_imprint);
|
||||
Signal::Data data(imprint, context->_submits);
|
||||
|
||||
/* communicate signal data to handler */
|
||||
auto const handler = _handlers.dequeue()->object();
|
||||
_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)
|
||||
{
|
||||
_contexts.remove(&c->_contexts_fe);
|
||||
_contexts.remove(c->_contexts_fe);
|
||||
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) {
|
||||
_handlers.remove(&h->_handlers_fe); }
|
||||
_handlers.remove(h->_handlers_fe); }
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
if (h->_receiver) { return -1; }
|
||||
_handlers.enqueue(&h->_handlers_fe);
|
||||
_handlers.enqueue(h->_handlers_fe);
|
||||
h->_receiver = this;
|
||||
h->_await_signal(this);
|
||||
_listen();
|
||||
|
@ -207,7 +203,6 @@ int Signal_receiver::add_handler(Signal_handler * const h)
|
|||
Signal_receiver::~Signal_receiver()
|
||||
{
|
||||
/* destruct all attached contexts */
|
||||
while (Signal_context * c = _contexts.dequeue()->object()) {
|
||||
c->~Signal_context();
|
||||
}
|
||||
_contexts.dequeue_all([] (Signal_context::Fifo_element &elem) {
|
||||
elem.object().~Signal_context(); });
|
||||
}
|
||||
|
|
|
@ -58,8 +58,8 @@ class Kernel::Signal_handler
|
|||
|
||||
typedef Genode::Fifo_element<Signal_handler> Fifo_element;
|
||||
|
||||
Fifo_element _handlers_fe;
|
||||
Signal_receiver * _receiver;
|
||||
Fifo_element _handlers_fe { *this };
|
||||
Signal_receiver * _receiver { nullptr };
|
||||
|
||||
/**
|
||||
* Let the handler block for signal receipt
|
||||
|
@ -86,7 +86,7 @@ class Kernel::Signal_handler
|
|||
|
||||
public:
|
||||
|
||||
Signal_handler();
|
||||
Signal_handler() { }
|
||||
virtual ~Signal_handler();
|
||||
|
||||
/**
|
||||
|
@ -158,14 +158,14 @@ class Kernel::Signal_context : public Kernel::Object
|
|||
|
||||
typedef Genode::Fifo_element<Signal_context> Fifo_element;
|
||||
|
||||
Fifo_element _deliver_fe;
|
||||
Fifo_element _contexts_fe;
|
||||
Fifo_element _deliver_fe { *this };
|
||||
Fifo_element _contexts_fe { *this };
|
||||
Signal_receiver * const _receiver;
|
||||
addr_t const _imprint;
|
||||
unsigned _submits;
|
||||
bool _ack;
|
||||
bool _killed;
|
||||
Signal_context_killer * _killer;
|
||||
Signal_context_killer * _killer { nullptr };
|
||||
unsigned _submits { 0 };
|
||||
bool _ack { true };
|
||||
bool _killed { false };
|
||||
|
||||
/**
|
||||
* Tell receiver about the submits of the context if any
|
||||
|
|
|
@ -151,15 +151,15 @@ void Thread::_await_request_failed()
|
|||
void Thread::_deactivate_used_shares()
|
||||
{
|
||||
Cpu_job::_deactivate_own_share();
|
||||
Ipc_node::for_each_helper([&] (Ipc_node * const h) {
|
||||
static_cast<Thread *>(h)->_deactivate_used_shares(); });
|
||||
Ipc_node::for_each_helper([&] (Ipc_node &h) {
|
||||
static_cast<Thread &>(h)._deactivate_used_shares(); });
|
||||
}
|
||||
|
||||
void Thread::_activate_used_shares()
|
||||
{
|
||||
Cpu_job::_activate_own_share();
|
||||
Ipc_node::for_each_helper([&] (Ipc_node * const h) {
|
||||
static_cast<Thread *>(h)->_activate_used_shares(); });
|
||||
Ipc_node::for_each_helper([&] (Ipc_node &h) {
|
||||
static_cast<Thread &>(h)._activate_used_shares(); });
|
||||
}
|
||||
|
||||
void Thread::_become_active()
|
||||
|
|
|
@ -32,7 +32,7 @@ using namespace Genode;
|
|||
void Signal_source_component::release(Signal_context_component &context)
|
||||
{
|
||||
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())
|
||||
return;
|
||||
|
||||
_signal_queue.enqueue(&context);
|
||||
_signal_queue.enqueue(context);
|
||||
|
||||
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()
|
||||
{
|
||||
if (_signal_queue.empty())
|
||||
return Signal(0, 0); /* just a dummy */
|
||||
Signal result(0, 0); /* just a dummy in the case of no signal pending */
|
||||
|
||||
/* dequeue and return pending signal */
|
||||
Signal_context_component &context = *_signal_queue.dequeue();
|
||||
Signal result(context.imprint(), context.cnt());
|
||||
_signal_queue.dequeue([&result] (Signal_context_component &context) {
|
||||
result = Signal(context.imprint(), context.cnt());
|
||||
context.reset_signal_cnt();
|
||||
});
|
||||
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
|
||||
* 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
|
||||
* blocking thread
|
||||
*/
|
||||
element = _queue.dequeue();
|
||||
_queue.dequeue([&element] (Element &head) {
|
||||
element = &head; });
|
||||
}
|
||||
|
||||
/* do not hold the lock while unblocking a waiting thread */
|
||||
|
@ -94,7 +95,7 @@ class Genode::Semaphore
|
|||
* in the wait queue.
|
||||
*/
|
||||
Element queue_element;
|
||||
_queue.enqueue(&queue_element);
|
||||
_queue.enqueue(queue_element);
|
||||
_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
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
|
@ -37,71 +37,69 @@ class Genode::Fifo
|
|||
|
||||
friend class Fifo;
|
||||
|
||||
QT *_next;
|
||||
bool _enqueued;
|
||||
QT *_next { nullptr };
|
||||
bool _enqueued { false };
|
||||
|
||||
public:
|
||||
|
||||
Element(): _next(0), _enqueued(false) { }
|
||||
Element() { }
|
||||
|
||||
/**
|
||||
* Return true is fifo element is enqueued in a fifo
|
||||
*/
|
||||
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
|
||||
*
|
||||
* \deprecated use 'Fifo::for_each' instead
|
||||
*/
|
||||
QT *next() const { return _next; }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
QT *_head; /* oldest element */
|
||||
Element *_tail; /* newest element */
|
||||
QT *_head { nullptr }; /* oldest element */
|
||||
Element *_tail { nullptr }; /* newest element */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return true if queue is empty
|
||||
*/
|
||||
bool empty() { return _tail == 0; }
|
||||
bool empty() { return _tail == nullptr; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void remove(QT *qe)
|
||||
void remove(QT &qe)
|
||||
{
|
||||
if (empty()) return;
|
||||
|
||||
/* if specified element is the first of the queue */
|
||||
if (qe == _head) {
|
||||
_head = qe->Fifo::Element::_next;
|
||||
if (!_head) _tail = 0;
|
||||
if (&qe == _head) {
|
||||
_head = qe.Fifo::Element::_next;
|
||||
if (!_head) _tail = nullptr;
|
||||
}
|
||||
else {
|
||||
|
||||
/* search specified element in the queue */
|
||||
Element *e = _head;
|
||||
while (e->_next && (e->_next != qe))
|
||||
while (e->_next && (e->_next != &qe))
|
||||
e = e->_next;
|
||||
|
||||
/* element is not member of the queue */
|
||||
|
@ -112,50 +110,78 @@ class Genode::Fifo
|
|||
if (!e->Element::_next) _tail = e;
|
||||
}
|
||||
|
||||
qe->Fifo::Element::_next = 0;
|
||||
qe->Fifo::Element::_enqueued = 0;
|
||||
qe.Fifo::Element::_next = nullptr;
|
||||
qe.Fifo::Element::_enqueued = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach element at the end of the queue
|
||||
*/
|
||||
void enqueue(QT *e)
|
||||
void enqueue(QT &e)
|
||||
{
|
||||
e->Fifo::Element::_next = 0;
|
||||
e->Fifo::Element::_enqueued = true;
|
||||
e.Fifo::Element::_next = nullptr;
|
||||
e.Fifo::Element::_enqueued = true;
|
||||
|
||||
if (empty()) {
|
||||
_tail = _head = e;
|
||||
_tail = _head = &e;
|
||||
return;
|
||||
}
|
||||
|
||||
_tail->Fifo::Element::_next = e;
|
||||
_tail = e;
|
||||
_tail->Fifo::Element::_next = &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
|
||||
*
|
||||
* \return head element or 0 if queue is empty
|
||||
* If queue is not empty then remove head and
|
||||
* call lambda 'func' of type 'void (QT&)'
|
||||
*/
|
||||
QT *dequeue()
|
||||
template <typename FUNC>
|
||||
void dequeue(FUNC const &func)
|
||||
{
|
||||
QT *result = _head;
|
||||
|
||||
/* check if queue has only one last element */
|
||||
if (_head == _tail) {
|
||||
_head = 0;
|
||||
_tail = 0;
|
||||
_head = nullptr;
|
||||
_tail = nullptr;
|
||||
} else
|
||||
_head = _head->Fifo::Element::_next;
|
||||
|
||||
/* mark fifo queue element as free */
|
||||
if (result) {
|
||||
result->Fifo::Element::_next = 0;
|
||||
result->Fifo::Element::_next = nullptr;
|
||||
result->Fifo::Element::_enqueued = false;
|
||||
|
||||
/* pass to caller */
|
||||
func(*result);
|
||||
}
|
||||
}
|
||||
|
||||
return 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>
|
||||
class Genode::Fifo_element : public Fifo<Fifo_element<T> >::Element
|
||||
{
|
||||
T *_object;
|
||||
T &_object;
|
||||
|
||||
public:
|
||||
|
||||
Fifo_element(T *object) : _object(object) { }
|
||||
Fifo_element(T &object) : _object(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;
|
||||
}
|
||||
inline T &object() { return _object; }
|
||||
};
|
||||
|
||||
#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) { }
|
||||
|
||||
using Fifo<Rm_faulter>::Element::next;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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);
|
||||
|
||||
/* check if attach operation resolves any faulting region-manager clients */
|
||||
for (Rm_faulter *faulter = _faulters.head(); faulter; ) {
|
||||
|
||||
/* 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.for_each([&] (Rm_faulter &faulter) {
|
||||
if (faulter.fault_in_addr_range((addr_t)attach_at, size)) {
|
||||
_faulters.remove(faulter);
|
||||
faulter->continue_after_resolved_fault();
|
||||
}
|
||||
|
||||
faulter = next;
|
||||
faulter.continue_after_resolved_fault();
|
||||
}
|
||||
});
|
||||
|
||||
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));
|
||||
|
||||
/* enqueue faulter */
|
||||
_faulters.enqueue(&faulter);
|
||||
_faulters.enqueue(faulter);
|
||||
|
||||
/* issue fault signal */
|
||||
_fault_notifier.submit();
|
||||
|
@ -617,9 +611,9 @@ void Region_map_component::discard_faulter(Rm_faulter &faulter, bool do_lock)
|
|||
{
|
||||
if (do_lock) {
|
||||
Lock::Guard lock_guard(_lock);
|
||||
_faulters.remove(&faulter);
|
||||
_faulters.remove(faulter);
|
||||
} else
|
||||
_faulters.remove(&faulter);
|
||||
_faulters.remove(faulter);
|
||||
}
|
||||
|
||||
|
||||
|
@ -634,15 +628,13 @@ Region_map::State Region_map_component::state()
|
|||
/* serialize access */
|
||||
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 */
|
||||
if (!faulter_ptr)
|
||||
return Region_map::State();
|
||||
Region_map::State result;
|
||||
|
||||
/* return fault information regarding the first faulter of the list */
|
||||
return faulter_ptr->fault_state();
|
||||
/* otherwise return fault information regarding the first faulter */
|
||||
_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)
|
||||
{
|
||||
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 {
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
/* dequeue and return pending signal */
|
||||
Signal_context_component &context = *_signal_queue.dequeue();
|
||||
Signal result(context.imprint(), context.cnt());
|
||||
Signal result { };
|
||||
_signal_queue.dequeue([&result] (Signal_context_component &context) {
|
||||
result = Signal(context.imprint(), context.cnt());
|
||||
context.reset_signal_cnt();
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,8 @@ extern "C" void brk(Linker::Debug *, Linker::Link_map *) { }
|
|||
|
||||
void Linker::dump_link_map(Object const &obj)
|
||||
{
|
||||
for (Object const *o = &obj; o; o = o->next_obj()) {
|
||||
|
||||
if (o->is_binary())
|
||||
continue;
|
||||
|
||||
log(" ", Hex(o->link_map().addr),
|
||||
" .. ", Hex(o->link_map().addr + o->size() - 1),
|
||||
": ", o->name());
|
||||
}
|
||||
if (!obj.is_binary())
|
||||
log(" ", Hex(obj.link_map().addr),
|
||||
" .. ", Hex(obj.link_map().addr + obj.size() - 1),
|
||||
": ", obj.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
|
||||
* 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),
|
||||
_md_alloc(&md_alloc)
|
||||
{
|
||||
deps.enqueue(this);
|
||||
deps.enqueue(*this);
|
||||
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)
|
||||
{
|
||||
for (Dependency const *d = dep.head(); d; d = d->next())
|
||||
if (!strcmp(file, d->obj().name()))
|
||||
return true;
|
||||
bool result = false;
|
||||
|
||||
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);
|
||||
} catch (...) {
|
||||
Init::list()->flush();
|
||||
while (Dependency *d = _deps.dequeue())
|
||||
destroy(_md_alloc, d);
|
||||
|
||||
_deps.dequeue_all([&] (Dependency &d) {
|
||||
destroy(_md_alloc, &d); });
|
||||
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
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
|
@ -135,7 +135,7 @@ class Linker::Dynamic
|
|||
throw Fatal();
|
||||
}
|
||||
Needed *n = new (*_md_alloc) Needed(d->un.ptr);
|
||||
_needed.enqueue(n);
|
||||
_needed.enqueue(*n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -199,8 +199,8 @@ class Linker::Dynamic
|
|||
if (!_md_alloc)
|
||||
return;
|
||||
|
||||
while (Needed *n = _needed.dequeue())
|
||||
destroy(*_md_alloc, n);
|
||||
_needed.dequeue_all([&] (Needed &n) {
|
||||
destroy(*_md_alloc, &n); });
|
||||
}
|
||||
|
||||
void call_init_function() const
|
||||
|
@ -310,8 +310,8 @@ class Linker::Dynamic
|
|||
template <typename FUNC>
|
||||
void for_each_dependency(FUNC const &fn) const
|
||||
{
|
||||
for (Needed *n = _needed.head(); n; n = n->next())
|
||||
fn(n->path(_strtab));
|
||||
_needed.for_each([&] (Needed &n) {
|
||||
fn(n.path(_strtab)); });
|
||||
}
|
||||
|
||||
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
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
|
@ -273,18 +273,27 @@ class Linker::Root_object
|
|||
|
||||
~Root_object()
|
||||
{
|
||||
while (Dependency *d = _deps.dequeue())
|
||||
destroy(_md_alloc, d);
|
||||
_deps.dequeue_all([&] (Dependency &d) {
|
||||
destroy(_md_alloc, &d); });
|
||||
}
|
||||
|
||||
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; }
|
||||
};
|
||||
|
|
|
@ -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
|
||||
* 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 */
|
||||
Init::list()->insert(this);
|
||||
obj_list()->enqueue(this);
|
||||
obj_list()->enqueue(*this);
|
||||
|
||||
/* add to link map */
|
||||
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);
|
||||
|
||||
/* remove from loaded objects list */
|
||||
obj_list()->remove(this);
|
||||
obj_list()->remove(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,7 +314,7 @@ Linker::Ld &Linker::Ld::linker()
|
|||
{
|
||||
Ld_vtable()
|
||||
{
|
||||
Elf_object::obj_list()->enqueue(this);
|
||||
Elf_object::obj_list()->enqueue(*this);
|
||||
plt_setup();
|
||||
}
|
||||
};
|
||||
|
@ -502,24 +502,30 @@ bool Linker::Object::needs_static_construction()
|
|||
Object &Linker::load(Env &env, Allocator &md_alloc, char const *path,
|
||||
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());
|
||||
log("LOAD: ", Linker::file(path), " == ", e.name());
|
||||
|
||||
if (!strcmp(Linker::file(path), e->name())) {
|
||||
e->load();
|
||||
return *e;
|
||||
if (!strcmp(Linker::file(path), e.name())) {
|
||||
e.load();
|
||||
result = &e;
|
||||
}
|
||||
}
|
||||
|
||||
return *new (md_alloc) Elf_object(env, md_alloc, path, dep, keep);
|
||||
});
|
||||
if (result == nullptr)
|
||||
result = new (md_alloc) Elf_object(env, md_alloc, path, dep, keep);
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
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() +
|
||||
Thread::stack_area_virtual_size() - 1),
|
||||
": stack area");
|
||||
dump_link_map(*Elf_object::obj_list()->head());
|
||||
Elf_object::obj_list()->for_each([] (Object const &obj) {
|
||||
dump_link_map(obj); });
|
||||
}
|
||||
} catch (...) { }
|
||||
|
||||
|
|
|
@ -108,10 +108,12 @@ class Timed_semaphore : public Semaphore
|
|||
* Iterate through the queue and find the thread,
|
||||
* with the corresponding timeout.
|
||||
*/
|
||||
Element *first = Semaphore::_queue.dequeue();
|
||||
Element *first = nullptr;
|
||||
Semaphore::_queue.dequeue([&first] (Element &e) {
|
||||
first = &e; });
|
||||
Element *e = first;
|
||||
|
||||
while (true) {
|
||||
while (e) {
|
||||
|
||||
/*
|
||||
* Wakeup the thread.
|
||||
|
@ -124,8 +126,10 @@ class Timed_semaphore : public Semaphore
|
|||
/*
|
||||
* Noninvolved threads are enqueued again.
|
||||
*/
|
||||
Semaphore::_queue.enqueue(e);
|
||||
e = Semaphore::_queue.dequeue();
|
||||
Semaphore::_queue.enqueue(*e);
|
||||
e = nullptr;
|
||||
Semaphore::_queue.dequeue([&e] (Element &next) {
|
||||
e = &next; });
|
||||
|
||||
/*
|
||||
* Maybe, the alarm was triggered just after the corresponding
|
||||
|
@ -210,7 +214,7 @@ class Timed_semaphore : public Semaphore
|
|||
* in the wait queue.
|
||||
*/
|
||||
Element queue_element;
|
||||
Semaphore::_queue.enqueue(&queue_element);
|
||||
Semaphore::_queue.enqueue(queue_element);
|
||||
Semaphore::_meta_lock.unlock();
|
||||
|
||||
/* Create the timeout */
|
||||
|
|
|
@ -78,7 +78,7 @@ struct rumpuser_mtx
|
|||
if (try_enter)
|
||||
return false;
|
||||
|
||||
fifo.enqueue(&applicant);
|
||||
fifo.enqueue(applicant);
|
||||
}
|
||||
applicant.block();
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ struct rumpuser_mtx
|
|||
owner = nullptr;
|
||||
}
|
||||
|
||||
if (Applicant *applicant = fifo.dequeue())
|
||||
applicant->wake_up();
|
||||
fifo.dequeue([] (Applicant &applicant) {
|
||||
applicant.wake_up(); });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -109,10 +109,13 @@ class Libc::Timed_semaphore : public Semaphore
|
|||
* Iterate through the queue and find the thread,
|
||||
* with the corresponding timeout.
|
||||
*/
|
||||
Element *first = Semaphore::_queue.dequeue();
|
||||
|
||||
Element *first = nullptr;
|
||||
Semaphore::_queue.dequeue([&first] (Element &e) {
|
||||
first = &e; });
|
||||
Element *e = first;
|
||||
|
||||
while (true) {
|
||||
while (e) {
|
||||
|
||||
/*
|
||||
* Wakeup the thread.
|
||||
|
@ -125,8 +128,10 @@ class Libc::Timed_semaphore : public Semaphore
|
|||
/*
|
||||
* Noninvolved threads are enqueued again.
|
||||
*/
|
||||
Semaphore::_queue.enqueue(e);
|
||||
e = Semaphore::_queue.dequeue();
|
||||
Semaphore::_queue.enqueue(*e);
|
||||
e = nullptr;
|
||||
Semaphore::_queue.dequeue([&e] (Element &next) {
|
||||
e = &next; });
|
||||
|
||||
/*
|
||||
* Maybe, the alarm was triggered just after the corresponding
|
||||
|
@ -211,7 +216,7 @@ class Libc::Timed_semaphore : public Semaphore
|
|||
* in the wait queue.
|
||||
*/
|
||||
Element queue_element;
|
||||
Semaphore::_queue.enqueue(&queue_element);
|
||||
Semaphore::_queue.enqueue(queue_element);
|
||||
Semaphore::_meta_lock.unlock();
|
||||
|
||||
/* Create the timeout */
|
||||
|
|
|
@ -64,7 +64,7 @@ class Isoc_packet : Fifo<Isoc_packet>::Element
|
|||
{
|
||||
if (!valid()) return false;
|
||||
|
||||
int remaining = _size - _offset;
|
||||
unsigned remaining = _size - _offset;
|
||||
int copy_size = min(usb_packet->iov.size, remaining);
|
||||
|
||||
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
|
||||
{
|
||||
Usb_host_device(const Usb_host_device&);
|
||||
const Usb_host_device& operator=(const Usb_host_device&);
|
||||
|
||||
struct Could_not_create_device : Exception { };
|
||||
|
||||
bool deleted = false;
|
||||
char const *label = nullptr;
|
||||
Dev_info const info;
|
||||
|
||||
USBHostDevice *qemu_dev;
|
||||
USBHostDevice *qemu_dev { nullptr };
|
||||
|
||||
/* submit queue + ack queue + 1 -> max nr of packets in flight */
|
||||
enum { NUM_COMPLETIONS = Usb::Session::TX_QUEUE_SIZE * 2 + 1 };
|
||||
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 };
|
||||
|
||||
Signal_receiver &sig_rec;
|
||||
|
@ -323,7 +326,9 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
|||
/* isochronous in */
|
||||
free_completion(packet);
|
||||
_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;
|
||||
}
|
||||
|
||||
if (isoc_read_queue.head()->copy(packet)) {
|
||||
free_packet(isoc_read_queue.dequeue());
|
||||
isoc_read_queue.head([&] (Isoc_packet &head) {
|
||||
if (head.copy(packet)) {
|
||||
isoc_read_queue.remove(head);
|
||||
free_packet(&head);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -351,9 +359,7 @@ struct Usb_host_device : List<Usb_host_device>::Element
|
|||
bool isoc_new_packet()
|
||||
{
|
||||
unsigned count = 0;
|
||||
for (Isoc_packet *packet = isoc_read_queue.head(); packet;
|
||||
packet = packet->next(), count++);
|
||||
|
||||
isoc_read_queue.for_each([&count] (Isoc_packet&) { count++; });
|
||||
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)
|
||||
{
|
||||
/* flush finished and stored data */
|
||||
for (Isoc_packet *packet = isoc_read_queue.head(); packet; )
|
||||
{
|
||||
if (!all && (!packet->valid() || packet->packet().transfer.ep != ep)) {
|
||||
packet = packet->next();
|
||||
continue;
|
||||
isoc_read_queue.for_each([&] (Isoc_packet &packet) {
|
||||
if (!all && (!packet.valid() || packet.packet().transfer.ep != ep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Isoc_packet *next = packet->next();
|
||||
isoc_read_queue.remove(packet);
|
||||
free_packet(packet);
|
||||
packet = next;
|
||||
}
|
||||
free_packet(&packet);
|
||||
});
|
||||
|
||||
/* flush in flight packets */
|
||||
flush_completion(ep);
|
||||
|
|
|
@ -702,7 +702,7 @@ class Lwip::Udp_socket_dir final :
|
|||
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);
|
||||
return pbuf_copy_partial(buf, dst, count, offset);
|
||||
|
@ -763,7 +763,7 @@ class Lwip::Udp_socket_dir final :
|
|||
{
|
||||
try {
|
||||
Packet *pkt = new (_packet_slab) Packet(addr, port, buf);
|
||||
_packet_queue.enqueue(pkt);
|
||||
_packet_queue.enqueue(*pkt);
|
||||
} catch (...) {
|
||||
Genode::warning("failed to queue UDP packet, dropping");
|
||||
pbuf_free(buf);
|
||||
|
@ -794,25 +794,28 @@ class Lwip::Udp_socket_dir final :
|
|||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
{
|
||||
Read_result result = Read_result::READ_ERR_INVALID;
|
||||
|
||||
switch(handle.kind) {
|
||||
|
||||
case Lwip_file_handle::DATA: {
|
||||
if (Packet *pkt = _packet_queue.head()) {
|
||||
out_count = pkt->read(dst, count);
|
||||
if (pkt->empty()) {
|
||||
destroy(_packet_slab, _packet_queue.dequeue());
|
||||
result = Read_result::READ_QUEUED;
|
||||
_packet_queue.head([&] (Packet &pkt) {
|
||||
out_count = pkt.read(dst, count);
|
||||
if (pkt.empty()) {
|
||||
_packet_queue.remove(pkt);
|
||||
destroy(_packet_slab, &pkt);
|
||||
}
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
return Read_result::READ_QUEUED;
|
||||
result = Read_result::READ_OK;
|
||||
});
|
||||
}
|
||||
|
||||
case Lwip_file_handle::PEEK: {
|
||||
if (Packet *pkt = _packet_queue.head()) {
|
||||
out_count = pkt->peek(dst, count);
|
||||
}
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
case Lwip_file_handle::PEEK:
|
||||
_packet_queue.head([&] (Packet const &pkt) {
|
||||
out_count = pkt.peek(dst, count);
|
||||
result = Read_result::READ_OK;
|
||||
});
|
||||
break;
|
||||
|
||||
case Lwip_file_handle::LOCAL:
|
||||
case Lwip_file_handle::BIND: {
|
||||
|
@ -834,28 +837,27 @@ class Lwip::Udp_socket_dir final :
|
|||
return Read_result::READ_OK;
|
||||
}
|
||||
|
||||
case Lwip_file_handle::REMOTE: {
|
||||
case Lwip_file_handle::REMOTE:
|
||||
if (count < ENDPOINT_STRLEN_MAX) {
|
||||
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 (Packet *pkt = _packet_queue.head()) {
|
||||
char const *ip_str = ipaddr_ntoa(&pkt->addr);
|
||||
_packet_queue.head([&] (Packet &pkt) {
|
||||
char const *ip_str = ipaddr_ntoa(&pkt.addr);
|
||||
/* TODO: IPv6 */
|
||||
out_count = Genode::snprintf(dst, count, "%s:%d\n",
|
||||
ip_str, pkt->port);
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
ip_str, pkt.port);
|
||||
result = Read_result::READ_OK;
|
||||
});
|
||||
} else {
|
||||
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
|
||||
/* TODO: [IPv6]:port */
|
||||
out_count = Genode::snprintf(dst, count, "%s:%d\n",
|
||||
ip_str, _pcb->remote_port);
|
||||
return Read_result::READ_OK;
|
||||
result = Read_result::READ_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Lwip_file_handle::LOCATION:
|
||||
/*
|
||||
|
@ -869,7 +871,7 @@ class Lwip::Udp_socket_dir final :
|
|||
default: break;
|
||||
}
|
||||
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
return result;
|
||||
}
|
||||
|
||||
Write_result write(Lwip_file_handle &handle,
|
||||
|
|
|
@ -190,26 +190,25 @@ struct Test::Main
|
|||
{
|
||||
try {
|
||||
Genode::Reporter::Xml_generator xml(_result_reporter, [&] () {
|
||||
for (Test_result *tr = _results.head(); tr;
|
||||
tr = tr->next()) {
|
||||
_results.for_each([&] (Test_result &tr) {
|
||||
xml.node("result", [&] () {
|
||||
xml.attribute("test", tr->name);
|
||||
xml.attribute("rx", tr->result.rx);
|
||||
xml.attribute("tx", tr->result.tx);
|
||||
xml.attribute("bytes", tr->result.bytes);
|
||||
xml.attribute("size", tr->result.request_size);
|
||||
xml.attribute("bsize", tr->result.block_size);
|
||||
xml.attribute("duration", tr->result.duration);
|
||||
xml.attribute("test", tr.name);
|
||||
xml.attribute("rx", tr.result.rx);
|
||||
xml.attribute("tx", tr.result.tx);
|
||||
xml.attribute("bytes", tr.result.bytes);
|
||||
xml.attribute("size", tr.result.request_size);
|
||||
xml.attribute("bsize", tr.result.block_size);
|
||||
xml.attribute("duration", tr.result.duration);
|
||||
|
||||
if (_calculate) {
|
||||
/* XXX */
|
||||
xml.attribute("mibs", (unsigned)(tr->result.mibs * (1<<20u)));
|
||||
xml.attribute("iops", (unsigned)(tr->result.iops + 0.5f));
|
||||
xml.attribute("mibs", (unsigned)(tr.result.mibs * (1<<20u)));
|
||||
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"); }
|
||||
}
|
||||
|
@ -235,7 +234,7 @@ struct Test::Main
|
|||
if (_report) {
|
||||
Test_result *tr = new (&_heap) Test_result(_current->name());
|
||||
tr->result = r;
|
||||
_results.enqueue(tr);
|
||||
_results.enqueue(*tr);
|
||||
|
||||
_generate_report();
|
||||
}
|
||||
|
@ -249,25 +248,22 @@ struct Test::Main
|
|||
|
||||
/* execute next test */
|
||||
if (!_current) {
|
||||
while (true) {
|
||||
_current = _tests.dequeue();
|
||||
if (_current) {
|
||||
if (_verbose) { Genode::log("start ", _current->name()); }
|
||||
|
||||
_tests.dequeue([&] (Test_base &head) {
|
||||
if (_verbose) { Genode::log("start ", head.name()); }
|
||||
try {
|
||||
_current->start(_stop_on_error);
|
||||
break;
|
||||
head.start(_stop_on_error);
|
||||
_current = &head;
|
||||
} catch (...) {
|
||||
Genode::log("Could not start ", _current->name());
|
||||
Genode::destroy(&_heap, _current);
|
||||
Genode::log("Could not start ", head.name());
|
||||
Genode::destroy(&_heap, &head);
|
||||
}
|
||||
} else {
|
||||
});
|
||||
}
|
||||
|
||||
if (!_current) {
|
||||
/* execution is finished */
|
||||
Genode::log("--- all tests finished ---");
|
||||
_env.parent().exit(_success ? 0 : 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,25 +279,25 @@ struct Test::Main
|
|||
if (node.has_type("ping_pong")) {
|
||||
Test_base *t = new (&_heap)
|
||||
Ping_pong(_env, _heap, node, _finished_sigh);
|
||||
_tests.enqueue(t);
|
||||
_tests.enqueue(*t);
|
||||
} else
|
||||
|
||||
if (node.has_type("random")) {
|
||||
Test_base *t = new (&_heap)
|
||||
Random(_env, _heap, node, _finished_sigh);
|
||||
_tests.enqueue(t);
|
||||
_tests.enqueue(*t);
|
||||
} else
|
||||
|
||||
if (node.has_type("replay")) {
|
||||
Test_base *t = new (&_heap)
|
||||
Replay(_env, _heap, node, _finished_sigh);
|
||||
_tests.enqueue(t);
|
||||
_tests.enqueue(*t);
|
||||
} else
|
||||
|
||||
if (node.has_type("sequential")) {
|
||||
Test_base *t = new (&_heap)
|
||||
Sequential(_env, _heap, node, _finished_sigh);
|
||||
_tests.enqueue(t);
|
||||
_tests.enqueue(*t);
|
||||
}
|
||||
});
|
||||
} catch (...) { Genode::error("invalid tests"); }
|
||||
|
@ -326,10 +322,8 @@ struct Test::Main
|
|||
|
||||
~Main()
|
||||
{
|
||||
Test_result * tr = nullptr;
|
||||
while ((tr = _results.dequeue())) {
|
||||
Genode::destroy(&_heap, tr);
|
||||
}
|
||||
_results.dequeue_all([&] (Test_result &tr) {
|
||||
Genode::destroy(&_heap, &tr); });
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -66,14 +66,13 @@ struct Test::Replay : Test_base
|
|||
try {
|
||||
while (_block->tx()->ready_to_submit() && more) {
|
||||
/* peak at head ... */
|
||||
Request *req = requests.head();
|
||||
if (!req) { return; }
|
||||
|
||||
more = false;
|
||||
requests.dequeue([&] (Request &req) {
|
||||
Block::Packet_descriptor p(
|
||||
_block->tx()->alloc_packet(req->count * _block_size),
|
||||
req->op, req->nr, req->count);
|
||||
_block->tx()->alloc_packet(req.count * _block_size),
|
||||
req.op, req.nr, req.count);
|
||||
|
||||
bool const write = req->op == Block::Packet_descriptor::WRITE;
|
||||
bool const write = req.op == Block::Packet_descriptor::WRITE;
|
||||
|
||||
/* simulate write */
|
||||
if (write) {
|
||||
|
@ -83,10 +82,9 @@ struct Test::Replay : Test_base
|
|||
|
||||
_block->tx()->submit_packet(p);
|
||||
|
||||
/* ... and only remove it if we could submit it */
|
||||
req = requests.dequeue();
|
||||
Genode::destroy(&alloc, req);
|
||||
Genode::destroy(&alloc, &req);
|
||||
more = _bulk;
|
||||
});
|
||||
}
|
||||
} catch (...) { }
|
||||
}
|
||||
|
@ -161,7 +159,7 @@ struct Test::Replay : Test_base
|
|||
else if (type == "write") { op = Block::Packet_descriptor::WRITE; }
|
||||
else { throw -1; }
|
||||
|
||||
requests.enqueue(new (&alloc) Request(op, nr, count));
|
||||
requests.enqueue(*(new (&alloc) Request(op, nr, count)));
|
||||
++request_num;
|
||||
});
|
||||
} catch (...) {
|
||||
|
|
|
@ -853,10 +853,10 @@ struct Igd::Device
|
|||
|
||||
bool _vgpu_already_scheduled(Vgpu &vgpu) const
|
||||
{
|
||||
for (Vgpu *v = _vgpu_list.head(); v; v = v->next()) {
|
||||
if (v == &vgpu) { return true; }
|
||||
}
|
||||
return false;
|
||||
bool result = false;
|
||||
_vgpu_list.for_each([&] (Vgpu const &v) {
|
||||
result |= (&v == &vgpu); });
|
||||
return result;
|
||||
}
|
||||
|
||||
void _submit_execlist(Engine<Rcs_context> &engine)
|
||||
|
@ -881,11 +881,19 @@ struct Igd::Device
|
|||
|
||||
Vgpu *_unschedule_current_vgpu()
|
||||
{
|
||||
Vgpu *gpu = _vgpu_list.dequeue();
|
||||
return gpu;
|
||||
Vgpu *result = nullptr;
|
||||
_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()
|
||||
{
|
||||
|
@ -1189,7 +1197,7 @@ struct Igd::Device
|
|||
|
||||
Vgpu const *pending = _current_vgpu();
|
||||
|
||||
_vgpu_list.enqueue(&vgpu);
|
||||
_vgpu_list.enqueue(vgpu);
|
||||
|
||||
if (pending) { return; }
|
||||
|
||||
|
@ -1211,9 +1219,11 @@ struct Igd::Device
|
|||
*/
|
||||
bool vgpu_active(Vgpu const &vgpu) const
|
||||
{
|
||||
Vgpu const *curr = _vgpu_list.head();
|
||||
if (!curr) { return false; }
|
||||
return &vgpu == curr ? true : false;
|
||||
bool result = false;
|
||||
_vgpu_list.head([&] (Vgpu const &curr) {
|
||||
result = (&vgpu == &curr);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/*********************
|
||||
|
|
Loading…
Reference in New Issue