Rework list functions

This commit is contained in:
Mark 2020-03-26 22:05:06 +02:00
parent 3da77fbc1a
commit f44505b05c
4 changed files with 87 additions and 63 deletions

View File

@ -1,28 +1,55 @@
#pragma once
struct list_link {
struct list_link *prev, *next;
};
struct list {
struct list_link *begin, *end;
struct list_head {
struct list_head *prev, *next;
};
#define LIST_HEAD(name) \
struct list name = { NULL, NULL }
struct list_head name = { &name, &name }
#define list_foreach(head, iter) \
for (struct list_link *iter = (head)->begin; iter; iter = iter->next)
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_link_value(link, type, member) ({ \
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#define list_entry(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; \
#define list_head_init(link) ({ \
(link)->prev = link; \
(link)->next = link; \
})
void list_append(struct list *list, struct list_link *ptr);
void list_remove(struct list *list, struct list_link *ptr);
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next) {
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
static inline void list_add(struct list_head *new, struct list_head *head) {
__list_add(new, head, head->next);
}
static inline void __list_del(struct list_head *prev, struct list_head *next) {
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry) {
__list_del(entry->prev, entry->next);
}
static inline int list_empty(const struct list_head *head) {
return head->next == head;
}

View File

@ -23,6 +23,7 @@ enum thread_state {
#define THREAD_KERNEL (1 << 0)
#define THREAD_EMPTY (1 << 1)
#define THREAD_FPU_SAVED (1 << 2)
#define THREAD_IDLE (1 << 3)
#define thread_signal_clear(thr, signum) \
(thr)->sigq &= ~(1ULL << ((signum) - 1))
@ -62,7 +63,7 @@ struct thread {
int exit_status;
// Global thread list (for stuff like finding by PID)
struct list_link g_link;
struct list_head g_link;
// Scheduler
int cpu;

View File

@ -2,36 +2,36 @@
#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;
}
//void list_add(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;
//}

View File

@ -37,10 +37,10 @@ struct sys_fork_frame {
////
//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;
// TODO: MAKE THIS PER-PROCESSOR
static uint64_t fxsave_buf[FXSAVE_REGION / 8] __attribute__((aligned(16)));
void context_save_fpu(struct thread *new, struct thread *old) {
@ -127,10 +127,8 @@ void thread_ioctx_fork(struct thread *dst, struct thread *src) {
int thread_signal_pgid(pid_t pgid, int signum) {
int ret = 0;
list_foreach(&threads_all_head, _thr) {
struct thread *thr = list_link_value(_thr, struct thread, g_link);
_assert(thr);
struct thread *thr;
list_for_each_entry(thr, &threads_all_head, g_link) {
if (thr->state != THREAD_STOPPED && thr->pgid == pgid) {
thread_signal(thr, signum);
++ret;
@ -141,10 +139,8 @@ int thread_signal_pgid(pid_t pgid, int signum) {
}
struct thread *thread_find(pid_t pid) {
list_foreach(&threads_all_head, _thr) {
struct thread *thr = list_link_value(_thr, struct thread, g_link);
_assert(thr);
struct thread *thr;
list_for_each_entry(thr, &threads_all_head, g_link) {
if (thr->pid == pid) {
return thr;
}
@ -259,7 +255,7 @@ int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) {
thr->data.fxsave = NULL;
}
list_link_init(&thr->g_link);
list_head_init(&thr->g_link);
uint64_t *stack = (uint64_t *) (thr->data.rsp0_base + thr->data.rsp0_size);
@ -373,7 +369,7 @@ int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) {
thr->pgid = -1;
thr->pid = -1;
list_append(&threads_all_head, &thr->g_link);
list_add(&threads_all_head, &thr->g_link);
return 0;
}
@ -390,7 +386,7 @@ 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);
list_head_init(&dst->g_link);
dst->data.rsp0_base = MM_VIRTUALIZE(stack_pages);
dst->data.rsp0_size = MM_PAGE_SIZE * 2;
@ -485,7 +481,7 @@ int sys_fork(struct sys_fork_frame *frame) {
dst->pgid = src->pgid;
dst->sigq = 0;
list_append(&threads_all_head, &dst->g_link);
list_add(&threads_all_head, &dst->g_link);
sched_queue(dst);
return dst->pid;
@ -683,7 +679,7 @@ int sys_waitpid(pid_t pid, int *status) {
}
thread_unchild(chld);
list_remove(&threads_all_head, &chld->g_link);
list_del(&chld->g_link);
thread_free(chld);
return 0;