1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
// Licensed under the Apache License, Version 2.0 (see LICENSE file)
// Official repository: https://github.com/ne-foss-org/nekernel
#ifndef KERNELKIT_HARDWARETHREADSCHEDULER_H
#define KERNELKIT_HARDWARETHREADSCHEDULER_H
#include <ArchKit/ArchKit.h>
#include <CompilerKit/CompilerKit.h>
#include <NeKit/Ref.h>
/// @note Last Rev Sun 28 Jul CET 2024
/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM
#if defined(__nekernel_max_cores)
/// \note This can be edited at compile-time to specify how many cores can be used by NeKernel.
#define kMaxAPInsideSched (__nekernel_max_cores)
#endif
#if defined(__nekernel_boot_core_index)
#define kBootAPIndex (__nekernel_boot_core_index)
#endif
namespace Kernel {
enum struct ThreadKind {
kAPInvalid = 0,
kAPSystemReserved = 100, // System reserved thread, well user can't use it
kAPStandard, // user thread, cannot be used by Kernel
kAPRealTime, // fallback thread, cannot be used by user if not clear or
// used by Kernel.
kAPBoot, // The core we booted from, the mama.
kAPCount = kAPBoot - kAPSystemReserved + 1,
};
/// \brief Alias for thread ID.
using ThreadID = UInt32;
/***********************************************************************************/
///
/// \name HardwareThread
/// \brief Abstraction over the CPU's core, used to run processes or threads.
///
/***********************************************************************************/
class HardwareThread final {
public:
explicit HardwareThread();
~HardwareThread();
public:
NE_COPY_DEFAULT(HardwareThread)
public:
explicit operator bool();
public:
Void Wake(const BOOL wakeup = false);
Void Busy(const BOOL busy = false);
public:
BOOL Switch(HAL::StackFramePtr frame);
BOOL IsWakeup();
public:
HAL::StackFramePtr StackFrame();
_Output const ThreadKind& Kind();
BOOL IsBusy();
_Output const ThreadID& ID();
private:
HAL::StackFramePtr fStack{};
ThreadKind fKind{ThreadKind::kAPStandard};
ThreadID fID{};
Bool fWakeup{NO};
Bool fBusy{NO};
UInt64 fPTime{};
private:
friend class HardwareThreadScheduler;
friend class UserProcessHelper;
};
///
/// \name HardwareThreadScheduler
/// \brief Class to manage the thread scheduling.
///
class HardwareThreadScheduler final : public ISchedulable {
private:
friend class UserProcessHelper;
public:
explicit HardwareThreadScheduler();
~HardwareThreadScheduler();
NE_COPY_DEFAULT(HardwareThreadScheduler)
public:
HAL::StackFramePtr Leak();
public:
Ref<HardwareThread*> operator[](SizeT idx);
bool operator!();
operator bool();
Bool IsUser() override { return Yes; }
Bool IsKernel() override { return No; }
Bool HasMP() override { return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; }
public:
/// @brief Shared instance of the MP Mgr.
/// @return the reference to the mp manager class.
STATIC HardwareThreadScheduler& The();
public:
/// @brief Returns the amount of threads present in the system.
/// @returns SizeT the amount of cores present.
SizeT Capacity();
private:
Array<HardwareThread, kMaxAPInsideSched> fThreadList;
ThreadID fCurrentThreadIdx{0};
};
/// @brief wakes up thread.
/// wakes up thread from hang.
Void mp_wakeup_thread(HAL::StackFramePtr stack);
/// @brief makes thread sleep.
/// hooks and hangs thread to prevent code from executing.
Void mp_hang_thread(HAL::StackFramePtr stack);
} // namespace Kernel
#endif
|