mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 09:46:04 -05:00
Kernel: Make AsyncDeviceRequest sub-req management alloc free
The previous implementation could allocate on insertion into the completed / pending sub request vectors. There's no reason these can't be intrusive lists instead. This is a very minor step towards improving the ability to handle OOM, as tracked by #6369 It might also help improve performance on the IO path in certain situations. I'll benchmark that later.
This commit is contained in:
parent
f1d832e5ea
commit
033b287635
Notes:
sideshowbarker
2024-07-18 19:17:48 +09:00
Author: https://github.com/bgianfo Commit: https://github.com/SerenityOS/serenity/commit/033b2876351 Pull-request: https://github.com/SerenityOS/serenity/pull/6509 Reviewed-by: https://github.com/alimpfard
2 changed files with 22 additions and 19 deletions
|
@ -49,10 +49,13 @@ AsyncDeviceRequest::~AsyncDeviceRequest()
|
||||||
// sub-requests should be completed (either succeeded, failed, or cancelled).
|
// sub-requests should be completed (either succeeded, failed, or cancelled).
|
||||||
// Which means there should be no more pending sub-requests and the
|
// Which means there should be no more pending sub-requests and the
|
||||||
// entire AsyncDeviceRequest hierarchy should be immutable.
|
// entire AsyncDeviceRequest hierarchy should be immutable.
|
||||||
for (auto& sub_request : m_sub_requests_complete) {
|
while (!m_sub_requests_complete.is_empty()) {
|
||||||
VERIFY(is_completed_result(sub_request.m_result)); // Shouldn't need any locking anymore
|
// Note: sub_request is ref-counted, and we use this specific pattern
|
||||||
VERIFY(sub_request.m_parent_request == this);
|
// to allow make sure the refcount is dropped properly.
|
||||||
sub_request.m_parent_request = nullptr;
|
auto sub_request = m_sub_requests_complete.take_first();
|
||||||
|
VERIFY(is_completed_result(sub_request->m_result)); // Shouldn't need any locking anymore
|
||||||
|
VERIFY(sub_request->m_parent_request == this);
|
||||||
|
sub_request->m_parent_request = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,24 +107,19 @@ void AsyncDeviceRequest::sub_request_finished(AsyncDeviceRequest& sub_request)
|
||||||
{
|
{
|
||||||
ScopedSpinLock lock(m_lock);
|
ScopedSpinLock lock(m_lock);
|
||||||
VERIFY(m_result == Started);
|
VERIFY(m_result == Started);
|
||||||
size_t index;
|
|
||||||
for (index = 0; index < m_sub_requests_pending.size(); index++) {
|
if (m_sub_requests_pending.contains(sub_request)) {
|
||||||
if (&m_sub_requests_pending[index] == &sub_request) {
|
// Note: append handles removing from any previous intrusive list internally.
|
||||||
NonnullRefPtr<AsyncDeviceRequest> request(m_sub_requests_pending[index]);
|
m_sub_requests_complete.append(sub_request);
|
||||||
m_sub_requests_pending.remove(index);
|
|
||||||
m_sub_requests_complete.append(move(request));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
VERIFY(index < m_sub_requests_pending.size());
|
|
||||||
all_completed = m_sub_requests_pending.is_empty();
|
all_completed = m_sub_requests_pending.is_empty();
|
||||||
if (all_completed) {
|
if (all_completed) {
|
||||||
// Aggregate any errors
|
// Aggregate any errors
|
||||||
bool any_failures = false;
|
bool any_failures = false;
|
||||||
bool any_memory_faults = false;
|
bool any_memory_faults = false;
|
||||||
for (index = 0; index < m_sub_requests_complete.size(); index++) {
|
for (auto& com_sub_request : m_sub_requests_complete) {
|
||||||
auto& sub_request = m_sub_requests_complete[index];
|
auto sub_result = com_sub_request.get_request_result();
|
||||||
auto sub_result = sub_request.get_request_result();
|
|
||||||
VERIFY(is_completed_result(sub_result));
|
VERIFY(is_completed_result(sub_result));
|
||||||
switch (sub_result) {
|
switch (sub_result) {
|
||||||
case Failure:
|
case Failure:
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/NonnullRefPtrVector.h>
|
#include <AK/IntrusiveList.h>
|
||||||
|
#include <AK/NonnullRefPtr.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
#include <Kernel/Thread.h>
|
#include <Kernel/Thread.h>
|
||||||
#include <Kernel/UserOrKernelBuffer.h>
|
#include <Kernel/UserOrKernelBuffer.h>
|
||||||
|
@ -160,8 +161,12 @@ private:
|
||||||
|
|
||||||
AsyncDeviceRequest* m_parent_request { nullptr };
|
AsyncDeviceRequest* m_parent_request { nullptr };
|
||||||
RequestResult m_result { Pending };
|
RequestResult m_result { Pending };
|
||||||
NonnullRefPtrVector<AsyncDeviceRequest> m_sub_requests_pending;
|
IntrusiveListNode<AsyncDeviceRequest, RefPtr<AsyncDeviceRequest>> m_list_node;
|
||||||
NonnullRefPtrVector<AsyncDeviceRequest> m_sub_requests_complete;
|
|
||||||
|
typedef IntrusiveList<AsyncDeviceRequest, RefPtr<AsyncDeviceRequest>, &AsyncDeviceRequest::m_list_node> AsyncDeviceSubRequestList;
|
||||||
|
|
||||||
|
AsyncDeviceSubRequestList m_sub_requests_pending;
|
||||||
|
AsyncDeviceSubRequestList m_sub_requests_complete;
|
||||||
WaitQueue m_queue;
|
WaitQueue m_queue;
|
||||||
NonnullRefPtr<Process> m_process;
|
NonnullRefPtr<Process> m_process;
|
||||||
void* m_private { nullptr };
|
void* m_private { nullptr };
|
||||||
|
|
Loading…
Add table
Reference in a new issue