Compare commits
5 Commits
389f250d0b
...
9ddde68449
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ddde68449 | |||
| 1b2063115a | |||
| e69606668d | |||
| 85872b856b | |||
| b571e2dbd3 |
21
ce/ce.c
21
ce/ce.c
@@ -72,16 +72,15 @@ static void cmd_cat (struct list_node_link* tokens) {
|
||||
struct list_node_link *token_link, *token_tmp_link;
|
||||
list_foreach (tokens, token_link, token_tmp_link) {
|
||||
struct token* token = list_entry (token_link, struct token, tokens_link);
|
||||
int ret;
|
||||
|
||||
ret = open (token->buffer);
|
||||
int handle = open (token->buffer);
|
||||
|
||||
if (ret < 0) {
|
||||
printf ("ERROR opening %s: %s\n", token->buffer, str_status[-ret]);
|
||||
if (handle < 0) {
|
||||
printf ("ERROR opening %s: %s\n", token->buffer, str_status[-handle]);
|
||||
continue;
|
||||
}
|
||||
|
||||
describe (token->buffer, &desc);
|
||||
describe (handle, &desc);
|
||||
|
||||
if (desc.type != FS_FILE)
|
||||
goto close1;
|
||||
@@ -92,21 +91,13 @@ static void cmd_cat (struct list_node_link* tokens) {
|
||||
goto close1;
|
||||
|
||||
memset (buffer, 0, desc.size + 1);
|
||||
|
||||
ret = read (token->buffer, 0, (uint8_t*)buffer, desc.size);
|
||||
|
||||
if (ret < 0) {
|
||||
printf ("ERROR reading%s: %s\n", token->buffer, str_status[-ret]);
|
||||
goto close1;
|
||||
}
|
||||
|
||||
read (handle, 0, (uint8_t*)buffer, desc.size);
|
||||
printf ("%s\n", buffer);
|
||||
|
||||
close1:
|
||||
if (buffer != NULL)
|
||||
free (buffer);
|
||||
|
||||
close (token->buffer);
|
||||
close (handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ struct proc* proc_from_elf (uint8_t* elf_contents) {
|
||||
memset (proc, 0, sizeof (*proc));
|
||||
|
||||
proc->lock = SPIN_LOCK_INIT;
|
||||
atomic_store (&proc->state, PROC_READY);
|
||||
proc->state = PROC_READY;
|
||||
proc->pid = atomic_fetch_add (&pids, 1);
|
||||
|
||||
proc->procgroup = procgroup_create ();
|
||||
@@ -71,7 +71,7 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent
|
||||
memset (proc, 0, sizeof (*proc));
|
||||
|
||||
proc->lock = SPIN_LOCK_INIT;
|
||||
atomic_store (&proc->state, PROC_READY);
|
||||
proc->state = PROC_READY;
|
||||
proc->pid = atomic_fetch_add (&pids, 1);
|
||||
|
||||
spin_lock (&proto->lock);
|
||||
|
||||
@@ -58,13 +58,22 @@ struct cpu* cpu_find_lightest (void) {
|
||||
struct limine_mp_response* mp = limine_mp_request.response;
|
||||
|
||||
int start = atomic_fetch_add (&last_cpu_index, 1) % mp->cpu_count;
|
||||
|
||||
struct cpu* best_cpu = &cpus[start];
|
||||
int best_load = atomic_load (&best_cpu->proc_run_q_count);
|
||||
|
||||
spin_lock (&best_cpu->lock);
|
||||
int best_load = best_cpu->proc_run_q_count;
|
||||
spin_unlock (&best_cpu->lock);
|
||||
|
||||
for (int i = 1; i < (int)mp->cpu_count; i++) {
|
||||
int idx = (start + i) % mp->cpu_count;
|
||||
|
||||
struct cpu* cpu = &cpus[idx];
|
||||
int l = atomic_load (&cpu->proc_run_q_count);
|
||||
|
||||
spin_lock (&cpu->lock);
|
||||
int l = cpu->proc_run_q_count;
|
||||
spin_unlock (&cpu->lock);
|
||||
|
||||
if (l < best_load) {
|
||||
best_load = l;
|
||||
best_cpu = cpu;
|
||||
|
||||
@@ -32,7 +32,7 @@ struct cpu {
|
||||
|
||||
struct list_node_link* proc_run_q;
|
||||
struct proc* proc_current;
|
||||
atomic_int proc_run_q_count;
|
||||
int proc_run_q_count;
|
||||
};
|
||||
|
||||
struct cpu* cpu_make (uint64_t lapic_id, uint64_t acpi_id);
|
||||
|
||||
165
kernel/fs/vfs.c
165
kernel/fs/vfs.c
@@ -46,7 +46,6 @@ int vfs_create_mountpoint (const char* key, int fs_type, struct device* back_dev
|
||||
|
||||
memcpy (mountpoint->key, key, strlen_null (key));
|
||||
mountpoint->fs_type = fs_type;
|
||||
mountpoint->lock = SPIN_LOCK_INIT;
|
||||
mountpoint->back_device = back_device;
|
||||
|
||||
switch (mountpoint->fs_type) {
|
||||
@@ -81,111 +80,137 @@ int vfs_create_mountpoint (const char* key, int fs_type, struct device* back_dev
|
||||
}
|
||||
|
||||
int vfs_open (struct procgroup* procgroup, const char* mountpoint, const char* path) {
|
||||
(void)path;
|
||||
|
||||
struct vfs_mountpoint* vmp = vfs_find_mountpoint (mountpoint);
|
||||
|
||||
if (vmp == NULL)
|
||||
return -ST_NOT_FOUND;
|
||||
|
||||
spin_lock (&vmp->lock);
|
||||
struct vfs_handle* handle = malloc (sizeof (*handle));
|
||||
|
||||
vmp->ownerpg = procgroup;
|
||||
vmp->locked = true;
|
||||
if (handle == NULL)
|
||||
return -ST_OOM_ERROR;
|
||||
|
||||
spin_unlock (&vmp->lock);
|
||||
memset (handle, 0, sizeof (*handle));
|
||||
handle->mountpoint = vmp;
|
||||
handle->ownerpg = procgroup;
|
||||
strncpy (handle->path, path, sizeof (handle->path));
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
|
||||
int id = handle->id = procgroup->sys_vfs_handles++;
|
||||
|
||||
rbtree_insert (struct vfs_handle, &procgroup->vfs_handle_tree, &handle->handle_tree_link,
|
||||
handle_tree_link, id);
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
int vfs_close (struct procgroup* procgroup, int id) {
|
||||
struct vfs_handle* handle = NULL;
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
|
||||
rbtree_find (struct vfs_handle, &procgroup->vfs_handle_tree, id, handle, handle_tree_link, id);
|
||||
|
||||
if (handle == NULL) {
|
||||
spin_unlock (&procgroup->lock);
|
||||
return -ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
rbtree_delete (&procgroup->vfs_handle_tree, &handle->handle_tree_link);
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
|
||||
free (handle);
|
||||
|
||||
return ST_OK;
|
||||
}
|
||||
|
||||
int vfs_close (struct procgroup* procgroup, const char* mountpoint, const char* path) {
|
||||
(void)path;
|
||||
int vfs_describe (struct procgroup* procgroup, int id, struct desc* desc) {
|
||||
struct vfs_handle* handle = NULL;
|
||||
|
||||
struct vfs_mountpoint* vmp = vfs_find_mountpoint (mountpoint);
|
||||
spin_lock (&procgroup->lock);
|
||||
|
||||
if (vmp == NULL)
|
||||
rbtree_find (struct vfs_handle, &procgroup->vfs_handle_tree, id, handle, handle_tree_link, id);
|
||||
|
||||
if (handle == NULL) {
|
||||
spin_unlock (&procgroup->lock);
|
||||
return -ST_NOT_FOUND;
|
||||
|
||||
spin_lock (&vmp->lock);
|
||||
|
||||
if (procgroup != NULL && vmp->ownerpg != procgroup) {
|
||||
spin_unlock (&vmp->lock);
|
||||
return -ST_PERMISSION_ERROR;
|
||||
}
|
||||
|
||||
vmp->locked = false;
|
||||
vmp->ownerpg = NULL;
|
||||
spin_unlock (&procgroup->lock);
|
||||
|
||||
spin_unlock (&vmp->lock);
|
||||
|
||||
return ST_OK;
|
||||
}
|
||||
|
||||
int vfs_describe (struct procgroup* procgroup, const char* mountpoint, const char* path,
|
||||
struct desc* desc) {
|
||||
struct vfs_mountpoint* vmp = vfs_find_mountpoint (mountpoint);
|
||||
|
||||
if (vmp == NULL)
|
||||
return -ST_NOT_FOUND;
|
||||
|
||||
spin_lock (&vmp->lock);
|
||||
|
||||
if ((procgroup != NULL && vmp->ownerpg != procgroup) && vmp->locked) {
|
||||
spin_unlock (&vmp->lock);
|
||||
return -ST_PERMISSION_ERROR;
|
||||
}
|
||||
|
||||
int ret = vmp->driver_ops.describe (vmp, path, desc);
|
||||
|
||||
spin_unlock (&vmp->lock);
|
||||
spin_lock (&handle->lock);
|
||||
int ret = handle->mountpoint->driver_ops.describe (handle->mountpoint, handle->path, desc);
|
||||
spin_unlock (&handle->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfs_read (struct procgroup* procgroup, const char* mountpoint, const char* path,
|
||||
uint8_t* buffer, size_t off, size_t size) {
|
||||
int vfs_read (struct procgroup* procgroup, int id, uint8_t* buffer, size_t off, size_t size) {
|
||||
struct vfs_handle* handle = NULL;
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
|
||||
rbtree_find (struct vfs_handle, &procgroup->vfs_handle_tree, id, handle, handle_tree_link, id);
|
||||
|
||||
if (handle == NULL) {
|
||||
spin_unlock (&procgroup->lock);
|
||||
return -ST_NOT_FOUND;
|
||||
}
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
|
||||
spin_lock (&handle->lock);
|
||||
int ret =
|
||||
handle->mountpoint->driver_ops.read (handle->mountpoint, handle->path, buffer, off, size);
|
||||
spin_unlock (&handle->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfs_kernel_read (const char* mountpoint, const char* path, uint8_t* buffer, size_t off,
|
||||
size_t size) {
|
||||
struct vfs_mountpoint* vmp = vfs_find_mountpoint (mountpoint);
|
||||
|
||||
if (vmp == NULL)
|
||||
return -ST_NOT_FOUND;
|
||||
|
||||
spin_lock (&vmp->lock);
|
||||
return vmp->driver_ops.read (vmp, path, buffer, off, size);
|
||||
}
|
||||
|
||||
if ((procgroup != NULL && vmp->ownerpg != procgroup) && vmp->locked) {
|
||||
spin_unlock (&vmp->lock);
|
||||
return -ST_PERMISSION_ERROR;
|
||||
}
|
||||
int vfs_kernel_describe (const char* mountpoint, const char* path, struct desc* desc) {
|
||||
struct vfs_mountpoint* vmp = vfs_find_mountpoint (mountpoint);
|
||||
|
||||
int ret = vmp->driver_ops.read (vmp, path, buffer, off, size);
|
||||
if (vmp == NULL)
|
||||
return -ST_NOT_FOUND;
|
||||
|
||||
spin_unlock (&vmp->lock);
|
||||
|
||||
return ret;
|
||||
return vmp->driver_ops.describe (vmp, path, desc);
|
||||
}
|
||||
|
||||
void vfs_procgroup_cleanup (struct procgroup* procgroup) {
|
||||
spin_lock (&mount_table.lock);
|
||||
struct list_node_link* handle_cleanup_list = NULL;
|
||||
struct vfs_handle* handle;
|
||||
|
||||
for (size_t i = 0; i < lengthof (mount_table.mountpoint_buckets); i++) {
|
||||
struct hash_node_link* link = mount_table.mountpoint_buckets[i];
|
||||
struct rb_node_link* node;
|
||||
rbtree_first (&procgroup->vfs_handle_tree, node);
|
||||
|
||||
while (link != NULL) {
|
||||
struct vfs_mountpoint* vmp = hash_entry (link, struct vfs_mountpoint, mount_table_link);
|
||||
|
||||
spin_lock (&vmp->lock);
|
||||
|
||||
if (vmp->ownerpg == procgroup) {
|
||||
vmp->locked = false;
|
||||
vmp->ownerpg = NULL;
|
||||
}
|
||||
|
||||
spin_unlock (&vmp->lock);
|
||||
|
||||
link = link->next;
|
||||
}
|
||||
while (node != NULL) {
|
||||
struct rb_node_link* next;
|
||||
rbtree_next (node, next);
|
||||
handle = rbtree_entry (node, struct vfs_handle, handle_tree_link);
|
||||
node = next;
|
||||
list_append (handle_cleanup_list, &handle->handle_cleanup_link);
|
||||
}
|
||||
|
||||
spin_unlock (&mount_table.lock);
|
||||
struct list_node_link *cleanup_link, *cleanup_tmp_link;
|
||||
list_foreach (handle_cleanup_list, cleanup_link, cleanup_tmp_link) {
|
||||
handle = list_entry (cleanup_link, struct vfs_handle, handle_cleanup_link);
|
||||
list_remove (handle_cleanup_list, &handle->handle_cleanup_link);
|
||||
free (handle);
|
||||
}
|
||||
}
|
||||
|
||||
void vfs_init (void) {
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include <device/device.h>
|
||||
#include <libk/hash.h>
|
||||
#include <libk/list.h>
|
||||
#include <libk/rbtree.h>
|
||||
#include <libk/std.h>
|
||||
#include <path.h>
|
||||
#include <proc/proc.h>
|
||||
#include <proc/procgroup.h>
|
||||
#include <proc/reschedule.h>
|
||||
@@ -13,13 +15,22 @@
|
||||
|
||||
#define VFS_TARFS 0
|
||||
|
||||
struct vfs_mountpoint;
|
||||
|
||||
struct vfs_handle {
|
||||
int id;
|
||||
struct vfs_mountpoint* mountpoint;
|
||||
char path[MAX_PATH];
|
||||
struct procgroup* ownerpg;
|
||||
struct rb_node_link handle_tree_link;
|
||||
struct list_node_link handle_cleanup_link;
|
||||
spin_lock_t lock;
|
||||
};
|
||||
|
||||
struct vfs_mountpoint {
|
||||
char key[0x100];
|
||||
struct hash_node_link mount_table_link;
|
||||
int fs_type;
|
||||
spin_lock_t lock;
|
||||
bool locked;
|
||||
struct procgroup* ownerpg;
|
||||
struct {
|
||||
int (*mount) (struct vfs_mountpoint* mountpoint, struct proc* proc,
|
||||
struct reschedule_ctx* rctx);
|
||||
@@ -41,16 +52,19 @@ struct vfs_mount_table {
|
||||
int vfs_create_mountpoint (const char* key, int fs_type, struct device* back_device,
|
||||
struct proc* proc, struct reschedule_ctx* rctx);
|
||||
|
||||
int vfs_describe (struct procgroup* procgroup, const char* mountpoint, const char* path,
|
||||
struct desc* desc);
|
||||
int vfs_describe (struct procgroup* procgroup, int id, struct desc* desc);
|
||||
|
||||
int vfs_read (struct procgroup* procgroup, const char* mountpoint, const char* path,
|
||||
uint8_t* buffer, size_t off, size_t size);
|
||||
int vfs_read (struct procgroup* procgroup, int id, uint8_t* buffer, size_t off, size_t size);
|
||||
|
||||
int vfs_close (struct procgroup* procgroup, const char* mountpoint, const char* path);
|
||||
int vfs_close (struct procgroup* procgroup, int id);
|
||||
|
||||
int vfs_open (struct procgroup* procgroup, const char* mountpoint, const char* path);
|
||||
|
||||
int vfs_kernel_read (const char* mountpoint, const char* path, uint8_t* buffer, size_t off,
|
||||
size_t size);
|
||||
|
||||
int vfs_kernel_describe (const char* mountpoint, const char* path, struct desc* desc);
|
||||
|
||||
void vfs_procgroup_cleanup (struct procgroup* procgroup);
|
||||
|
||||
void vfs_init (void);
|
||||
|
||||
@@ -108,47 +108,73 @@ struct proc* proc_from_file (struct procgroup* procgroup, const char* mountpoint
|
||||
const char* path) {
|
||||
struct desc desc;
|
||||
|
||||
if (vfs_open (procgroup, mountpoint, path) != ST_OK)
|
||||
return NULL;
|
||||
if (procgroup == NULL) {
|
||||
if (vfs_kernel_describe (mountpoint, path, &desc) < 0)
|
||||
return NULL;
|
||||
|
||||
if (vfs_describe (procgroup, mountpoint, path, &desc) != ST_OK) {
|
||||
vfs_close (procgroup, mountpoint, path);
|
||||
return NULL;
|
||||
}
|
||||
if (desc.type != FS_FILE)
|
||||
return NULL;
|
||||
|
||||
if (desc.type != FS_FILE) {
|
||||
vfs_close (procgroup, mountpoint, path);
|
||||
return NULL;
|
||||
}
|
||||
uint8_t* temp_buffer = malloc (desc.size);
|
||||
|
||||
uint8_t* temp_buffer = malloc (desc.size);
|
||||
if (temp_buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
if (temp_buffer == NULL) {
|
||||
vfs_close (procgroup, mountpoint, path);
|
||||
return NULL;
|
||||
}
|
||||
if (vfs_kernel_read (mountpoint, path, temp_buffer, 0, desc.size) < 0) {
|
||||
free (temp_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!proc_check_elf (temp_buffer)) {
|
||||
free (temp_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct proc* proc = proc_from_elf (temp_buffer);
|
||||
|
||||
if (vfs_read (procgroup, mountpoint, path, temp_buffer, 0, desc.size) != ST_OK) {
|
||||
free (temp_buffer);
|
||||
vfs_close (procgroup, mountpoint, path);
|
||||
return NULL;
|
||||
}
|
||||
return proc;
|
||||
} else {
|
||||
int handle = vfs_open (procgroup, mountpoint, path);
|
||||
|
||||
vfs_close (procgroup, mountpoint, path);
|
||||
if (handle < 0)
|
||||
return NULL;
|
||||
|
||||
bool ok = proc_check_elf (temp_buffer);
|
||||
if (vfs_describe (procgroup, handle, &desc) != ST_OK) {
|
||||
vfs_close (procgroup, handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG ("Spawning %s:%s, elf header %s\n", mountpoint, path, ok ? "ok" : "bad");
|
||||
if (desc.type != FS_FILE) {
|
||||
vfs_close (procgroup, handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t* temp_buffer = malloc (desc.size);
|
||||
|
||||
if (temp_buffer == NULL) {
|
||||
vfs_close (procgroup, handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (vfs_read (procgroup, handle, temp_buffer, 0, desc.size) != ST_OK) {
|
||||
free (temp_buffer);
|
||||
vfs_close (procgroup, handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vfs_close (procgroup, handle);
|
||||
|
||||
if (!proc_check_elf (temp_buffer)) {
|
||||
free (temp_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct proc* proc = proc_from_elf (temp_buffer);
|
||||
|
||||
if (!ok) {
|
||||
free (temp_buffer);
|
||||
return NULL;
|
||||
return proc;
|
||||
}
|
||||
|
||||
struct proc* proc = proc_from_elf (temp_buffer);
|
||||
|
||||
free (temp_buffer);
|
||||
return proc;
|
||||
}
|
||||
|
||||
struct proc* proc_find_pid (int pid) {
|
||||
@@ -172,7 +198,7 @@ void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedu
|
||||
|
||||
rbtree_insert (struct proc, &proc_tree, &proc->proc_tree_link, proc_tree_link, pid);
|
||||
|
||||
atomic_fetch_add (&cpu->proc_run_q_count, 1);
|
||||
cpu->proc_run_q_count++;
|
||||
list_append (cpu->proc_run_q, &proc->cpu_run_q_link);
|
||||
if (cpu->proc_current == NULL)
|
||||
cpu->proc_current = proc;
|
||||
@@ -207,7 +233,11 @@ static struct proc* proc_find_sched (struct cpu* cpu) {
|
||||
do {
|
||||
struct proc* proc = list_entry (current, struct proc, cpu_run_q_link);
|
||||
|
||||
if (atomic_load (&proc->state) == PROC_READY)
|
||||
spin_lock (&proc->lock);
|
||||
int state = proc->state;
|
||||
spin_unlock (&proc->lock);
|
||||
|
||||
if (state == PROC_READY)
|
||||
return proc;
|
||||
|
||||
current = current->next ? current->next : cpu->proc_run_q;
|
||||
@@ -230,14 +260,16 @@ static void proc_reap (struct reschedule_ctx* rctx) {
|
||||
rbtree_next (node, next);
|
||||
proc = rbtree_entry (node, struct proc, proc_tree_link);
|
||||
|
||||
if (atomic_load (&proc->state) == PROC_DEAD) {
|
||||
spin_lock (&proc->lock);
|
||||
rbtree_delete (&proc_tree, &proc->proc_tree_link);
|
||||
node = next;
|
||||
|
||||
spin_lock (&proc->lock);
|
||||
|
||||
if (proc->state == PROC_DEAD) {
|
||||
list_append (reap_list, &proc->reap_link);
|
||||
spin_unlock (&proc->lock);
|
||||
rbtree_delete (&proc_tree, &proc->proc_tree_link);
|
||||
}
|
||||
|
||||
node = next;
|
||||
spin_unlock (&proc->lock);
|
||||
}
|
||||
|
||||
spin_unlock (&proc_tree_lock);
|
||||
@@ -247,6 +279,7 @@ static void proc_reap (struct reschedule_ctx* rctx) {
|
||||
proc = list_entry (reap_link, struct proc, reap_link);
|
||||
|
||||
list_remove (reap_list, &proc->reap_link);
|
||||
|
||||
DEBUG ("cleanup PID %d\n", proc->pid);
|
||||
proc_cleanup (proc, rctx);
|
||||
}
|
||||
@@ -286,11 +319,11 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&cpu->lock);
|
||||
spin_lock (&proc->lock);
|
||||
|
||||
atomic_store (&proc->state, PROC_DEAD);
|
||||
proc->state = PROC_DEAD;
|
||||
proc->cpu = NULL;
|
||||
|
||||
list_remove (cpu->proc_run_q, &proc->cpu_run_q_link);
|
||||
atomic_fetch_sub (&cpu->proc_run_q_count, 1);
|
||||
cpu->proc_run_q_count--;
|
||||
if (cpu->proc_current == proc)
|
||||
cpu->proc_current = NULL;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ struct proc {
|
||||
uint32_t flags;
|
||||
spin_lock_t lock;
|
||||
struct cpu* cpu;
|
||||
atomic_int state;
|
||||
int state;
|
||||
uintptr_t uvaddr_argument;
|
||||
void* mail_recv_buffer;
|
||||
size_t mail_recv_size;
|
||||
|
||||
@@ -145,7 +145,6 @@ struct procgroup* procgroup_create (void) {
|
||||
|
||||
memset (procgroup, 0, sizeof (*procgroup));
|
||||
|
||||
procgroup->refs = 0;
|
||||
procgroup->memb_proc_tree = NULL;
|
||||
procgroup->lock = SPIN_LOCK_INIT;
|
||||
procgroup->pgid = atomic_fetch_add (&pgids, 1);
|
||||
@@ -171,7 +170,6 @@ void procgroup_attach (struct procgroup* procgroup, struct proc* proc) {
|
||||
|
||||
rbtree_insert (struct proc, &procgroup->memb_proc_tree, &proc->procgroup_memb_tree_link,
|
||||
procgroup_memb_tree_link, pid);
|
||||
atomic_fetch_add (&procgroup->refs, 1);
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&procgroup->lock);
|
||||
@@ -183,12 +181,12 @@ void procgroup_detach (struct procgroup* procgroup, struct proc* proc,
|
||||
spin_lock (&proc->lock);
|
||||
|
||||
rbtree_delete (&procgroup->memb_proc_tree, &proc->procgroup_memb_tree_link);
|
||||
int refs = atomic_fetch_sub (&procgroup->refs, 1);
|
||||
struct rb_node_link* memb_tree = procgroup->memb_proc_tree;
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&procgroup->lock);
|
||||
|
||||
if (refs == 1) {
|
||||
if (memb_tree == NULL) {
|
||||
spin_lock (&procgroup_tree_lock);
|
||||
spin_lock (&procgroup->lock);
|
||||
|
||||
@@ -197,6 +195,8 @@ void procgroup_detach (struct procgroup* procgroup, struct proc* proc,
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup_tree_lock);
|
||||
|
||||
struct list_node_link* resource_delete_list = NULL;
|
||||
|
||||
/* delete resources */
|
||||
struct rb_node_link* rnode;
|
||||
rbtree_first (&procgroup->resource_tree, rnode);
|
||||
@@ -209,6 +209,16 @@ void procgroup_detach (struct procgroup* procgroup, struct proc* proc,
|
||||
|
||||
rnode = next;
|
||||
|
||||
list_append (resource_delete_list, &resource->delete_list_link);
|
||||
}
|
||||
|
||||
struct list_node_link *resource_delete_link, *resource_delete_tmp_link;
|
||||
list_foreach (resource_delete_list, resource_delete_link, resource_delete_tmp_link) {
|
||||
struct proc_resource* resource =
|
||||
list_entry (resource_delete_link, struct proc_resource, delete_list_link);
|
||||
|
||||
list_remove (resource_delete_list, &resource->delete_list_link);
|
||||
|
||||
proc_delete_resource (resource, rctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ struct procgroup {
|
||||
struct rb_node_link procgroup_tree_link;
|
||||
struct rb_node_link* memb_proc_tree;
|
||||
spin_lock_t lock;
|
||||
atomic_int refs;
|
||||
struct rb_node_link* resource_tree;
|
||||
atomic_int sys_rids;
|
||||
struct pd pd;
|
||||
struct list_node_link* mappings;
|
||||
uintptr_t map_base;
|
||||
struct procgroup_tls tls;
|
||||
uint64_t capabilities;
|
||||
struct rb_node_link* vfs_handle_tree;
|
||||
int sys_vfs_handles;
|
||||
};
|
||||
|
||||
struct procgroup* procgroup_create (void);
|
||||
|
||||
@@ -21,6 +21,7 @@ struct proc_resource {
|
||||
int rid;
|
||||
spin_lock_t lock;
|
||||
struct rb_node_link resource_tree_link;
|
||||
struct list_node_link delete_list_link;
|
||||
union {
|
||||
struct proc_mutex mutex;
|
||||
struct proc_mail mail;
|
||||
|
||||
@@ -28,7 +28,7 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
|
||||
|
||||
spin_unlock (resource_lock);
|
||||
|
||||
atomic_store (&proc->state, PROC_SUSPENDED);
|
||||
proc->state = PROC_SUSPENDED;
|
||||
|
||||
/* append to sq's list */
|
||||
list_append (sq->proc_list, &sq_entry->sq_link);
|
||||
@@ -37,7 +37,7 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
|
||||
list_append (proc->sq_entries, &sq_entry->proc_link);
|
||||
|
||||
list_remove (cpu->proc_run_q, &proc->cpu_run_q_link);
|
||||
atomic_fetch_sub (&cpu->proc_run_q_count, 1);
|
||||
cpu->proc_run_q_count--;
|
||||
|
||||
if (cpu->proc_current == proc)
|
||||
cpu->proc_current = NULL;
|
||||
@@ -70,10 +70,10 @@ void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
proc->cpu = cpu;
|
||||
|
||||
if (proc->sq_entries == NULL)
|
||||
atomic_store (&proc->state, PROC_READY);
|
||||
proc->state = PROC_READY;
|
||||
|
||||
list_append (cpu->proc_run_q, &proc->cpu_run_q_link);
|
||||
atomic_fetch_add (&cpu->proc_run_q_count, 1);
|
||||
cpu->proc_run_q_count++;
|
||||
|
||||
spin_unlock (&sq->lock);
|
||||
spin_unlock (&proc->lock);
|
||||
|
||||
@@ -324,35 +324,16 @@ DEFINE_SYSCALL (sys_open) {
|
||||
return SYSRESULT (vfs_open (proc->procgroup, mountpoint, subpath));
|
||||
}
|
||||
|
||||
/* int close (char* path) */
|
||||
/* int close (int handle) */
|
||||
DEFINE_SYSCALL (sys_close) {
|
||||
uintptr_t uvaddr_path = a1;
|
||||
int handle = (int)a1;
|
||||
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
uintptr_t out_paddr;
|
||||
|
||||
spin_lock (&proc->procgroup->lock);
|
||||
out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path);
|
||||
spin_unlock (&proc->procgroup->lock);
|
||||
|
||||
if (out_paddr == 0)
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr);
|
||||
|
||||
char mountpoint[fieldsizeof (struct vfs_mountpoint, key)];
|
||||
const char* subpath = NULL;
|
||||
|
||||
if (!path_parse (path, mountpoint, &subpath))
|
||||
return SYSRESULT (-ST_BAD_PATH);
|
||||
|
||||
return SYSRESULT (vfs_close (proc->procgroup, mountpoint, subpath));
|
||||
return SYSRESULT (vfs_close (proc->procgroup, handle));
|
||||
}
|
||||
|
||||
/* int read (char* path, size_t off, uint8_t* buffer, size_t size) */
|
||||
/* int read (int handle, size_t off, uint8_t* buffer, size_t size) */
|
||||
DEFINE_SYSCALL (sys_read) {
|
||||
uintptr_t uvaddr_path = a1;
|
||||
int handle = (int)a1;
|
||||
size_t off = (size_t)a2;
|
||||
uintptr_t uvaddr_buffer = a3;
|
||||
size_t size = (size_t)a4;
|
||||
@@ -362,31 +343,12 @@ DEFINE_SYSCALL (sys_read) {
|
||||
if (buffer == NULL)
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
uintptr_t out_paddr;
|
||||
|
||||
spin_lock (&proc->procgroup->lock);
|
||||
out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path);
|
||||
spin_unlock (&proc->procgroup->lock);
|
||||
|
||||
if (out_paddr == 0)
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr);
|
||||
|
||||
char mountpoint[fieldsizeof (struct vfs_mountpoint, key)];
|
||||
const char* subpath = NULL;
|
||||
|
||||
if (!path_parse (path, mountpoint, &subpath))
|
||||
return SYSRESULT (-ST_BAD_PATH);
|
||||
|
||||
return SYSRESULT (vfs_read (proc->procgroup, mountpoint, subpath, buffer, off, size));
|
||||
return SYSRESULT (vfs_read (proc->procgroup, handle, buffer, off, size));
|
||||
}
|
||||
|
||||
/* int describe (char* path, struct desc* desc) */
|
||||
/* int describe (int handle, struct desc* desc) */
|
||||
DEFINE_SYSCALL (sys_describe) {
|
||||
uintptr_t uvaddr_path = a1;
|
||||
int handle = (int)a1;
|
||||
uintptr_t uvaddr_desc = a2;
|
||||
|
||||
struct desc* desc = sys_get_user_buffer (proc, uvaddr_desc, sizeof (struct desc));
|
||||
@@ -394,26 +356,7 @@ DEFINE_SYSCALL (sys_describe) {
|
||||
if (desc == NULL)
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
uintptr_t out_paddr;
|
||||
|
||||
spin_lock (&proc->procgroup->lock);
|
||||
out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path);
|
||||
spin_unlock (&proc->procgroup->lock);
|
||||
|
||||
if (out_paddr == 0)
|
||||
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr);
|
||||
|
||||
char mountpoint[fieldsizeof (struct vfs_mountpoint, key)];
|
||||
const char* subpath = NULL;
|
||||
|
||||
if (!path_parse (path, mountpoint, &subpath))
|
||||
return SYSRESULT (-ST_BAD_PATH);
|
||||
|
||||
return SYSRESULT (vfs_describe (proc->procgroup, mountpoint, subpath, desc));
|
||||
return SYSRESULT (vfs_describe (proc->procgroup, handle, desc));
|
||||
}
|
||||
|
||||
/* int get_procgroup (int pid) */
|
||||
|
||||
@@ -43,14 +43,14 @@ int exec (const char* path) { return (int)do_syscall (SYS_EXEC, path); }
|
||||
|
||||
int open (const char* path) { return (int)do_syscall (SYS_OPEN, path); }
|
||||
|
||||
int close (const char* path) { return (int)do_syscall (SYS_CLOSE, path); }
|
||||
int close (int handle) { return (int)do_syscall (SYS_CLOSE, handle); }
|
||||
|
||||
int read (const char* path, size_t off, uint8_t* buffer, size_t size) {
|
||||
return (int)do_syscall (SYS_READ, path, off, buffer, size);
|
||||
int read (int handle, size_t off, uint8_t* buffer, size_t size) {
|
||||
return (int)do_syscall (SYS_READ, handle, off, buffer, size);
|
||||
}
|
||||
|
||||
int describe (const char* path, struct desc* desc) {
|
||||
return (int)do_syscall (SYS_DESCRIBE, path, desc);
|
||||
int describe (int handle, struct desc* desc) {
|
||||
return (int)do_syscall (SYS_DESCRIBE, handle, desc);
|
||||
}
|
||||
|
||||
int mail_send (int pgid, void* mesg, size_t mesg_size) {
|
||||
|
||||
@@ -57,13 +57,13 @@ int exec (const char* path);
|
||||
int open (const char* path);
|
||||
|
||||
/* Close a file */
|
||||
int close (const char* path);
|
||||
int close (int handle);
|
||||
|
||||
/* Read a file */
|
||||
int read (const char* path, size_t off, uint8_t* buffer, size_t size);
|
||||
int read (int handle, size_t off, uint8_t* buffer, size_t size);
|
||||
|
||||
/* describe a file */
|
||||
int describe (const char* path, struct desc* desc);
|
||||
int describe (int handle, struct desc* desc);
|
||||
|
||||
/* send a message to a procgroup's mail */
|
||||
int mail_send (int pgid, void* mesg, size_t mesg_size);
|
||||
|
||||
Reference in New Issue
Block a user