Skip to content

Commit ad0cf34

Browse files
committed
more scheduler rewrite work
1 parent 0d77652 commit ad0cf34

File tree

18 files changed

+534
-187
lines changed

18 files changed

+534
-187
lines changed

kernel/interfaces/arch/aarch64/system/cpu.cppm

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,10 @@ export namespace cpu
7676
return mrs<"tpidr_el0">();
7777
}
7878

79-
std::uintptr_t self_addr() { return read_el1_base(); }
79+
std::uintptr_t self_addr()
80+
{
81+
std::uintptr_t addr;
82+
asm volatile ("mrs %0, tpidr_el1; ldr %0, [%0]" : "=r"(addr) :: "memory");
83+
return addr;
84+
}
8085
} // export namespace cpu

kernel/interfaces/arch/aarch64/system/sched/arch.cppm

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@ export namespace sched::arch
2121

2222
thread_t *current_thread();
2323

24-
void context_switch(thread_t *prev, thread_t *next);
25-
26-
void init_thread(
27-
thread_t *thread, std::uintptr_t ip, std::uintptr_t arg,
28-
std::uintptr_t stack_top, bool is_kernel
29-
);
24+
void init_core(thread_t *initial);
25+
void init_thread(thread_t *thread, std::uintptr_t ip, std::uintptr_t arg, bool is_kernel);
3026

27+
void context_switch(thread_t *prev, thread_t *next);
3128
[[noreturn]] void return_to_user(std::uintptr_t ip, std::uintptr_t stack);
3229
} // export namespace sched::arch

kernel/interfaces/arch/x86_64/system/cpu.cppm

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export namespace cpu
228228

229229
namespace gs
230230
{
231-
std::uintptr_t read()
231+
std::uintptr_t read_self()
232232
{
233233
std::uintptr_t addr;
234234
asm volatile ("mov %0, gs:[0]" : "=r"(addr) :: "memory");
@@ -245,20 +245,15 @@ export namespace cpu
245245
return msr::read(0xC0000102);
246246
}
247247

248-
void write_user(std::uintptr_t addr)
248+
void write(std::uintptr_t addr)
249249
{
250250
msr::write(0xC0000101, addr);
251251
}
252252

253-
std::uintptr_t read_user()
253+
std::uintptr_t read()
254254
{
255255
return msr::read(0xC0000101);
256256
}
257-
258-
bool is_set()
259-
{
260-
return read_user() != 0;
261-
}
262257
} // namespace gs
263258

264259
namespace fs
@@ -274,5 +269,5 @@ export namespace cpu
274269
}
275270
} // namespace gs
276271

277-
std::uintptr_t self_addr() { return gs::read(); }
272+
std::uintptr_t self_addr() { return gs::read_self(); }
278273
} // export namespace cpu

kernel/interfaces/arch/x86_64/system/sched/arch.cppm

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,9 @@ export namespace sched::arch
3535

3636
thread_t *current_thread();
3737

38-
void context_switch(thread_t *prev, thread_t *next);
39-
40-
void init_thread(
41-
thread_t *thread, std::uintptr_t ip, std::uintptr_t arg,
42-
std::uintptr_t stack_top, bool is_kernel
43-
);
38+
void init_core(thread_t *initial);
39+
void init_thread(thread_t *thread, std::uintptr_t ip, std::uintptr_t arg, bool is_kernel);
4440

41+
void context_switch(thread_t *prev, thread_t *next);
4542
[[noreturn]] void return_to_user(std::uintptr_t ip, std::uintptr_t stack);
4643
} // export namespace sched::arch

kernel/interfaces/system/sched/process.cppm

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export namespace sched
3434
struct process_t
3535
{
3636
pid_t pid;
37-
pid_t ppid;
3837

3938
process_t *parent;
4039

@@ -49,33 +48,33 @@ export namespace sched
4948
session_t *session;
5049

5150
std::shared_ptr<vmm::vmspace> vmspace;
51+
52+
struct vfs_state
53+
{
54+
vfs::path root;
55+
vfs::path cwd;
56+
mode_t umask = static_cast<mode_t>(s_iwgrp | s_iwoth);
57+
};
58+
std::shared_ptr<vfs_state> vfs;
5259
std::shared_ptr<vfs::fdtable> fds;
5360

61+
std::shared_ptr<cred_t> cred;
62+
63+
std::shared_ptr<signal_action_t> sigactions;
64+
signal_queue_t sigqueue;
65+
5466
lib::locker<
5567
lib::map::flat_hash<
5668
pid_t,
5769
thread_t *
5870
>, lib::spinlock
5971
> threads;
6072

61-
std::atomic<std::size_t> alive_threads;
62-
63-
std::shared_ptr<cred_t> cred;
64-
65-
std::shared_ptr<signal_action_t> sigactions;
66-
signal_queue_t sigqueue;
73+
std::atomic<std::size_t> alive_threads = 0;
6774

6875
int exit_code = 0;
6976
bool is_zombie = false;
7077

71-
struct vfs_state
72-
{
73-
vfs::path root;
74-
vfs::path cwd;
75-
mode_t umask = static_cast<mode_t>(s_iwgrp | s_iwoth);
76-
};
77-
std::shared_ptr<vfs_state> vfs;
78-
7978
lib::spinlock lock;
8079
};
8180

kernel/interfaces/system/sched/run_queue.cppm

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -36,49 +36,54 @@ namespace sched
3636

3737
export namespace sched
3838
{
39-
struct cfs_run_queue_t
39+
struct run_queue_t
4040
{
41+
lib::spinlock lock;
42+
4143
lib::rbtree<
42-
entity_t, &entity_t::hook,
44+
thread_t, &thread_t::hook,
4345
compare<
44-
entity_t,
46+
thread_t,
4547
std::uint64_t,
46-
&entity_t::vruntime
48+
&thread_t::vruntime
4749
>
4850
> queue;
4951

50-
entity_t *current;
51-
5252
std::uint64_t total_weight;
5353
std::uint64_t _min_vruntime;
5454

55-
inline std::size_t num_entities() const
56-
{
57-
return queue.size();
58-
}
55+
std::size_t cpu_idx;
56+
std::uint64_t nr_running;
5957

60-
cfs_run_queue_t()
61-
: queue { }, current { nullptr }, total_weight { 0 }, _min_vruntime { 0 } { }
58+
thread_t *current;
59+
thread_t *idle;
6260

63-
// enqueue when entity becomes runnable
64-
void enqueue(entity_t *entity);
65-
// dequeue when entity leaves runnable state
66-
void dequeue(entity_t *entity);
61+
std::uint64_t nr_switches;
62+
63+
std::uint64_t load_update;
64+
std::uint64_t load_active;
6765

68-
// pick the next entity to run (least amount of vruntime)
66+
bool needs_resched;
67+
68+
// enqueue when thread becomes runnable
69+
void enqueue(thread_t *thread);
70+
// dequeue when thread leaves runnable state
71+
void dequeue(thread_t *thread);
72+
73+
// pick the next thread to run (least amount of vruntime)
6974
// nullptr if empty
70-
entity_t *pick_next();
75+
thread_t *pick_next();
7176

72-
// update current entity vruntime
77+
// update current thread vruntime
7378
void update_current(std::uint64_t now);
7479

7580
// adjust vruntime
76-
void adjust(entity_t *entity, bool initial);
81+
void adjust(thread_t *thread, bool initial);
7782

78-
// check if current should be preempted with entity
79-
bool check_preempt_wakeup(entity_t *entity);
83+
// check if current should be preempted with thread
84+
bool check_preempt_wakeup(thread_t *thread);
8085

81-
// calculate fair timeslice for an entity
86+
// calculate fair timeslice for a thread
8287
std::uint64_t calc_timeslice(std::uint64_t weight);
8388

8489
std::uint64_t calc_vruntime(
@@ -88,24 +93,4 @@ export namespace sched
8893

8994
void update_min_vruntime();
9095
};
91-
92-
struct run_queue_t
93-
{
94-
lib::spinlock_preempt lock;
95-
96-
std::size_t cpu_idx;
97-
std::uint64_t nr_running;
98-
99-
thread_t *current;
100-
thread_t *idle;
101-
102-
cfs_run_queue_t cfs;
103-
104-
std::uint64_t nr_switches;
105-
106-
std::uint64_t load_update;
107-
std::uint64_t load_active;
108-
109-
bool needs_resched;
110-
};
11196
} // export namespace sched

kernel/interfaces/system/sched/scheduler.cppm

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export import :wait_queue;
1212
export import :work_queue;
1313

1414
import :arch;
15+
import boot;
1516

1617
// implemented in :arch
1718
namespace sched::arch
@@ -22,18 +23,18 @@ namespace sched::arch
2223
// makes sure that thread doesn't migrate to another core
2324
thread_t *current_thread();
2425

25-
void context_switch(thread_t *prev, thread_t *next);
26-
27-
void init_thread(
28-
thread_t *thread, std::uintptr_t ip, std::uintptr_t arg,
29-
std::uintptr_t stack_top, bool is_kernel
30-
);
26+
void init_core(thread_t *initial);
27+
void init_thread(thread_t *thread, std::uintptr_t ip, std::uintptr_t arg, bool is_kernel);
3128

29+
void context_switch(thread_t *prev, thread_t *next);
3230
[[noreturn]] void return_to_user(std::uintptr_t ip, std::uintptr_t stack);
3331
} // namespace sched::arch
3432

3533
export namespace sched
3634
{
35+
constexpr std::size_t kstack_size = boot::kstack_size;
36+
constexpr std::size_t ustack_size = boot::ustack_size;
37+
3738
// called from bsp
3839
void init();
3940

@@ -72,11 +73,14 @@ export namespace sched
7273
// called on yield, block, timer or wake up
7374
void schedule();
7475

75-
// create and run a new kernel thread under pid 0
76-
thread_t *create_kthread(nice_t nice, std::uintptr_t ip, std::uintptr_t arg);
76+
// create a new kernel thread under pid 0
77+
thread_t *create_kthread(std::uintptr_t ip, std::uintptr_t arg, nice_t nice = default_nice);
7778

7879
// create a user thread
79-
thread_t *create_thread(process_t *proc, int nice, std::uintptr_t entry, std::uintptr_t stack);
80+
thread_t *create_uthread(process_t *proc, std::uintptr_t entry, std::uintptr_t stack, nice_t nice = default_nice);
81+
82+
// enqueue a new thread on current cpu
83+
void enqueue_new(thread_t *thread);
8084

8185
bool wake_up(thread_t *thread, bool preempt = true);
8286

kernel/interfaces/system/sched/thread.cppm

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
export module system.sched:thread;
44

5+
import system.sched.thread_base;
6+
57
import system.cpu.local;
68
import magic_enum;
79
import lib;
@@ -34,32 +36,16 @@ export namespace sched
3436

3537
using namespace magic_enum::bitwise_operators;
3638

37-
struct entity_t
38-
{
39-
std::uint64_t vruntime = 0;
40-
std::uint64_t total_runtime = 0;
41-
std::uint64_t prev_runtime = 0;
42-
std::uint64_t sched_time = 0;
43-
44-
nice_t nice = default_nice;
45-
std::uint64_t weight = nice_to_weight(nice);
46-
std::uint64_t inv_weight = nice_to_inv_weight(nice);
47-
48-
bool on_rq = false;
49-
50-
lib::rbtree_hook<entity_t> hook;
51-
};
52-
5339
struct process_t;
54-
struct thread_t
40+
struct thread_t : thread_base_t
5541
{
5642
// accessed from assembly
5743
cpu::processor *running_on;
5844
std::uintptr_t ustack_top;
5945
std::uintptr_t kstack_top;
6046
thread_t *self;
6147

62-
std::atomic<std::ssize_t> preempt_count;
48+
std::atomic<std::ssize_t> preempt_count = 0;
6349

6450
// sizes are fixed
6551
std::uintptr_t ustack_base;
@@ -72,7 +58,18 @@ export namespace sched
7258
thread_flags flags = thread_flags::none;
7359
int exit_code = 0;
7460

75-
entity_t entity;
61+
std::uint64_t vruntime = 0;
62+
std::uint64_t total_runtime = 0;
63+
std::uint64_t prev_runtime = 0;
64+
std::uint64_t sched_time = 0;
65+
66+
nice_t nice;
67+
std::uint64_t weight;
68+
std::uint64_t inv_weight;
69+
70+
bool in_rq = false;
71+
lib::rbtree_hook<thread_t> hook;
72+
7673
arch::context *ctx;
7774
arch::data adata;
7875

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright (C) 2024-2026 ilobilo
2+
3+
export module system.sched.thread_base;
4+
5+
export namespace sched
6+
{
7+
struct thread_base_t { };
8+
} // export namespace sched

0 commit comments

Comments
 (0)