Add linked list structure

This commit is contained in:
Mark
2020-02-05 11:38:13 +02:00
parent fc837b97d8
commit 533bc8567a
12 changed files with 217 additions and 67 deletions
+1
View File
@@ -25,6 +25,7 @@ void *syscall_table[256] = {
[SYSCALL_NR_LSEEK] = sys_lseek,
[SYSCALL_NR_IOCTL] = sys_ioctl,
[SYSCALL_NR_ACCESS] = sys_access,
[SYSCALL_NR_SELECT] = sys_select,
[SYSCALL_NR_GETCWD] = sys_getcwd,
[SYSCALL_NR_CHDIR] = sys_chdir,
[SYSCALL_NR_MKDIR] = sys_mkdir,
+2 -1
View File
@@ -56,7 +56,8 @@ OBJS+=$(O)/sys/debug.o \
$(O)/sys/init.o \
$(O)/sys/font/logo.o \
$(O)/sys/font/psf.o \
$(O)/sys/font/default8x16.o
$(O)/sys/font/default8x16.o \
$(O)/sys/list.o
DIRS+=$(O)/sys \
$(O)/sys/char \
$(O)/sys/block \
+28
View File
@@ -0,0 +1,28 @@
#pragma once
struct list_link {
struct list_link *prev, *next;
};
struct list {
struct list_link *begin, *end;
};
#define LIST_HEAD(name) \
struct list name = { NULL, NULL }
#define list_foreach(head, iter) \
for (struct list_link *iter = (head)->begin; iter; iter = iter->next)
#define list_link_value(link, type, member) ({ \
const typeof (((type *) 0)->member) *__memb = (link); \
(type *) ((char *) __memb - offsetof(type, member)); \
})
#define list_link_init(link) ({ \
(link)->prev = NULL; \
(link)->next = NULL; \
})
void list_append(struct list *list, struct list_link *ptr);
void list_remove(struct list *list, struct list_link *ptr);
-7
View File
@@ -5,14 +5,7 @@
#include "arch/amd64/sys/spin.h"
#endif
#if defined(AMD64_SMP)
void spin_lock(spin_t *s);
void spin_release(spin_t *s);
void spin_lock_irqsave(spin_t *s, uintptr_t *irq);
void spin_release_irqrestore(spin_t *s, uintptr_t *irq);
#else
#define spin_lock(s)
#define spin_release(s)
#define spin_lock_irqsave(s, i)
#define spin_release_irqrestore(s, i)
#endif
+2
View File
@@ -1,4 +1,5 @@
#pragma once
#include "user/select.h"
#include "sys/types.h"
ssize_t sys_read(int fd, void *data, size_t lim);
@@ -17,6 +18,7 @@ int sys_open(const char *filename, int flags, int mode);
void sys_close(int fd);
int sys_stat(const char *filename, struct stat *st);
int sys_access(const char *path, int mode);
int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *excp, struct timeval *tv);
int sys_chmod(const char *path, mode_t mode);
int sys_chown(const char *path, uid_t uid, gid_t gid);
off_t sys_lseek(int fd, off_t offset, int whence);
+3 -2
View File
@@ -2,6 +2,7 @@
#if defined(ARCH_AMD64)
#include "arch/amd64/asm/asm_thread.h"
#endif
#include "sys/list.h"
#include "fs/vfs.h"
#include "sys/mm.h"
@@ -59,11 +60,11 @@ struct thread {
int exit_status;
// Global thread list (for stuff like finding by PID)
struct thread *g_prev, *g_next;
struct list_link g_link;
// Scheduler
int cpu;
struct thread *prev, *next;
struct thread *sched_prev, *sched_next;
};
pid_t thread_alloc_pid(int is_user);
+26
View File
@@ -0,0 +1,26 @@
#pragma once
struct timeval;
// 64 bits
typedef long int __fd_mask;
#define __NFDBITS (8 * (int) sizeof(__fd_mask))
// TODO: Guess this should be the same as the maximum
// per-process filedes count
#define __FD_SETSIZE 64
typedef struct {
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
} fd_set;
#define FD_SET(fd, fds) \
(fds)->fds_bits[(fd) / __NFDBITS] |= (1ULL << ((fd) % __NFDBITS))
#define FD_ISSET(fd, fds) \
(!!((fds)->fds_bits[(fd) / __NFDBITS] & (1ULL << ((fd) % __NFDBITS))))
#define FD_ZERO(fds) \
for (int __i = 0; __i < (__FD_SETSIZE / __NFDBITS); ++__i) \
(fds)->fds_bits[__i] = 0
+1
View File
@@ -8,6 +8,7 @@
#define SYSCALL_NR_LSEEK 8
#define SYSCALL_NR_IOCTL 16
#define SYSCALL_NR_ACCESS 21
#define SYSCALL_NR_SELECT 23
#define SYSCALL_NR_GETCWD 79
#define SYSCALL_NR_CHDIR 80
#define SYSCALL_NR_MKDIR 83
+37
View File
@@ -0,0 +1,37 @@
#include "sys/assert.h"
#include "sys/types.h"
#include "sys/list.h"
void list_append(struct list *head, struct list_link *link) {
link->prev = head->end;
if (head->end) {
head->end->next = link;
} else {
head->begin = link;
}
link->next = NULL;
head->end = link;
}
void list_remove(struct list *head, struct list_link *link) {
struct list_link *prev, *next;
prev = link->prev;
next = link->next;
if (prev) {
prev->next = next;
} else {
_assert(link == head->begin);
head->begin = next;
}
if (next) {
next->prev = prev;
} else {
_assert(link == head->end);
head->end = prev;
}
link->prev = NULL;
link->next = NULL;
}
+28 -25
View File
@@ -48,15 +48,15 @@ void sched_queue_to(struct thread *thr, int cpu_no) {
thr->cpu = cpu_no;
if (queue_heads[cpu_no]) {
struct thread *queue_tail = queue_heads[cpu_no]->prev;
struct thread *queue_tail = queue_heads[cpu_no]->sched_prev;
queue_tail->next = thr;
thr->prev = queue_tail;
queue_heads[cpu_no]->prev = thr;
thr->next = queue_heads[cpu_no];
queue_tail->sched_next = thr;
thr->sched_prev = queue_tail;
queue_heads[cpu_no]->sched_prev = thr;
thr->sched_next = queue_heads[cpu_no];
} else {
thr->next = thr;
thr->prev = thr;
thr->sched_next = thr;
thr->sched_prev = thr;
queue_heads[cpu_no] = thr;
}
@@ -66,6 +66,7 @@ void sched_queue_to(struct thread *thr, int cpu_no) {
}
void sched_queue(struct thread *thr) {
#if defined(AMD64_SMP)
size_t min_queue_size = (size_t) -1;
int min_queue_index = 0;
uintptr_t irq;
@@ -78,8 +79,10 @@ void sched_queue(struct thread *thr) {
}
}
spin_release_irqrestore(&sched_lock, &irq);
sched_queue_to(thr, min_queue_index);
#else
sched_queue_to(thr, 0);
#endif
}
void sched_unqueue(struct thread *thr, enum thread_state new_state) {
@@ -97,8 +100,8 @@ void sched_unqueue(struct thread *thr, enum thread_state new_state) {
thr->cpu = -1;
int cpu_no = cpu->processor_id;
struct thread *prev = thr->prev;
struct thread *next = thr->next;
struct thread *sched_prev = thr->sched_prev;
struct thread *sched_next = thr->sched_next;
_assert((new_state == THREAD_WAITING) ||
(new_state == THREAD_STOPPED) ||
@@ -112,9 +115,9 @@ void sched_unqueue(struct thread *thr, enum thread_state new_state) {
thread_check_signal(thr, 0);
spin_lock_irqsave(&sched_lock, &irq);
if (next == thr) {
thr->next = NULL;
thr->prev = NULL;
if (sched_next == thr) {
thr->sched_next = NULL;
thr->sched_prev = NULL;
queue_heads[cpu_no] = NULL;
@@ -126,21 +129,21 @@ void sched_unqueue(struct thread *thr, enum thread_state new_state) {
}
if (thr == queue_heads[cpu_no]) {
queue_heads[cpu_no] = next;
queue_heads[cpu_no] = sched_next;
}
_assert(thr && next && prev);
_assert(thr && sched_next && sched_prev);
next->prev = prev;
prev->next = next;
sched_next->sched_prev = sched_prev;
sched_prev->sched_next = sched_next;
thr->prev = NULL;
thr->next = NULL;
thr->sched_prev = NULL;
thr->sched_next = NULL;
spin_release_irqrestore(&sched_lock, &irq);
if (thr == cpu->thread) {
cpu->thread = next;
context_switch_to(next, thr);
cpu->thread = sched_next;
context_switch_to(sched_next, thr);
}
}
@@ -210,7 +213,7 @@ void sched_debug_cycle(uint64_t delta_ms) {
struct thread *head = queue_heads[cpu];
if (head) {
struct thread *tail = head->prev;
struct thread *tail = head->sched_prev;
do {
if (head->name[0]) {
@@ -226,7 +229,7 @@ void sched_debug_cycle(uint64_t delta_ms) {
} else {
debugs(DEBUG_DEFAULT, ", ");
}
head = head->next;
head = head->sched_next;
} while (1);
debugs(DEBUG_DEFAULT, "\n");
@@ -272,8 +275,8 @@ void yield(void) {
struct thread *from = cpu->thread;
struct thread *to;
if (from && from->next) {
to = from->next;
if (from && from->sched_next) {
to = from->sched_next;
} else if (queue_heads[cpu->processor_id]) {
to = queue_heads[cpu->processor_id];
} else {
+45
View File
@@ -233,3 +233,48 @@ ssize_t sys_readdir(int fd, struct dirent *ent) {
return vfs_readdir(&thr->ioctx, thr->fds[fd], ent);
}
int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *excp, struct timeval *tv) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
// Not yet implemented
_assert(!outp);
_assert(!excp);
if (!inp) {
return 0;
}
fd_set _inp;
memcpy(&_inp, inp, sizeof(fd_set));
FD_ZERO(inp);
// Check fds
for (int i = 0; i < n; ++i) {
if (FD_ISSET(i, &_inp)) {
struct ofile *fd = thr->fds[i];
if (!fd) {
return -EBADF;
}
_assert(fd->vnode);
if (fd->vnode->type != VN_CHR) {
kerror("Tried to select() on non-char device/file: %s\n", fd->vnode->name);
return -ENOSYS;
}
}
}
uint64_t deadline = (uint64_t) -1;
if (tv) {
deadline = tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000ULL + system_time;
}
int res;
panic("NYI\n");
return 0;
}
+44 -32
View File
@@ -36,7 +36,8 @@ struct sys_fork_frame {
////
static struct thread *threads_all_head = NULL;
//static struct thread *threads_all_head = NULL;
LIST_HEAD(threads_all_head);
static pid_t last_kernel_pid = 0;
static pid_t last_user_pid = 0;
@@ -48,32 +49,32 @@ pid_t thread_alloc_pid(int is_user) {
}
}
static void thread_add(struct thread *thr) {
if (threads_all_head) {
threads_all_head->g_prev = thr;
}
thr->g_next = threads_all_head;
thr->g_prev = NULL;
threads_all_head = thr;
}
static void thread_remove(struct thread *thr) {
struct thread *prev = thr->g_prev;
struct thread *next = thr->g_next;
if (prev) {
prev->g_next = next;
} else {
threads_all_head = next;
}
if (next) {
next->g_prev = prev;
}
thr->g_next = NULL;
thr->g_prev = NULL;
}
//static void thread_add(struct thread *thr) {
// if (threads_all_head) {
// threads_all_head->g_prev = thr;
// }
// thr->g_next = threads_all_head;
// thr->g_prev = NULL;
// threads_all_head = thr;
//}
//
//static void thread_remove(struct thread *thr) {
// struct thread *prev = thr->g_prev;
// struct thread *next = thr->g_next;
//
// if (prev) {
// prev->g_next = next;
// } else {
// threads_all_head = next;
// }
//
// if (next) {
// next->g_prev = prev;
// }
//
// thr->g_next = NULL;
// thr->g_prev = NULL;
//}
////
@@ -103,7 +104,10 @@ void thread_ioctx_fork(struct thread *dst, struct thread *src) {
int thread_signal_pgid(pid_t pgid, int signum) {
int ret = 0;
for (struct thread *thr = threads_all_head; thr; thr = thr->g_next) {
list_foreach(&threads_all_head, _thr) {
struct thread *thr = list_link_value(_thr, struct thread, g_link);
_assert(thr);
if (thr->state != THREAD_STOPPED && thr->pgid == pgid) {
thread_signal(thr, signum);
++ret;
@@ -114,11 +118,15 @@ int thread_signal_pgid(pid_t pgid, int signum) {
}
struct thread *thread_find(pid_t pid) {
for (struct thread *thr = threads_all_head; thr; thr = thr->g_next) {
list_foreach(&threads_all_head, _thr) {
struct thread *thr = list_link_value(_thr, struct thread, g_link);
_assert(thr);
if (thr->pid == pid) {
return thr;
}
}
return NULL;
}
@@ -218,6 +226,8 @@ int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) {
thr->name[0] = 0;
thr->flags = user ? 0 : THREAD_KERNEL;
list_link_init(&thr->g_link);
uint64_t *stack = (uint64_t *) (thr->data.rsp0_base + thr->data.rsp0_size);
if (user) {
@@ -330,7 +340,7 @@ int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) {
thr->pgid = -1;
thr->pid = -1;
thread_add(thr);
list_append(&threads_all_head, &thr->g_link);
return 0;
}
@@ -347,6 +357,8 @@ int sys_fork(struct sys_fork_frame *frame) {
uintptr_t stack_pages = amd64_phys_alloc_contiguous(2);
_assert(stack_pages != MM_NADDR);
list_link_init(&dst->g_link);
dst->data.rsp0_base = MM_VIRTUALIZE(stack_pages);
dst->data.rsp0_size = MM_PAGE_SIZE * 2;
dst->data.rsp0_top = dst->data.rsp0_base + dst->data.rsp0_size;
@@ -430,7 +442,7 @@ int sys_fork(struct sys_fork_frame *frame) {
dst->pgid = src->pgid;
dst->sigq = 0;
thread_add(dst);
list_append(&threads_all_head, &dst->g_link);
sched_queue(dst);
return dst->pid;
@@ -625,7 +637,7 @@ int sys_waitpid(pid_t pid, int *status) {
}
thread_unchild(chld);
thread_remove(chld);
list_remove(&threads_all_head, &chld->g_link);
thread_free(chld);
return 0;