Serenity Operating System
1/*
2 * Copyright (c) 2021, the SerenityOS developers.
3 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#pragma once
9
10#include <AK/Error.h>
11#include <AK/IntrusiveList.h>
12#include <Kernel/Forward.h>
13#include <Kernel/Locking/SpinlockProtected.h>
14#include <Kernel/WaitQueue.h>
15
16namespace Kernel {
17
18extern WorkQueue* g_io_work;
19extern WorkQueue* g_ata_work;
20
21class WorkQueue {
22 AK_MAKE_NONCOPYABLE(WorkQueue);
23 AK_MAKE_NONMOVABLE(WorkQueue);
24
25public:
26 static void initialize();
27
28 ErrorOr<void> try_queue(void (*function)(void*), void* data = nullptr, void (*free_data)(void*) = nullptr)
29 {
30 auto item = new (nothrow) WorkItem; // TODO: use a pool
31 if (!item)
32 return Error::from_errno(ENOMEM);
33 item->function = [function, data, free_data] {
34 function(data);
35 if (free_data)
36 free_data(data);
37 };
38 do_queue(*item);
39 return {};
40 }
41
42 template<typename Function>
43 ErrorOr<void> try_queue(Function function)
44 {
45 auto item = new (nothrow) WorkItem; // TODO: use a pool
46 if (!item)
47 return Error::from_errno(ENOMEM);
48 item->function = Function(function);
49 do_queue(*item);
50 return {};
51 }
52
53private:
54 explicit WorkQueue(StringView);
55
56 struct WorkItem {
57 public:
58 IntrusiveListNode<WorkItem> m_node;
59 Function<void()> function;
60 };
61
62 void do_queue(WorkItem&);
63
64 LockRefPtr<Thread> m_thread;
65 WaitQueue m_wait_queue;
66 SpinlockProtected<IntrusiveList<&WorkItem::m_node>, LockRank::None> m_items {};
67};
68
69}