MCPcopy Create free account
hub / github.com/Simple-XX/SimpleKernel / Balance

Method Balance

src/task/task_manager.cpp:181–258  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

179}
180
181auto TaskManager::Balance() -> void {
182 auto current_core = cpu_io::GetCurrentCoreId();
183 auto& current_sched = cpu_schedulers_[current_core];
184
185 // 获取当前核心 kNormal 队列长度(无锁快速检查)
186 size_t current_load = 0;
187 if (current_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)]) {
188 current_load =
189 current_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)]
190 ->GetQueueSize();
191 }
192
193 // 寻找负载最高的核心
194 size_t max_load = 0;
195 size_t max_core = current_core;
196
197 for (size_t core_id = 0; core_id < SIMPLEKERNEL_MAX_CORE_COUNT; ++core_id) {
198 if (core_id == current_core) {
199 continue;
200 }
201 auto& other_sched = cpu_schedulers_[core_id];
202 if (other_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)]) {
203 size_t load =
204 other_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)]
205 ->GetQueueSize();
206 if (load > max_load) {
207 max_load = load;
208 max_core = core_id;
209 }
210 }
211 }
212
213 // 仅当差值 > 1 时才窃取(避免 ping-pong)
214 if (max_core == current_core || max_load <= current_load + 1) {
215 return;
216 }
217
218 // 按核心 ID 顺序获取锁,防止死锁
219 auto& source_sched = cpu_schedulers_[max_core];
220 size_t first_core = (current_core < max_core) ? current_core : max_core;
221 size_t second_core = (current_core < max_core) ? max_core : current_core;
222
223 LockGuard<SpinLock> lock_first(cpu_schedulers_[first_core].lock);
224 LockGuard<SpinLock> lock_second(cpu_schedulers_[second_core].lock);
225
226 // 重新检查(持锁后条件可能已变化)
227 auto* source_scheduler =
228 source_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)].get();
229 auto* dest_scheduler =
230 current_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)]
231 .get();
232
233 if (!source_scheduler || !dest_scheduler) {
234 return;
235 }
236
237 size_t source_load = source_scheduler->GetQueueSize();
238 size_t dest_load = dest_scheduler->GetQueueSize();

Callers

nothing calls this directly

Calls 5

GetCurrentCoreIdFunction · 0.85
DebugFunction · 0.85
GetQueueSizeMethod · 0.45
PickNextMethod · 0.45
EnqueueMethod · 0.45

Tested by

no test coverage detected