diff options
-rw-r--r-- | Kernel/Net/NetworkAdapter.cpp | 40 | ||||
-rw-r--r-- | Kernel/Net/NetworkAdapter.h | 20 |
2 files changed, 37 insertions, 23 deletions
diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp index e1b3a999a4..e453c325d9 100644 --- a/Kernel/Net/NetworkAdapter.cpp +++ b/Kernel/Net/NetworkAdapter.cpp @@ -153,27 +153,34 @@ void NetworkAdapter::did_receive(ReadonlyBytes payload) m_packets_in++; m_bytes_in += payload.size(); - Optional<KBuffer> buffer; - if (m_packet_queue_size == max_packet_buffers) { // FIXME: Keep track of the number of dropped packets return; } - if (m_unused_packet_buffers.is_empty()) { - buffer = KBuffer::copy(payload.data(), payload.size()); + RefPtr<PacketWithTimestamp> packet; + + if (m_unused_packets.is_empty()) { + auto buffer = KBuffer::copy(payload.data(), payload.size()); + packet = adopt_ref_if_nonnull(new PacketWithTimestamp { move(buffer), kgettimeofday() }); } else { - buffer = m_unused_packet_buffers.take_first(); - --m_unused_packet_buffers_count; - if (payload.size() <= buffer.value().capacity()) { - memcpy(buffer.value().data(), payload.data(), payload.size()); - buffer.value().set_size(payload.size()); + packet = m_unused_packets.take_first(); + if (payload.size() <= packet->buffer.capacity()) { + memcpy(packet->buffer.data(), payload.data(), payload.size()); + packet->buffer.set_size(payload.size()); + packet->timestamp = kgettimeofday(); } else { - buffer = KBuffer::copy(payload.data(), payload.size()); + auto buffer = KBuffer::copy(payload.data(), payload.size()); + packet = adopt_ref_if_nonnull(new PacketWithTimestamp { move(buffer), kgettimeofday() }); } } - m_packet_queue.append({ buffer.value(), kgettimeofday() }); + if (!packet) { + dbgln("Discarding packet because we're out of memory"); + return; + } + + m_packet_queue.append(*packet); m_packet_queue_size++; if (on_receive) @@ -187,13 +194,12 @@ size_t NetworkAdapter::dequeue_packet(u8* buffer, size_t buffer_size, Time& pack return 0; auto packet_with_timestamp = m_packet_queue.take_first(); m_packet_queue_size--; - packet_timestamp = packet_with_timestamp.timestamp; - auto packet = move(packet_with_timestamp.packet); - size_t packet_size = packet.size(); + packet_timestamp = packet_with_timestamp->timestamp; + auto& packet_buffer = packet_with_timestamp->buffer; + size_t packet_size = packet_buffer.size(); VERIFY(packet_size <= buffer_size); - memcpy(buffer, packet.data(), packet_size); - m_unused_packet_buffers.append(packet); - ++m_unused_packet_buffers_count; + memcpy(buffer, packet_buffer.data(), packet_size); + m_unused_packets.append(*packet_with_timestamp); return packet_size; } diff --git a/Kernel/Net/NetworkAdapter.h b/Kernel/Net/NetworkAdapter.h index f1477f6e22..14748520c1 100644 --- a/Kernel/Net/NetworkAdapter.h +++ b/Kernel/Net/NetworkAdapter.h @@ -8,8 +8,8 @@ #include <AK/ByteBuffer.h> #include <AK/Function.h> +#include <AK/IntrusiveList.h> #include <AK/MACAddress.h> -#include <AK/SinglyLinkedList.h> #include <AK/Types.h> #include <AK/WeakPtr.h> #include <AK/Weakable.h> @@ -86,18 +86,26 @@ private: IPv4Address m_ipv4_netmask; IPv4Address m_ipv4_gateway; - struct PacketWithTimestamp { - KBuffer packet; + struct PacketWithTimestamp : public RefCounted<PacketWithTimestamp> { + PacketWithTimestamp(KBuffer buffer, Time timestamp) + : buffer(move(buffer)) + , timestamp(timestamp) + { + } + + KBuffer buffer; Time timestamp; + IntrusiveListNode<PacketWithTimestamp, RefPtr<PacketWithTimestamp>> packet_node; }; // FIXME: Make this configurable static constexpr size_t max_packet_buffers = 1024; - SinglyLinkedList<PacketWithTimestamp> m_packet_queue; + using PacketList = IntrusiveList<PacketWithTimestamp, RefPtr<PacketWithTimestamp>, &PacketWithTimestamp::packet_node>; + + PacketList m_packet_queue; size_t m_packet_queue_size { 0 }; - SinglyLinkedList<KBuffer> m_unused_packet_buffers; - size_t m_unused_packet_buffers_count { 0 }; + PacketList m_unused_packets; String m_name; u32 m_packets_in { 0 }; u32 m_bytes_in { 0 }; |