scheduler: pid refcount

This commit is contained in:
Matheus
2024-04-28 18:45:43 -03:00
parent 8deb3a1144
commit e0c2cd9a2a
4 changed files with 38 additions and 2 deletions
+10
View File
@@ -46,10 +46,12 @@ typedef struct thread_t {
spinlock_t sleeplock;
int wakeupreason;
bool shouldexit;
void *kernelarg;
} thread_t;
typedef struct proc_t {
spinlock_t lock;
int refcount;
int status;
int state;
struct proc_t *sibling;
@@ -77,6 +79,13 @@ typedef struct proc_t {
#include <arch/cpu.h>
#define UMASK(mode) ((mode) & ~_cpu()->thread->proc->umask)
#define PROC_HOLD(v) __atomic_add_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST)
#define PROC_RELEASE(v) {\
if (__atomic_sub_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST) == 0) {\
sched_inactiveproc(v); \
(v) = NULL; \
} \
}
extern proc_t *sched_initproc;
@@ -101,5 +110,6 @@ void sched_destroythread(thread_t *);
void sched_targetcpu(struct cpu_t *cpu);
void sched_sleepus(size_t us);
void sched_apentry();
void sched_inactiveproc(proc_t *proc);
#endif
+24 -1
View File
@@ -51,6 +51,7 @@ proc_t *sched_newproc() {
SPINLOCK_INIT(proc->lock);
SPINLOCK_INIT(proc->nodeslock);
proc->fdcount = 3;
proc->refcount = 1;
proc->fdfirst = 3;
SPINLOCK_INIT(proc->fdlock);
SEMAPHORE_INIT(&proc->waitsem, 0);
@@ -87,8 +88,11 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int priority, proc_t *pro
thread->vmmctx = proc ? NULL : &vmm_kernelctx;
thread->proc = proc;
thread->priority = priority;
if (proc)
if (proc) {
// each thread holds one reference to proc
PROC_HOLD(proc);
thread->tid = __atomic_fetch_add(&currpid, 1, __ATOMIC_SEQ_CST);
}
CTX_INIT(&thread->context, proc != NULL, true);
@@ -229,9 +233,15 @@ __attribute__((noreturn)) void sched_stopcurrentthread() {
switchthread(next);
}
// called when all threads in a process have exited
void sched_procexit() {
proc_t *proc = _cpu()->thread->proc;
// the process is going to be referenced by the child list, hold it
// it only holds it now because it has to have running threads to be in the list
// which hold a reference. it won't now since its a zombie, which is why it will be held
PROC_HOLD(proc);
// close fds
for (int fd = 0; fd < proc->fdcount; ++fd)
fd_close(fd);
@@ -245,6 +255,7 @@ void sched_procexit() {
proc->state = SCHED_PROC_STATE_ZOMBIE;
proc_t *lastchild = proc->child;
spinlock_acquire(&sched_initproc->lock);
bool haszombie = false;
@@ -270,6 +281,14 @@ void sched_procexit() {
semaphore_signal(&sched_initproc->waitsem);
}
void sched_inactiveproc(proc_t *proc) {
// proc refcount 0, we can free the structure
// TODO remove from the pid list
printf("destroying proc!\n");
sched_destroyproc(proc);
}
static void threadexit_internal(context_t *) {
thread_t *thread = _cpu()->thread;
// we don't need to access the current thread anymore, as any state will be ignored and we are running on the scheduler stack
@@ -301,6 +320,7 @@ __attribute__((noreturn)) void sched_threadexit() {
sched_procexit();
vmm_destroycontext(oldctx);
PROC_RELEASE(proc);
}
}
@@ -628,8 +648,11 @@ void sched_runinit() {
thread_t *uthread = sched_newthread(entry, PAGE_SIZE * 16, 1, proc, stack);
__assert(uthread);
uthread->vmmctx = vmmctx;
sched_queue(uthread);
VOP_RELEASE(initnode);
// proc starts with 1 refcount, release it here as to only have the thread reference
PROC_RELEASE(proc);
}
+2
View File
@@ -57,6 +57,8 @@ syscallret_t syscall_fork(context_t *ctx) {
ret.ret = nproc->pid;
sched_queue(nthread);
// proc starts with 1 refcount, release it here as to only have the thread reference
PROC_RELEASE(nproc);
cleanup:
return ret;
+2 -1
View File
@@ -75,6 +75,7 @@ syscallret_t syscall_waitpid(context_t *context, pid_t pid, int *status, int opt
ret.errno = 0;
__assert(iterator);
sched_destroyproc(iterator);
// process will no longer be referenced by the child list
PROC_RELEASE(iterator);
return ret;
}