mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 21:08:12 +00:00

Background: DoubleBuffer is a handy buffer class in the kernel that allows you to keep writing to it from the "outside" while the "inside" reads from it. It's used for things like LocalSocket and PTY's. Internally, it has a read buffer and a write buffer, but the two will swap places when the read buffer is exhausted (by reading from it.) Before this patch, it was internally implemented as two Vector<u8> that we would swap between when the reader side had exhausted the data in the read buffer. Now instead we preallocate a large KBuffer (64KB*2) on DoubleBuffer construction and use that throughout its lifetime. This removes all the kmalloc heap traffic caused by DoubleBuffers :^)
38 lines
856 B
C++
38 lines
856 B
C++
#pragma once
|
|
|
|
#include <AK/Types.h>
|
|
#include <Kernel/KBuffer.h>
|
|
#include <Kernel/Lock.h>
|
|
|
|
class DoubleBuffer {
|
|
public:
|
|
explicit DoubleBuffer(size_t capacity = 65536);
|
|
|
|
ssize_t write(const u8*, ssize_t);
|
|
ssize_t read(u8*, ssize_t);
|
|
|
|
bool is_empty() const { return m_empty; }
|
|
|
|
size_t space_for_writing() const { return m_space_for_writing; }
|
|
|
|
private:
|
|
void flip();
|
|
void compute_lockfree_metadata();
|
|
|
|
struct InnerBuffer {
|
|
u8* data { nullptr };
|
|
size_t size;
|
|
};
|
|
|
|
InnerBuffer* m_write_buffer { nullptr };
|
|
InnerBuffer* m_read_buffer { nullptr };
|
|
InnerBuffer m_buffer1;
|
|
InnerBuffer m_buffer2;
|
|
|
|
KBuffer m_storage;
|
|
size_t m_capacity { 0 };
|
|
size_t m_read_buffer_index { 0 };
|
|
size_t m_space_for_writing { 0 };
|
|
bool m_empty { true };
|
|
mutable Lock m_lock { "DoubleBuffer" };
|
|
};
|