Skip to content

Commit

Permalink
working futex timeouts
Browse files Browse the repository at this point in the history
  • Loading branch information
tcfw committed Jul 24, 2024
1 parent efdf122 commit 3184659
Show file tree
Hide file tree
Showing 28 changed files with 193,869 additions and 72 deletions.
4 changes: 4 additions & 0 deletions arch/aarch64/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ void enableSystemCounter(struct clocksource_t *cs)
cnt_ctl |= 1;

__asm__ volatile("MSR CNTP_CTL_EL0, %0" ::"r"(cnt_ctl));

// Allow EL0 access to physical counters
uint64_t cntkctl = (1 << 0); // Access to CNTPCT_EL0
__asm__ volatile("MSR CNTKCTL_EL1, %0" ::"r"(cntkctl));
}

uint64_t getSystemCounterFreq(struct clocksource_t *cs)
Expand Down
5 changes: 5 additions & 0 deletions arch/aarch64/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ boot:
ADD x10, x10, #:lo12:stack
MOV sp, x10

//Add null stack frame
SUB sp, sp, #16
MOV fp, xzr
MOV lr, xzr //no return

.globl kernel_main
B kernel_main // Jump to the main function

Expand Down
2 changes: 2 additions & 0 deletions include/kernel/cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <kernel/thread.h>
#include <kernel/wait.h>

#define is_current_cls(cls) cls == get_cls()

enum exception_operation
{
EXCEPTION_UNKNOWN = 0,
Expand Down
2 changes: 1 addition & 1 deletion include/kernel/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ int futex_get_key(void *uaddr, union futex_key *key);

int futex_do_wake(void *uaddr, uint32_t n_wake, uint32_t val);

int futex_do_sleep(void *uaddr, uint32_t val, timespec_t *timeout);
int futex_do_sleep(void *uaddr, uint32_t val, int64_t timeout_ns);

#endif
8 changes: 6 additions & 2 deletions include/kernel/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <kernel/stdint.h>
#include <kernel/sync.h>
#include <kernel/vm.h>
#include <kernel/wait.h>

#define THREAD_KTHREAD (1)

Expand Down Expand Up @@ -120,7 +121,7 @@ struct thread_wait_cond_futex
thread_wait_cond cond;

futex_queue_t *queue;
timespec_t *timeout;
waitqueue_entry_t *timeout;
int ret;
};

Expand Down Expand Up @@ -163,6 +164,7 @@ typedef struct thread_t

thread_sigactions_t sigactions;

spinlock_t wc_lock;
thread_wait_cond *wc;
} thread_t;

Expand Down Expand Up @@ -214,7 +216,9 @@ void thread_return_wc(thread_t *thread, void *data1);

int can_wake_thread(thread_t *thread);

thread_t *get_thread_by_pid(pid_t pid);
thread_t *get_first_thread_by_pid(pid_t pid);

thread_t *get_current_sibling_thread_by_tid(tid_t tid);

void mark_zombie_thread(thread_t *thread);

Expand Down
1 change: 1 addition & 0 deletions include/syscall_num.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define SYSCALL_EXEC (30) // int exec();
#define SYSCALL_CLONE (31) // int clone();
#define SYSCALL_THREAD_START (32) // int thread_start();
#define SYSCALL_THREAD_PREEMPT (33) // int thread_preempt();
#define SYSCALL_KNAME (40) // int kname();
#define SYSCALL_SYSINFO (41) // int sysinfo();
#define SYSCALL_SET_HOSTNAME (42) // int set_hostname();
Expand Down
2 changes: 1 addition & 1 deletion kernel/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void timespec_from_cs(struct clocksource_t *cs, timespec_t *ts)
uint64_t freq = cs->getFreq(cs);

uint64_t seconds = cc / freq;
uint64_t clock_nanos = (uint64_t)((1.0 / (double)freq) * 1000000000.0);
uint64_t clock_nanos = 1000000000 / freq;
uint64_t nano = (cc - (seconds * freq)) * clock_nanos;
ts->seconds = seconds;
ts->nanoseconds = nano;
Expand Down
4 changes: 3 additions & 1 deletion kernel/cls.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ cls_t *get_core_cls(uint8_t n)

void set_current_thread(thread_t *thread)
{
get_cls()->rq.current_thread = thread;
cls_t *cls = get_cls();
cls->rq.current_thread = thread;
thread->running_core = cls->id;
}
33 changes: 12 additions & 21 deletions kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <kernel/mm.h>
#include <kernel/sync.h>
#include <kernel/syscall.h>
#include <kernel/tty.h>
#include <kernel/uaccess.h>
#include <kernel/vm.h>
#include <kernel/wait.h>
Expand Down Expand Up @@ -67,6 +68,8 @@ int futex_do_wake(void *uaddr, uint32_t n_wake, uint32_t val)
if (ret != 0)
return ret;

// terminal_logf("futex(wake): 0x%X n=0x%X val=0x%X", key.both, n_wake, val);

hb = futex_hb(&key);

memory_barrier;
Expand All @@ -91,17 +94,12 @@ int futex_do_wake(void *uaddr, uint32_t n_wake, uint32_t val)
spinlock_release(&hb->lock);

list_head_for_each_safe(queued_task, next, &to_wake)
{
wake_thread(queued_task->thread);

list_del(queued_task);
kfree(queued_task);
}

return ret;
}

int futex_do_sleep(void *uaddr, uint32_t val, timespec_t *timeout)
int futex_do_sleep(void *uaddr, uint32_t val, int64_t timeout_ns)
{
futex_hb_t *hb;
union futex_key key = {.both = {.ptr = 0ULL}};
Expand All @@ -114,6 +112,8 @@ int futex_do_sleep(void *uaddr, uint32_t val, timespec_t *timeout)

hb = futex_hb(&key);

// terminal_logf("futex(sleep): 0x%X n=0x%X to=%d", key.both, val, timeout_ns);

spinlock_acquire(&hb->lock);

memory_barrier;
Expand Down Expand Up @@ -157,18 +157,15 @@ int futex_do_sleep(void *uaddr, uint32_t val, timespec_t *timeout)

spinlock_release(&hb->lock);

if (timeout == NULL)
if (timeout_ns <= 0)
return ret;

timespec_t *t = kmalloc(sizeof(*t));
if (t == NULL)
goto freeWC;

wc->timeout = t;

ret = copy_from_user(timeout, t, sizeof(*t));
if (ret < 0)
goto freeToT;
t->nanoseconds = timeout_ns & ((1 << 30) - 1);
t->seconds = timeout_ns >> 30;

waitqueue_entry_t *wqe = kmalloc(sizeof(waitqueue_entry_t));
if (wqe == NULL)
Expand All @@ -177,6 +174,7 @@ int futex_do_sleep(void *uaddr, uint32_t val, timespec_t *timeout)
wqe->thread = thread;
wqe->func = wq_can_wake_thread;
wqe->timeout = t;
wc->timeout = wqe;

cls_t *cls = get_cls();
spinlock_acquire(&cls->sleepq.lock);
Expand All @@ -200,25 +198,18 @@ int futex_do_sleep(void *uaddr, uint32_t val, timespec_t *timeout)
return -ERRNOMEM;
}

DEFINE_SYSCALL5(syscall_futex, SYSCALL_FUTEX, void *, addr, int, op, uint32_t, val, uint32_t, val2, timespec_t *, timeout)
DEFINE_SYSCALL5(syscall_futex, SYSCALL_FUTEX, void *, addr, int, op, uint32_t, val, uint32_t, val2, int64_t, timeout_ns)
{
int ret = access_ok(ACCESS_TYPE_READ, addr, sizeof(val));
if (ret < 0)
return ret;

if (timeout != NULL)
{
ret = access_ok(ACCESS_TYPE_READ, timeout, sizeof(*timeout));
if (ret < 0)
return ret;
}

switch (op)
{
case FUTEX_OP_WAKE:
return futex_do_wake(addr, val, val2);
case FUTEX_OP_SLEEP:
return futex_do_sleep(addr, val, timeout);
return futex_do_sleep(addr, val, timeout_ns);
default:
return -ERRINVAL;
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ void k_setup_clock_irq()
{
// EL1 physical timer
assign_irq_hook(30, clock_tick);
enable_xrq_n_prio(30, 1);
enable_xrq_n_prio(30, 0);
xrq_set_trigger_type(30, 1);

// EL1 virtual timer
assign_irq_hook(27, clock_tick);
enable_xrq_n_prio(27, 1);
enable_xrq_n_prio(27, 0);
xrq_set_trigger_type(27, 1);
}

Expand Down
12 changes: 9 additions & 3 deletions kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static void init_mon(void *data)
terminal_printf("\r\n\033c");

terminal_printf("\r\n\033[;H");
terminal_logf("\r\nProc\tCore\tPC\t\tTime\t\tState\r\n");
terminal_logf("\r\nProc\tCore\tPC\t\tTime\t\t\tDeadline\t\tState\r\n");

thread_list_entry_t *this;

Expand All @@ -79,7 +79,7 @@ static void init_mon(void *data)
else
terminal_writestring(" ");

terminal_printf("\t%d\t0x%x\t%X\t%d", this->thread->running_core, this->thread->ctx.pc, this->thread->timing.total_execution, this->thread->state);
terminal_printf("\t%d\t0x%x\t%X\t%X\t%d", this->thread->running_core, this->thread->ctx.pc, this->thread->timing.total_execution, this->thread->sched_entity.deadline, this->thread->state);

switch (this->thread->state)
{
Expand All @@ -95,13 +95,19 @@ static void init_mon(void *data)
struct thread_wait_cond_futex *wc = (struct thread_wait_cond_futex *)this->thread->wc;
if (wc->timeout != NULL)
terminal_writestring(" with timeout");
terminal_printf(" for futex=0x%X", wc->queue->key.both);
}
if (this->thread->wc->type == SLEEP)
else if (this->thread->wc->type == SLEEP)
{
struct thread_wait_cond_sleep *wc = (struct thread_wait_cond_sleep *)this->thread->wc;
terminal_printf(" until %d.%d", wc->timer.seconds, wc->timer.nanoseconds);
}
else
terminal_printf(" WC=0x%x", this->thread->wc->type);
}
else
terminal_writestring(" NWC!");

break;
case THREAD_UNINT_SLEEPING:
terminal_writestring("\tUint sleeping");
Expand Down
14 changes: 9 additions & 5 deletions kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <kernel/sync.h>
#include <kernel/thread.h>
#include <kernel/wait.h>
#include <kernel/tty.h>

static LIST_HEAD(pending);

Expand All @@ -32,15 +33,15 @@ static int thread_deadline_comparator(void *n1, void *n2)
thread_t *tn1 = (thread_t *)n1;
thread_t *tn2 = (thread_t *)n2;

if (tn1->process->pid == tn2->process->pid)
if (tn1->tid == tn2->tid)
return 0;

uint64_t tn1e = tn1->sched_entity.deadline;
uint64_t tn2e = tn2->sched_entity.deadline;

if (tn1e == tn2e)
return 0;
else if (tn1e > tn2e)
else if (tn1e < tn2e)
return 1;
else
return -1;
Expand Down Expand Up @@ -191,7 +192,9 @@ void schedule(void)

int state = spinlock_acquire_irq(&cls->rq.lock);

spinlock_acquire(&cls->sleepq.lock);
try_wake_waitqueue(&cls->sleepq);
spinlock_release(&cls->sleepq.lock);

struct clocksource_t *clk = clock_first(CS_GLOBAL);
uint64_t clkval = clk->val(clk);
Expand All @@ -205,7 +208,9 @@ void schedule(void)

prev->timing.total_user += clkval - prev->timing.last_user;
prev->timing.total_execution = prev->timing.total_system + prev->timing.total_user;
prev->sched_entity.deadline -= clkval - prev->sched_entity.last_deadline;
prev->sched_entity.deadline -= (int64_t)(clkval - prev->sched_entity.last_deadline);
if (prev->sched_entity.deadline < 0)
prev->sched_entity.deadline = -1;

if (prev->state == THREAD_RUNNING)
prev->sched_class->requeue_thread(&cls->rq, prev);
Expand Down Expand Up @@ -241,8 +246,7 @@ void schedule(void)
next->timing.total_wait += clkval - next->timing.last_wait;
next->sched_entity.last_deadline = clkval;

cls->rq.current_thread = next;
next->running_core = cls->id;
set_current_thread(next);
arch_thread_prep_switch(next);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void *slub_alloc(slub_t *slub)
// check if posioned
if (slub->object_size >= sizeof(slub_entry_t))
if (((slub_entry_t *)addr)->poison != POISON_VALUE)
panicf("Object allocated that did not have a correct poison value!\r\nAddr alloc'd: 0x%X\r\nObject Size: 0x%X\r\n", addr, slub->object_size);
panicf("Object allocated that did not have a correct poison value!\r\nPossible use after free...\r\nAddr alloc'd: 0x%X\r\nObject Size: 0x%X\r\n", addr, slub->object_size);

memset(addr, 0, slub->object_size);

Expand Down
2 changes: 2 additions & 0 deletions kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ uint64_t ksyscall_entry(uint64_t type, uint64_t arg0, uint64_t arg1, uint64_t ar
ret = handler->handler(cthread);
break;
}
else
terminal_logf("unhandled SYSCALL 0x%X TID=0x%X:0x%X", type, cthread->process->pid, cthread->tid);

clkval = clk->val(clk);
cthread->timing.total_system += clkval - cthread->timing.last_system;
Expand Down
5 changes: 3 additions & 2 deletions kernel/syscall_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ DEFINE_SYSCALL2(writeconsole, SYSCALL_CONSOLE_WRITE, const void *, c, size_t, n)
return aok;

void *buf = page_alloc_s(n);
memset(buf, 0, n);
memset(buf, 0, n + (PAGE_SIZE - (n % PAGE_SIZE)));

int ret = copy_from_user(c, buf, n);
if (ret < 0)
Expand All @@ -24,7 +24,8 @@ DEFINE_SYSCALL2(writeconsole, SYSCALL_CONSOLE_WRITE, const void *, c, size_t, n)
return ret;
}

terminal_write(buf, n);
// terminal_write(buf, n);
terminal_logf(buf);

// if (((char *)buf)[n - 1] == '\n')
// terminal_write("\r", 1);
Expand Down
Loading

0 comments on commit 3184659

Please sign in to comment.