summaryrefslogtreecommitdiff
path: root/Kernel/Net/NetworkAdapter.cpp
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-05-14 09:52:49 +0200
committerAndreas Kling <kling@serenityos.org>2021-05-18 16:06:27 +0200
commit093818de627bbf60cafe554ba429b3083970f8d2 (patch)
treec6a344c8762732e94aeb9c183363ee500ce1a020 /Kernel/Net/NetworkAdapter.cpp
parentb66f91e7d35ae1d2de3f0cec3d7a8489db6e37ca (diff)
downloadserenity-093818de627bbf60cafe554ba429b3083970f8d2.zip
Kernel: Avoid allocations when receiving network packets
This avoids two allocations when receiving network packets. One for inserting a PacketWithTimestamp into m_packet_queue and another one when inserting buffers into the list of unused packet buffers. With this fixed the only allocations in NetworkTask happen when initially allocating the PacketWithTimestamp structs and when switching contexts.
Diffstat (limited to 'Kernel/Net/NetworkAdapter.cpp')
-rw-r--r--Kernel/Net/NetworkAdapter.cpp40
1 files changed, 23 insertions, 17 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;
}