can haz threads?
This commit is contained in:
parent
cffbb02240
commit
4453aba2de
@ -64,7 +64,7 @@ DECL_SYSCALL3(lseek, int, int, int);
|
||||
DECL_SYSCALL2(stat, const char *, void *);
|
||||
|
||||
/* Process Control */
|
||||
DECL_SYSCALL0(getpid);
|
||||
DECL_SYSCALL0(sys_getpid);
|
||||
DECL_SYSCALL3(execve, char *, char **, char **);
|
||||
DECL_SYSCALL0(fork);
|
||||
DECL_SYSCALL2(kill, int, int);
|
||||
|
@ -257,7 +257,7 @@ extern void switch_task(uint8_t reschedule);
|
||||
extern void switch_from_cross_thread_lock();
|
||||
extern void switch_next();
|
||||
extern uint32_t fork();
|
||||
extern uint32_t clone(uintptr_t new_stack, uintptr_t old_stack);
|
||||
extern uint32_t clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg);
|
||||
extern uint32_t getpid();
|
||||
extern void enter_user_jmp(uintptr_t location, int argc, char ** argv, uintptr_t stack);
|
||||
|
||||
|
@ -22,6 +22,8 @@ typedef struct page_directory {
|
||||
page_table_t *tables[1024]; /* 1024 pointers to page tables... */
|
||||
uintptr_t physical_tables[1024]; /* Physical addresses of the tables */
|
||||
uintptr_t physical_address; /* The physical address of physical_tables */
|
||||
|
||||
int32_t ref_count;
|
||||
} page_directory_t;
|
||||
|
||||
|
||||
|
@ -150,6 +150,7 @@ process_t * spawn_init() {
|
||||
* of the process' entry in the process tree. */
|
||||
init->tree_entry = process_tree->root;
|
||||
init->id = 0; /* Init is PID 1 */
|
||||
init->group = 0;
|
||||
init->name = "init"; /* Um, duh. */
|
||||
init->user = 0; /* UID 0 */
|
||||
init->group = 0; /* Task group 0 */
|
||||
@ -224,6 +225,7 @@ process_t * spawn_process(volatile process_t * parent) {
|
||||
/* Allocate a new process */
|
||||
process_t * proc = malloc(sizeof(process_t));
|
||||
proc->id = get_next_pid(); /* Set its PID */
|
||||
proc->group = proc->id; /* Set the GID */
|
||||
proc->name = default_name; /* Use the default name */
|
||||
proc->description = NULL; /* No description */
|
||||
|
||||
|
@ -163,6 +163,11 @@ static int sys_sbrk(int size) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sys_getpid() {
|
||||
/* The user actually wants the pid of the originating thread (which can be us). */
|
||||
return current_process->group;
|
||||
}
|
||||
|
||||
static int execve(const char * filename, char *const argv[], char *const envp[]) {
|
||||
validate((void *)argv);
|
||||
validate((void *)filename);
|
||||
@ -489,7 +494,7 @@ static uintptr_t syscalls[] = {
|
||||
(uintptr_t)&gettimeofday,
|
||||
(uintptr_t)&execve,
|
||||
(uintptr_t)&fork, /* 8 */
|
||||
(uintptr_t)&getpid,
|
||||
(uintptr_t)&sys_getpid,
|
||||
(uintptr_t)&sys_sbrk,
|
||||
(uintptr_t)&getgraphicsaddress,
|
||||
(uintptr_t)&kbd_mode, /* 12 */
|
||||
|
@ -29,6 +29,8 @@ clone_directory(
|
||||
page_directory_t * dir = (page_directory_t *)kvmalloc_p(sizeof(page_directory_t), &phys);
|
||||
/* Clear it out */
|
||||
memset(dir, 0, sizeof(page_directory_t));
|
||||
dir->ref_count = 1;
|
||||
|
||||
/* Calculate the physical address offset */
|
||||
uintptr_t offset = (uintptr_t)dir->physical_tables - (uintptr_t)dir;
|
||||
/* And store it... */
|
||||
@ -56,22 +58,26 @@ clone_directory(
|
||||
/*
|
||||
* Free a directory and its tables
|
||||
*/
|
||||
void free_directory(page_directory_t * dir) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < 1024; ++i) {
|
||||
if (!dir->tables[i] || (uintptr_t)dir->tables[i] == (uintptr_t)0xFFFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
if (kernel_directory->tables[i] != dir->tables[i]) {
|
||||
for (uint32_t j = 0; j < 1024; ++j) {
|
||||
if (dir->tables[i]->pages[j].frame) {
|
||||
free_frame(&(dir->tables[i]->pages[j]));
|
||||
}
|
||||
void release_directory(page_directory_t * dir) {
|
||||
dir->ref_count--;
|
||||
|
||||
if (dir->ref_count < 1) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < 1024; ++i) {
|
||||
if (!dir->tables[i] || (uintptr_t)dir->tables[i] == (uintptr_t)0xFFFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
if (kernel_directory->tables[i] != dir->tables[i]) {
|
||||
for (uint32_t j = 0; j < 1024; ++j) {
|
||||
if (dir->tables[i]->pages[j].frame) {
|
||||
free_frame(&(dir->tables[i]->pages[j]));
|
||||
}
|
||||
}
|
||||
free(dir->tables[i]);
|
||||
}
|
||||
free(dir->tables[i]);
|
||||
}
|
||||
free(dir);
|
||||
}
|
||||
free(dir);
|
||||
}
|
||||
|
||||
void reap_process(process_t * proc) {
|
||||
@ -80,7 +86,7 @@ void reap_process(process_t * proc) {
|
||||
list_free(proc->signal_queue);
|
||||
free(proc->signal_queue);
|
||||
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
|
||||
free_directory(proc->thread.page_directory);
|
||||
release_directory(proc->thread.page_directory);
|
||||
free((void *)(proc->fds.entries));
|
||||
|
||||
shm_release_all(proc);
|
||||
@ -238,7 +244,7 @@ fork() {
|
||||
* memory space with the given pointer as its new stack.
|
||||
*/
|
||||
uint32_t
|
||||
clone(uintptr_t stack_top, uintptr_t stack_old) {
|
||||
clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) {
|
||||
unsigned int magic = TASK_MAGIC;
|
||||
uintptr_t esp, ebp, eip;
|
||||
|
||||
@ -255,6 +261,7 @@ clone(uintptr_t stack_top, uintptr_t stack_old) {
|
||||
assert(new_proc && "Could not allocate a new process!");
|
||||
/* Set the new process' page directory to the original process' */
|
||||
set_process_environment(new_proc, directory);
|
||||
directory->ref_count++;
|
||||
/* Read the instruction pointer */
|
||||
eip = read_eip();
|
||||
|
||||
@ -282,6 +289,19 @@ clone(uintptr_t stack_top, uintptr_t stack_old) {
|
||||
uintptr_t offset = ((uintptr_t)current_process->syscall_registers - o_stack);
|
||||
new_proc->syscall_registers = (struct regs *)(n_stack + offset);
|
||||
|
||||
/* Set the gid */
|
||||
new_proc->group = current_process->group;
|
||||
|
||||
/* Push arg, bogus return address onto the new thread's stack */
|
||||
new_stack -= sizeof(uintptr_t);
|
||||
*((uintptr_t *)new_stack) = arg;
|
||||
new_stack -= sizeof(uintptr_t);
|
||||
*((uintptr_t *)new_stack) = THREAD_RETURN;
|
||||
|
||||
/* Set esp, ebp, and eip for the new thread */
|
||||
new_proc->syscall_registers->esp = new_stack;
|
||||
new_proc->syscall_registers->ebp = new_stack;
|
||||
new_proc->syscall_registers->eip = thread_func;
|
||||
|
||||
/* Set the new process instruction pointer (to the return from read_eip) */
|
||||
new_proc->thread.eip = eip;
|
||||
@ -291,7 +311,7 @@ clone(uintptr_t stack_top, uintptr_t stack_old) {
|
||||
/* Return the child PID */
|
||||
return new_proc->id;
|
||||
} else {
|
||||
assert(magic == TASK_MAGIC && "Bad process fork magic (child clone)!");
|
||||
assert(magic == TASK_MAGIC && "Bad process clone magic (child clone)!");
|
||||
/* Child fork is complete, return */
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user