Skip to content

Commit 766e674

Browse files
committed
use smart pointers for threads and processes
1 parent 529c98f commit 766e674

26 files changed

Lines changed: 524 additions & 443 deletions

File tree

kernel/interfaces/drivers/fs/dev/tty.cppm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ export namespace fs::dev::tty
430430

431431
std::atomic_bool stopped;
432432

433-
sched::thread_t *worker_thread;
433+
std::weak_ptr<sched::thread_t> worker_thread;
434434
std::atomic_bool should_work;
435435
std::atomic_bool shut_down;
436436
sched::wait_queue_t hung_wq;
@@ -485,7 +485,7 @@ export namespace fs::dev::tty
485485

486486
lib::rbspscd<std::byte, raw_buffer_size> raw_buffer;
487487
sched::wait_queue_t raw_wq;
488-
sched::thread_t *worker_thread;
488+
std::weak_ptr<sched::thread_t> worker_thread;
489489
std::atomic_bool raw_should_work;
490490

491491
std::weak_ptr<instance> link;

kernel/interfaces/system/bin/exec.cppm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export namespace bin::exec
3030
public:
3131
virtual ~image() = default;
3232

33-
virtual sched::thread_t *load(const request &req) const = 0;
33+
virtual std::shared_ptr<sched::thread_t> load(const request &req) const = 0;
3434

3535
virtual std::string_view format_name() const = 0;
3636
};

kernel/interfaces/system/proc/mutex.cppm

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export namespace sched
4545
lib::panic("mutex deadlock");
4646
}
4747

48-
_waiters.wait_unint();
48+
_waiters.wait_unkillable();
4949
}
5050
}
5151

@@ -67,7 +67,8 @@ export namespace sched
6767
lib::panic("mutex deadlock");
6868
}
6969

70-
if (_waiters.wait().interrupted)
70+
const auto res = _waiters.wait();
71+
if (res.interrupted || res.killed)
7172
return false;
7273
}
7374
}
@@ -121,7 +122,8 @@ export namespace sched
121122
if (now >= deadline)
122123
return false;
123124

124-
if (_waiters.wait(deadline - now).interrupted)
125+
const auto res = _waiters.wait(deadline - now);
126+
if (res.interrupted || res.killed)
125127
return false;
126128
}
127129
}
@@ -173,7 +175,7 @@ export namespace sched
173175
}
174176
}
175177

176-
_waiters.wait_unint();
178+
_waiters.wait_unkillable();
177179
}
178180
}
179181

@@ -200,7 +202,8 @@ export namespace sched
200202
}
201203
}
202204

203-
if (_waiters.wait().interrupted)
205+
const auto res = _waiters.wait();
206+
if (res.interrupted || res.killed)
204207
return false;
205208
}
206209
}
@@ -281,7 +284,8 @@ export namespace sched
281284
if (now >= deadline)
282285
return false;
283286

284-
if (_waiters.wait(deadline - now).interrupted)
287+
const auto res = _waiters.wait(deadline - now);
288+
if (res.interrupted || res.killed)
285289
return false;
286290
}
287291
}

kernel/interfaces/system/proc/process.cppm

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ export namespace sched
3333
root = 2
3434
};
3535

36-
struct process_t
36+
struct process_t : std::enable_shared_from_this<process_t>
3737
{
3838
pid_t pid;
3939

40-
process_t *parent;
40+
std::weak_ptr<process_t> parent;
4141

4242
lib::locker<
4343
lib::map::flat_hash<
4444
pid_t,
45-
process_t *
45+
std::shared_ptr<process_t>
4646
>, mutex
4747
> children;
4848

@@ -78,12 +78,11 @@ export namespace sched
7878
lib::locker<
7979
lib::map::flat_hash<
8080
pid_t,
81-
thread_t *
81+
std::shared_ptr<thread_t>
8282
>, mutex
8383
> threads;
8484

8585
std::atomic<std::size_t> alive_threads = 0;
86-
std::atomic<std::size_t> to_quiesce = 0;
8786

8887
std::atomic<dumpable_t> dumpable = dumpable_t::user;
8988

@@ -123,7 +122,7 @@ export namespace sched
123122
lib::locker<
124123
lib::map::flat_hash<
125124
pid_t,
126-
process_t *
125+
std::weak_ptr<process_t>
127126
>, mutex
128127
> members;
129128

kernel/interfaces/system/proc/run_queue.cppm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export namespace sched
4646
std::uint64_t nr_running;
4747

4848
thread_t *current;
49-
thread_t *idle;
49+
std::shared_ptr<thread_t> idle;
5050

5151
std::uint64_t nr_switches;
5252

kernel/interfaces/system/proc/scheduler.cppm

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ export namespace sched
104104
// called on yield, block, timer or wake up
105105
void schedule();
106106

107-
process_t *create_process(process_t *parent);
107+
std::shared_ptr<process_t> create_process(const std::shared_ptr<process_t> &parent);
108108

109109
// create a new kernel thread under pid 0
110-
thread_t *create_kthread(std::uintptr_t ip, std::uintptr_t arg, nice_t nice = default_nice);
110+
std::shared_ptr<thread_t> create_kthread(std::uintptr_t ip, std::uintptr_t arg, nice_t nice = default_nice);
111111

112112
// create a user thread
113-
thread_t *create_uthread(
114-
process_t *proc, std::uintptr_t ip, std::uintptr_t arg,
113+
std::shared_ptr<thread_t> create_uthread(
114+
const std::shared_ptr<process_t> &proc, std::uintptr_t ip, std::uintptr_t arg,
115115
bool is_trampoline, bool is_clone,
116116
std::uintptr_t stack, nice_t nice = default_nice
117117
);
@@ -120,17 +120,17 @@ export namespace sched
120120
void enqueue_new(thread_t *thread);
121121

122122
// create a new kernel thread and enqueue it
123-
thread_t *spawn(std::uintptr_t ip, std::uintptr_t arg = 0, nice_t nice = default_nice);
123+
std::shared_ptr<thread_t> spawn(std::uintptr_t ip, std::uintptr_t arg = 0, nice_t nice = default_nice);
124124

125125
template<typename Func>
126-
inline thread_t *spawn(Func &&func, std::uintptr_t arg = 0, nice_t nice = default_nice)
126+
inline std::shared_ptr<thread_t> spawn(Func &&func, std::uintptr_t arg = 0, nice_t nice = default_nice)
127127
{
128128
return spawn(reinterpret_cast<std::uintptr_t>(func), arg, nice);
129129
}
130130

131131
template<typename Func, typename Arg>
132132
requires (!std::convertible_to<Arg, std::uintptr_t>)
133-
inline thread_t *spawn(Func &&func, Arg arg, nice_t nice = default_nice)
133+
inline std::shared_ptr<thread_t> spawn(Func &&func, Arg arg, nice_t nice = default_nice)
134134
{
135135
return spawn(
136136
reinterpret_cast<std::uintptr_t>(func),
@@ -142,6 +142,9 @@ export namespace sched
142142

143143
bool yield();
144144

145+
void request_kill(thread_t *thread, int exit_code);
146+
void die_if_kill_pending();
147+
145148
// exit the current thread
146149
// if this is the last thread, process becomes a zombie
147150
[[noreturn]] void thread_exit(int exit_code);
@@ -153,12 +156,12 @@ export namespace sched
153156
// status reported to waitpid will have WIFSIGNALED set
154157
[[noreturn]] void process_exit_signal(int signo, bool core_dumped = false);
155158

156-
process_t *get_process(pid_t pid);
157-
thread_t *get_thread(pid_t tid);
159+
std::shared_ptr<process_t> get_process(pid_t pid);
160+
std::shared_ptr<thread_t> get_thread(pid_t tid);
158161

159162
std::size_t process_count();
160163

161-
void for_each_process(std::function<bool (process_t *)> func);
164+
void for_each_process(std::function<bool (const std::shared_ptr<process_t> &)> func);
162165

163166
// called from a timer interrupt
164167
void tick(bool from_user);

kernel/interfaces/system/proc/signal.cppm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ export namespace sched
281281
bool send_signal(thread_t *thread, const siginfo_t &info);
282282
bool send_signal(process_t *process, const siginfo_t &info);
283283

284+
bool signal_pending_for(thread_t *thread);
285+
284286
void flush_signal(process_t *proc, int sig);
285287

286288
void handle_pending_signals(cpu::registers *regs);

kernel/interfaces/system/proc/thread.cppm

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export namespace sched
3636
needs_resched = (1 << 2),
3737
interrupted = (1 << 3),
3838
signal_pending = (1 << 4),
39-
quiesce_pending = (1 << 5)
39+
kill_pending = (1 << 5)
4040
};
4141

4242
using namespace magic_enum::bitwise_operators;
@@ -63,6 +63,7 @@ export namespace sched
6363
std::atomic<thread_state> prev_state = thread_state::runnable;
6464
std::atomic<std::uint8_t> flags = 0;
6565
int exit_code = 0;
66+
std::atomic<int> pending_exit_code = 0;
6667

6768
std::uint64_t vruntime = 0;
6869
std::uint64_t total_runtime = 0;
@@ -76,16 +77,12 @@ export namespace sched
7677
void *on_rq = nullptr;
7778
lib::rbtree_hook<thread_t> hook;
7879

79-
lib::intrusive_list_hook<thread_t> dead_hook;
80-
8180
std::atomic_bool *was_in_interrupt = nullptr;
8281
lib::spinlock_irq *needs_unlock = nullptr;
8382

8483
std::atomic<wait_queue_t *> on_wait_queue = nullptr;
8584
std::atomic<wait_queue_entry_t *> wait_entry = nullptr;
8685

87-
std::atomic<bool> dead_listed = false;
88-
8986
std::atomic<bool> on_cpu = false;
9087
thread_t *prev_to_release = nullptr;
9188

kernel/interfaces/system/proc/wait_queue.cppm

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import std;
99

1010
export namespace sched
1111
{
12+
enum class wait_mode
13+
{
14+
interruptible, // woken by signals and kill
15+
killable, // woken by kill
16+
unkillable // uninterruptible
17+
};
18+
1219
struct wait_queue_entry_t
1320
{
1421
private:
@@ -56,14 +63,22 @@ export namespace sched
5663
{
5764
bool interrupted;
5865
bool expired;
66+
bool killed;
5967
};
6068

69+
private:
70+
wait_result_t wait_common(std::size_t gen, std::uint64_t ns, wait_mode mode);
71+
72+
public:
6173
wait_result_t wait(std::uint64_t ns = 0);
62-
wait_result_t wait_unint(std::uint64_t ns = 0);
74+
// ignores signals
75+
wait_result_t wait_killable(std::uint64_t ns = 0);
76+
wait_result_t wait_unkillable(std::uint64_t ns = 0);
6377

6478
std::size_t snapshot_gen() const;
6579
wait_result_t wait_prepared(std::size_t gen, std::uint64_t ns = 0);
66-
wait_result_t wait_unint_prepared(std::size_t gen, std::uint64_t ns = 0);
80+
wait_result_t wait_killable_prepared(std::size_t gen, std::uint64_t ns = 0);
81+
wait_result_t wait_unkillable_prepared(std::size_t gen, std::uint64_t ns = 0);
6782

6883
void wake_one(bool drop = false);
6984
void wake_all();

kernel/interfaces/system/syscall/proc.cppm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export namespace syscall::proc
7272
const sched::sigset_t __user *uthese, sched::siginfo_t __user *uinfo,
7373
const timespec __user *uts, std::size_t sigsetsize
7474
);
75+
int rt_sigsuspend(const sched::sigset_t __user *set, std::size_t sigsetsize);
7576
int sigaltstack(const sched::stack_t __user *ss, sched::stack_t __user *old_ss);
7677

7778
std::uintptr_t rt_sigreturn();

0 commit comments

Comments
 (0)