diff --git a/repos/os/include/os/packet_stream.h b/repos/os/include/os/packet_stream.h index 7705670654..7a7a498b26 100644 --- a/repos/os/include/os/packet_stream.h +++ b/repos/os/include/os/packet_stream.h @@ -639,6 +639,10 @@ class Genode::Packet_stream_source : private Packet_stream_base class Saturated_submit_queue : Exception { }; class Empty_ack_queue : Exception { }; + enum class Alloc_packet_error { FAILED }; + + using Alloc_packet_result = Attempt; + /** * Constructor * @@ -726,6 +730,29 @@ class Genode::Packet_stream_source : private Packet_stream_base throw Packet_alloc_failed(); }); } + /** + * Allocate packet without throwing exceptions + * + * \param size size of packet in bytes + * \param align alignment of packet as log2 value, default is 1 byte + * \return an Attempt object that either contains an error or a + * packet descriptor with an assigned range within the + * bulk buffer shared between source and sink + */ + Alloc_packet_result alloc_packet_attempt(Genode::size_t size, unsigned align = PACKET_ALIGNMENT) + { + if (size == 0) + return Packet_descriptor(0, 0); + + return _packet_alloc.alloc_aligned(size, align).convert( + + [&] (void *base) { + return Packet_descriptor((Genode::off_t)base, size); }, + + [&] (Allocator::Alloc_error) { + return Alloc_packet_error::FAILED; }); + } + /** * Get pointer to the content of the specified packet * diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 24e6d7b270..f7a6282b52 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -1850,15 +1850,6 @@ void Interface::send(Ethernet_frame ð, } -void Interface::_send_alloc_pkt(Packet_descriptor &pkt, - void * &pkt_base, - size_t pkt_size) -{ - pkt = _source.alloc_packet(pkt_size); - pkt_base = _source.packet_content(pkt); -} - - void Interface::_send_submit_pkt(Packet_descriptor &pkt, void * &pkt_base, size_t pkt_size) diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 117e1e2a73..9661c3f160 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -307,10 +307,6 @@ class Net::Interface : private Interface_list::Element void _ack_packet(Packet_descriptor const &pkt); - void _send_alloc_pkt(Genode::Packet_descriptor &pkt, - void * &pkt_base, - Genode::size_t pkt_size); - void _send_submit_pkt(Genode::Packet_descriptor &pkt, void * &pkt_base, Genode::size_t pkt_size); @@ -402,18 +398,19 @@ class Net::Interface : private Interface_list::Element _failed_to_send_packet_submit(); return; } - try { - Packet_descriptor pkt; - void *pkt_base; - - _send_alloc_pkt(pkt, pkt_base, pkt_size); - Size_guard size_guard(pkt_size); - write_to_pkt(pkt_base, size_guard); - _send_submit_pkt(pkt, pkt_base, pkt_size); - } - catch (Packet_stream_source::Packet_alloc_failed) { - _failed_to_send_packet_alloc(); - } + _source.alloc_packet_attempt(pkt_size).with_result( + [&] (Packet_descriptor pkt) + { + void *pkt_base { _source.packet_content(pkt) }; + Size_guard size_guard(pkt_size); + write_to_pkt(pkt_base, size_guard); + _send_submit_pkt(pkt, pkt_base, pkt_size); + }, + [&] (Packet_stream_source::Alloc_packet_error) + { + _failed_to_send_packet_alloc(); + } + ); } void send(Ethernet_frame ð,