mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
scheduler: sched_stopotherthreads()
This commit is contained in:
@@ -80,6 +80,7 @@ typedef struct proc_t {
|
|||||||
extern proc_t *sched_initproc;
|
extern proc_t *sched_initproc;
|
||||||
|
|
||||||
void sched_init();
|
void sched_init();
|
||||||
|
void sched_stopotherthreads();
|
||||||
void sched_runinit();
|
void sched_runinit();
|
||||||
__attribute__((noreturn)) void sched_threadexit();
|
__attribute__((noreturn)) void sched_threadexit();
|
||||||
void sched_queue(thread_t *thread);
|
void sched_queue(thread_t *thread);
|
||||||
|
|||||||
@@ -253,6 +253,27 @@ __attribute__((noreturn)) void sched_threadexit() {
|
|||||||
sched_stopcurrentthread();
|
sched_stopcurrentthread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sched_stopotherthreads() {
|
||||||
|
thread_t *thread = _cpu()->thread;
|
||||||
|
proc_t *proc = thread->proc;
|
||||||
|
spinlock_acquire(&proc->lock);
|
||||||
|
proc->nomorethreads = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < proc->threadtablesize; ++i) {
|
||||||
|
if (proc->threads[i] == NULL || proc->threads[i] == thread)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
proc->threads[i]->shouldexit = true;
|
||||||
|
sched_wakeup(proc->threads[i], SCHED_WAKEUP_REASON_INTERRUPTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_release(&proc->lock);
|
||||||
|
|
||||||
|
while (__atomic_load_n(&proc->runningthreadcount, __ATOMIC_SEQ_CST) > 1) sched_yield();
|
||||||
|
|
||||||
|
proc->nomorethreads = false;
|
||||||
|
}
|
||||||
|
|
||||||
static void yield(context_t *context) {
|
static void yield(context_t *context) {
|
||||||
thread_t *thread = _cpu()->thread;
|
thread_t *thread = _cpu()->thread;
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ syscallret_t syscall_execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
|
|
||||||
ret.ret = 0;
|
ret.ret = 0;
|
||||||
|
|
||||||
// TODO kill other threads and close CLOEXEC fds
|
// close CLOEXEC fds
|
||||||
|
|
||||||
|
sched_stopotherthreads();
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(path);
|
free(path);
|
||||||
|
|||||||
@@ -11,21 +11,7 @@ __attribute__((noreturn)) void syscall_exit(context_t *context, int status) {
|
|||||||
__assert(proc != sched_initproc);
|
__assert(proc != sched_initproc);
|
||||||
__assert(spinlock_try(&proc->exiting)); // only one thread can exit at the same time
|
__assert(spinlock_try(&proc->exiting)); // only one thread can exit at the same time
|
||||||
|
|
||||||
// stop other threads
|
sched_stopotherthreads();
|
||||||
spinlock_acquire(&proc->lock);
|
|
||||||
proc->nomorethreads = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < proc->threadtablesize; ++i) {
|
|
||||||
if (proc->threads[i] == NULL || proc->threads[i] == thread)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
proc->threads[i]->shouldexit = true;
|
|
||||||
sched_wakeup(proc->threads[i], SCHED_WAKEUP_REASON_INTERRUPTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_release(&proc->lock);
|
|
||||||
|
|
||||||
while (__atomic_load_n(&proc->runningthreadcount, __ATOMIC_SEQ_CST) > 1) sched_yield();
|
|
||||||
|
|
||||||
// close fds
|
// close fds
|
||||||
for (int fd = 0; fd < proc->fdcount; ++fd)
|
for (int fd = 0; fd < proc->fdcount; ++fd)
|
||||||
|
|||||||
Reference in New Issue
Block a user