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
138
139
140
141
142
143
144
145
146
147
|
/* -------------------------------------------
Copyright ZKA Technologies.
------------------------------------------- */
#ifndef __INC_MP_MANAGER_HPP__
#define __INC_MP_MANAGER_HPP__
#include <ArchKit/ArchKit.hxx>
#include <CompilerKit/CompilerKit.hxx>
#include <NewKit/Ref.hxx>
/// @note Last Rev Sun 28 Jul CET 2024
/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM
#define cMaxHWThreads (8U)
namespace Kernel
{
class HardwareThread;
class HardwareThreadScheduler;
using ThreadID = UInt32;
enum ThreadKind
{
kHartSystemReserved, // System reserved thread, well user can't use it
kHartStandard, // user thread, cannot be used by Kernel
kHartFallback, // fallback thread, cannot be used by user if not clear or
// used by Kernel.
kHartBoot, // The core we booted from, the mama.
kInvalidHart,
kHartCount,
};
typedef enum ThreadKind ThreadKind;
typedef ThreadID ThreadID;
///
/// \name HardwareThread
/// \brief Abstraction over the CPU's core, used to run processes or threads.
///
class HardwareThread final
{
public:
explicit HardwareThread();
~HardwareThread();
public:
ZKA_COPY_DEFAULT(HardwareThread)
public:
operator bool();
public:
void Wake(const bool wakeup = false) noexcept;
void Busy(const bool busy = false) noexcept;
public:
bool Switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr frame);
bool IsWakeup() noexcept;
public:
HAL::StackFramePtr StackFrame() noexcept;
const ThreadKind& Kind() noexcept;
bool IsBusy() noexcept;
const ThreadID& ID() noexcept;
private:
HAL::StackFramePtr fStack{nullptr};
ThreadKind fKind{ThreadKind::kHartStandard};
ThreadID fID{0};
ProcessID fSourcePID{-1};
Bool fWakeup{false};
Bool fBusy{false};
UInt64 fPTime{0};
private:
friend class HardwareThreadScheduler;
friend class UserProcessHelper;
};
///
/// \name HardwareThreadScheduler
/// \brief Class to manage the thread scheduling.
///
class HardwareThreadScheduler final : public ISchedulerObject
{
private:
friend class UserProcessHelper;
public:
explicit HardwareThreadScheduler();
~HardwareThreadScheduler();
ZKA_COPY_DEFAULT(HardwareThreadScheduler);
public:
HAL::StackFramePtr Leak() noexcept;
public:
Ref<HardwareThread*> operator[](const SizeT& idx);
bool operator!() noexcept;
operator bool() noexcept;
const Bool IsUser() override
{
return Yes;
}
const Bool IsKernel() override
{
return No;
}
const 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 Count() noexcept;
private:
Array<HardwareThread, cMaxHWThreads> fThreadList;
ThreadID fCurrentThread{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 // !__INC_MP_MANAGER_HPP__
|