blob: 84d788da08721f6284193a2046046aab14d6ed97 (
plain)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
// 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
#include <ArchKit/ArchKit.h>
#include <CFKit/Property.h>
#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/ProcessScheduler.h>
/***********************************************************************************/
///! @file HardwareThreadScheduler.cc
///! @brief This file handles multi processing in the Kernel.
///! @brief Multi processing is needed for multi-tasking operations.
/***********************************************************************************/
namespace Kernel {
/***********************************************************************************/
/// @note Those symbols are needed in order to switch and validate the stack.
/***********************************************************************************/
EXTERN_C Bool hal_check_task(HAL::StackFramePtr frame);
EXTERN_C Bool mp_register_task(HAL::StackFramePtr frame, ProcessID pid);
STATIC HardwareThreadScheduler kHardwareThreadScheduler;
///! A HardwareThread class takes care of it's owned hardware thread.
///! It has a stack for it's core.
/***********************************************************************************/
///! @brief C++ constructor.
/***********************************************************************************/
HardwareThread::HardwareThread() = default;
/***********************************************************************************/
///! @brief C++ destructor.
/***********************************************************************************/
HardwareThread::~HardwareThread() = default;
/***********************************************************************************/
//! @brief returns the id of the thread.
/***********************************************************************************/
_Output const ThreadID& HardwareThread::ID() {
return fID;
}
/***********************************************************************************/
//! @brief returns the kind of thread we have.
/***********************************************************************************/
_Output const ThreadKind& HardwareThread::Kind() {
return fKind;
}
/***********************************************************************************/
//! @brief is the thread busy?
//! @return whether the thread is busy or not.
/***********************************************************************************/
Bool HardwareThread::IsBusy() {
return fBusy;
}
/***********************************************************************************/
/// @brief Get processor stack frame.
/***********************************************************************************/
HAL::StackFramePtr HardwareThread::StackFrame() {
MUST_PASS(this->fStack);
return this->fStack;
}
Void HardwareThread::Busy(Bool busy) {
this->fBusy = busy;
}
HardwareThread::operator bool() {
return this->fStack && !this->fBusy;
}
/***********************************************************************************/
/// @brief Wakeup the processor.
/***********************************************************************************/
Void HardwareThread::Wake(const bool wakeup) {
this->fWakeup = wakeup;
}
/***********************************************************************************/
/// @brief Switch to hardware thread.
/// @param stack the new hardware thread.
/// @retval true stack was changed, code is running.
/// @retval false stack is invalid, previous code is running.
/***********************************************************************************/
Bool HardwareThread::Switch(HAL::StackFramePtr frame) {
if (!frame) {
return NO;
}
if (!hal_check_task(frame)) {
return NO;
}
this->fStack = frame;
return mp_register_task(fStack, this->fID);
}
/***********************************************************************************/
///! @brief Tells if processor is waked up.
/***********************************************************************************/
bool HardwareThread::IsWakeup() {
return this->fWakeup;
}
/***********************************************************************************/
///! @brief Constructor and destructors.
///! @brief Default constructor.
/***********************************************************************************/
HardwareThreadScheduler::HardwareThreadScheduler() = default;
/***********************************************************************************/
///! @brief Default destructor.
/***********************************************************************************/
HardwareThreadScheduler::~HardwareThreadScheduler() = default;
/***********************************************************************************/
/// @brief Shared singleton function
/***********************************************************************************/
HardwareThreadScheduler& HardwareThreadScheduler::The() {
return kHardwareThreadScheduler;
}
/***********************************************************************************/
/// @brief Get Stack Frame of AP.
/***********************************************************************************/
HAL::StackFramePtr HardwareThreadScheduler::Leak() {
return fThreadList[fCurrentThreadIdx].fStack;
}
/***********************************************************************************/
/**
* Get Hardware thread at index.
* @param idx the index
* @return the reference to the hardware thread.
*/
/***********************************************************************************/
Ref<HardwareThread*> HardwareThreadScheduler::operator[](SizeT idx) {
if (idx > kMaxAPInsideSched) {
STATIC HardwareThread* kFakeThread = nullptr;
return {kFakeThread};
}
fCurrentThreadIdx = idx;
return &fThreadList[idx];
}
/***********************************************************************************/
/**
* Check if thread pool isn't empty.
* @return
*/
/***********************************************************************************/
HardwareThreadScheduler::operator bool() {
return !fThreadList.Empty();
}
/***********************************************************************************/
/**
* Reverse operator bool
* @return
*/
/***********************************************************************************/
bool HardwareThreadScheduler::operator!() {
return fThreadList.Empty();
}
/***********************************************************************************/
/// @brief Returns the amount of core present.
/// @return the number of APs.
/***********************************************************************************/
SizeT HardwareThreadScheduler::Capacity() {
return fThreadList.Count();
}
} // namespace Kernel
|