2021-10-30 15:30:19 +02:00
|
|
|
#include "process.h"
|
|
|
|
#include "alloc.h"
|
|
|
|
#include "irq.h"
|
|
|
|
#include "klibc.h"
|
|
|
|
#include "list.h"
|
|
|
|
#include "mmuContext.h"
|
2022-08-09 16:15:00 +02:00
|
|
|
#include "types.h"
|
2024-02-15 18:40:45 +01:00
|
|
|
#include "thread.h"
|
2022-08-07 23:14:26 +02:00
|
|
|
#include "uaddrspace.h"
|
2021-10-30 15:30:19 +02:00
|
|
|
|
|
|
|
struct process {
|
|
|
|
char name[PROCESS_NAME_MAX_LENGTH];
|
|
|
|
int ref;
|
2024-02-15 18:40:45 +01:00
|
|
|
pid_t pid;
|
|
|
|
pid_t nextTid;
|
2022-08-07 23:14:26 +02:00
|
|
|
struct uAddrSpace *addrSpace;
|
2021-10-30 15:30:19 +02:00
|
|
|
struct thread *thList;
|
|
|
|
|
|
|
|
struct process *prev, *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct process *processList;
|
|
|
|
static int nextPid;
|
|
|
|
|
|
|
|
int processSetup()
|
|
|
|
{
|
|
|
|
list_init(processList);
|
|
|
|
allocBookSlab(sizeof(struct process), PAGE_SIZE * 3, 0, 0);
|
|
|
|
nextPid = 0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct process *processCreate(char *name)
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
|
|
|
|
|
|
|
struct process *new = (struct process *)malloc(sizeof(struct process));
|
|
|
|
if (new == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2022-08-07 23:14:26 +02:00
|
|
|
new->addrSpace = uAddrSpaceCreate(new);
|
|
|
|
if(new->addrSpace == NULL){
|
2021-10-30 15:30:19 +02:00
|
|
|
free(new);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
strzcpy(new->name, name, PROCESS_NAME_MAX_LENGTH);
|
|
|
|
new->ref = 1;
|
|
|
|
|
|
|
|
disable_IRQs(flags);
|
2024-02-14 23:20:46 +01:00
|
|
|
new->pid = nextPid++;
|
|
|
|
new->nextTid = new->pid;
|
2021-10-30 15:30:19 +02:00
|
|
|
list_add_tail(processList, new);
|
|
|
|
restore_IRQs(flags);
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
void processListPrint()
|
|
|
|
{
|
|
|
|
struct process *proc;
|
|
|
|
int nbProcs;
|
|
|
|
struct thread *cur = getCurrentThread();
|
|
|
|
|
|
|
|
printf("PID NAME NBTHREAD REF\n");
|
|
|
|
list_foreach(processList, proc, nbProcs)
|
|
|
|
{
|
|
|
|
struct thread *th;
|
|
|
|
int nbTh;
|
|
|
|
|
2024-02-15 18:40:45 +01:00
|
|
|
printf("%lu %s %d %d\n", proc->pid, proc->name, processCountThread(proc), proc->ref);
|
2021-10-30 15:30:19 +02:00
|
|
|
list_foreach_named(proc->thList, th, nbTh, prevInProcess, nextInProcess)
|
|
|
|
{
|
|
|
|
if (th == cur) {
|
2023-11-09 20:30:09 +01:00
|
|
|
printf(" th: 0x%lx Current\n", (vaddr_t)th);
|
2021-10-30 15:30:19 +02:00
|
|
|
} else {
|
2023-11-09 20:30:09 +01:00
|
|
|
printf(" th: 0x%lx in 0x%lx\n", (vaddr_t)th, cpu_context_get_PC(th->cpuState));
|
2021-10-30 15:30:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int processCountThread(struct process *proc)
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
struct thread *th;
|
|
|
|
|
|
|
|
list_foreach_named(proc->thList, th, count, prevInProcess, nextInProcess) {}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
int processRef(struct process *proc)
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
|
|
|
// ref == 0 -> delete
|
|
|
|
assert(proc->ref > 0);
|
|
|
|
|
|
|
|
disable_IRQs(flags);
|
|
|
|
proc->ref++;
|
|
|
|
restore_IRQs(flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int processUnref(struct process *proc)
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
2022-08-07 23:14:26 +02:00
|
|
|
int ret;
|
2021-10-30 15:30:19 +02:00
|
|
|
|
|
|
|
assert(proc->ref > 0);
|
|
|
|
|
|
|
|
disable_IRQs(flags);
|
|
|
|
|
|
|
|
proc->ref--;
|
|
|
|
if (proc->ref > 0) {
|
|
|
|
restore_IRQs(flags);
|
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
list_delete(processList, proc);
|
|
|
|
restore_IRQs(flags);
|
|
|
|
|
2022-08-07 23:14:26 +02:00
|
|
|
ret = uAddrSpaceDelete(proc->addrSpace);
|
2021-10-30 15:30:19 +02:00
|
|
|
free(proc);
|
|
|
|
|
2022-08-07 23:14:26 +02:00
|
|
|
return ret;
|
2021-10-30 15:30:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int processAddThread(struct process *proc, struct thread *th)
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
|
|
|
|
|
|
|
assert(proc->ref > 0);
|
|
|
|
|
|
|
|
th->process = proc;
|
|
|
|
|
|
|
|
disable_IRQs(flags);
|
|
|
|
processRef(proc);
|
|
|
|
list_add_tail_named(proc->thList, th, prevInProcess, nextInProcess);
|
|
|
|
|
|
|
|
restore_IRQs(flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int processRemoveThread(struct thread *th)
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
|
|
|
struct process *proc;
|
|
|
|
|
|
|
|
disable_IRQs(flags);
|
|
|
|
proc = th->process;
|
|
|
|
|
|
|
|
list_delete_named(proc->thList, th, prevInProcess, nextInProcess);
|
|
|
|
restore_IRQs(flags);
|
|
|
|
processUnref(proc);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int processSetName(struct process *proc, char *name)
|
|
|
|
{
|
|
|
|
assert(name != NULL);
|
|
|
|
strzcpy(proc->name, name, PROCESS_NAME_MAX_LENGTH);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2021-11-02 21:24:12 +01:00
|
|
|
|
2024-01-26 22:23:58 +01:00
|
|
|
char *processGetName(struct process *proc){
|
|
|
|
return proc->name;
|
|
|
|
}
|
|
|
|
|
2021-11-02 21:24:12 +01:00
|
|
|
struct mmu_context *processGetMMUContext(struct process *proc)
|
|
|
|
{
|
2022-08-07 23:14:26 +02:00
|
|
|
return uAddrSpaceGetMMUContext(proc->addrSpace);
|
2021-11-02 21:24:12 +01:00
|
|
|
}
|
2022-08-09 16:15:00 +02:00
|
|
|
|
|
|
|
struct uAddrSpace *processGetAddrSpace(struct process *proc){
|
|
|
|
return proc->addrSpace;
|
|
|
|
}
|
|
|
|
|
|
|
|
int processInitHeap(struct process *proc, uaddr_t lastUserAddr){
|
|
|
|
return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0);
|
|
|
|
}
|
2024-02-14 23:20:46 +01:00
|
|
|
|
2024-02-15 18:40:45 +01:00
|
|
|
pid_t processGetId(struct process *proc){
|
2024-02-14 23:20:46 +01:00
|
|
|
return proc->pid;
|
|
|
|
}
|
|
|
|
|
2024-02-15 18:40:45 +01:00
|
|
|
pid_t processGetNextTid(struct process *proc){
|
2024-02-14 23:20:46 +01:00
|
|
|
return proc->nextTid++;
|
|
|
|
}
|
2024-02-16 00:40:48 +01:00
|
|
|
|
|
|
|
//Should be called with IRQ disabled
|
|
|
|
struct thread *processGetThread(struct process *proc, pid_t tid)
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
struct thread *th;
|
|
|
|
struct thread *thFound = NULL;
|
|
|
|
|
|
|
|
list_foreach_named(proc->thList, th, count, prevInProcess, nextInProcess)
|
|
|
|
{
|
|
|
|
if (th->tid == tid) {
|
|
|
|
thFound = th;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return thFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
int processJoinThread(struct process *proc, pid_t tid)
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
|
|
|
struct thread *th;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
disable_IRQs(flags);
|
|
|
|
|
|
|
|
th = processGetThread(proc, tid);
|
|
|
|
if (th && th->wqExit) {
|
|
|
|
wait(th->wqExit);
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
restore_IRQs(flags);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|