timer sleep and wakeup functions by Balazs-san
This commit is contained in:
parent
22bd5d8247
commit
337fe4b20d
@ -1,6 +1,6 @@
|
||||
AALDIR=$(AALBASE)/$(TARGET)
|
||||
OBJS = init.o mem.o debug.o mikc.o listeners.o ap.o syscall.o cls.o host.o
|
||||
OBJS += process.o copy.o waitq.o futex.o
|
||||
OBJS += process.o copy.o waitq.o futex.o timer.o
|
||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||
|
||||
CFLAGS += -I$(SRC)/include -mcmodel=kernel -D__KERNEL__
|
||||
|
||||
49
kernel/Makefile.build.mpiu
Executable file
49
kernel/Makefile.build.mpiu
Executable file
@ -0,0 +1,49 @@
|
||||
AALDIR=$(AALBASE)/$(TARGET)
|
||||
OBJS = init.o mem.o debug.o mikc.o listeners.o ap.o syscall.o cls.o host.o
|
||||
OBJS += process.o copy.o waitq.o futex.o
|
||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||
|
||||
#CFLAGS += -I$(SRC)/include -mcmodel=kernel -D__KERNEL__ -DDCFA_KMOD -DIOCTL_FUNC_EXTENSION
|
||||
CFLAGS += -I$(SRC)/include -mcmodel=kernel -D__KERNEL__ -DDCFA_KMOD -DKNC_MAP_MICPA -DUSE_NOCACHE_MMAP
|
||||
CFLAGS += -DCONFIG_$(CONFIG_V)
|
||||
|
||||
LDFLAGS += -e arch_start
|
||||
AALOBJ = aal/aal.o
|
||||
|
||||
include $(SRC)/configs/config.$(TARGET)
|
||||
include $(AALBASE)/Makefile.common
|
||||
|
||||
SUBCMD_OPTS = TARGET=$(TARGET) O=$(CURDIR)/aal CC=$(CC) LD=$(LD) CONFIG_V=$(CONFIG_V)
|
||||
|
||||
ld_kern_cmd_base = $(LD) $(LDFLAGS) -o $@.elf $^
|
||||
mkimage_cmd_base = [ -f $(SRC)/scripts/mkimage.$(TARGET) ] && CC=$(CC) LD=$(LD) LDFLAGS="$(LDFLAGS_MKIMAGE)" sh $(SRC)/scripts/mkimage.$(TARGET) '$@.elf' '$@' '$(SRC)' || cp $@.elf $@
|
||||
|
||||
ld_kern_cmd = $(call echo_cmd,LDKERN,$@)$(ld_kern_cmd_base)
|
||||
mkimage_cmd = $(call echo_cmd,MKIMAGE,$@)$(mkimage_cmd_base)
|
||||
|
||||
all: depend kernel.img
|
||||
|
||||
kernel.img: $(OBJS) $(AALOBJ) $(EXTRA_OBJS)
|
||||
$(ld_kern_cmd)
|
||||
$(mkimage_cmd)
|
||||
|
||||
clean:
|
||||
$(rm_cmd) $(OBJS) kernel.img kernel.img.elf Makefile.dep
|
||||
@$(submake) -C $(AALBASE) $(SUBCMD_OPTS) clean
|
||||
|
||||
depend: Makefile.dep
|
||||
|
||||
Makefile.dep:
|
||||
$(call dep_cmd,$(DEPSRCS))
|
||||
|
||||
$(AALOBJ): FORCE
|
||||
@mkdir -p $(dir $(AALOBJ))
|
||||
$(call echo_cmd,BUILD AAL,$(TARGET))$(submake) -C $(AALBASE) $(SUBCMD_OPTS) prepare
|
||||
$(call echo_cmd,BUILD AAL,$(TARGET))$(submake) -C $(AALBASE) $(SUBCMD_OPTS)
|
||||
|
||||
%.o: $(SRC)/%.c
|
||||
$(cc_cmd)
|
||||
|
||||
FORCE:
|
||||
|
||||
-include Makefile.dep
|
||||
@ -62,6 +62,7 @@
|
||||
#include <list.h>
|
||||
#include <cls.h>
|
||||
#include <kmsg.h>
|
||||
#include <timer.h>
|
||||
|
||||
#if 0
|
||||
#include <lwk/kernel.h>
|
||||
|
||||
34
kernel/include/timer.h
Normal file
34
kernel/include/timer.h
Normal file
@ -0,0 +1,34 @@
|
||||
#include <types.h>
|
||||
#include <kmsg.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <cpulocal.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
#include <aal/ikc.h>
|
||||
#include <errno.h>
|
||||
#include <cls.h>
|
||||
#include <syscall.h>
|
||||
#include <page.h>
|
||||
#include <amemcpy.h>
|
||||
#include <uio.h>
|
||||
#include <aal/lock.h>
|
||||
#include <ctype.h>
|
||||
#include <waitq.h>
|
||||
#include <rlimit.h>
|
||||
#include <affinity.h>
|
||||
#include <time.h>
|
||||
|
||||
#define TIMER_CPU_ID 227
|
||||
|
||||
struct timer {
|
||||
uint64_t timeout;
|
||||
struct waitq processes;
|
||||
struct list_head list;
|
||||
struct process *proc;
|
||||
};
|
||||
|
||||
uint64_t schedule_timeout(uint64_t timeout);
|
||||
|
||||
void init_timers(void);
|
||||
void wake_timers_loop(void);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <page.h>
|
||||
#include <cpulocal.h>
|
||||
#include <auxvec.h>
|
||||
#include <timer.h>
|
||||
|
||||
#define DEBUG_PRINT_PROCESS
|
||||
|
||||
@ -365,6 +366,11 @@ void sched_init(void)
|
||||
INIT_LIST_HEAD(&cpu_local_var(runq));
|
||||
cpu_local_var(runq_len) = 0;
|
||||
aal_mc_spinlock_init(&cpu_local_var(runq_lock));
|
||||
|
||||
if (aal_mc_get_processor_id() == TIMER_CPU_ID) {
|
||||
init_timers();
|
||||
wake_timers_loop();
|
||||
}
|
||||
}
|
||||
|
||||
void schedule(void)
|
||||
|
||||
@ -750,7 +750,7 @@ SYSCALL_DECLARE(futex)
|
||||
{
|
||||
// TODO: timespec support!
|
||||
//struct timespec _utime;
|
||||
uint64_t timeout = 1000; // MAX_SCHEDULE_TIMEOUT;
|
||||
uint64_t timeout = 0; // No timeout
|
||||
uint32_t val2 = 0;
|
||||
|
||||
uint32_t *uaddr = (uint32_t *)aal_mc_syscall_arg0(ctx);
|
||||
@ -780,13 +780,13 @@ SYSCALL_DECLARE(futex)
|
||||
val2 = (uint32_t) (unsigned long) aal_mc_syscall_arg3(ctx);
|
||||
|
||||
// we don't have timer interrupt and wakeup, so fake it by just pausing
|
||||
if (op == FUTEX_WAIT_BITSET && utime) {
|
||||
|
||||
if (utime && (op == FUTEX_WAIT_BITSET || op == FUTEX_WAIT)) {
|
||||
// gettimeofday(&tv_now, NULL);
|
||||
struct syscall_request request AAL_DMA_ALIGN;
|
||||
struct timeval tv_now;
|
||||
request.number = 96;
|
||||
|
||||
#if 1
|
||||
unsigned long __phys;
|
||||
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table,
|
||||
(void *)&tv_now,
|
||||
@ -810,11 +810,18 @@ SYSCALL_DECLARE(futex)
|
||||
long nsec_timeout = ((long)utime->tv_sec * 1000000000ULL) +
|
||||
utime->tv_nsec * 1;
|
||||
long diff_nsec = nsec_timeout - nsec_now;
|
||||
|
||||
/*
|
||||
if(diff_nsec > 0) {
|
||||
dkprintf("pausing %016ldnsec\n", diff_nsec);
|
||||
arch_delay(diff_nsec/1000); // unit is usec
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
*/
|
||||
timeout = (diff_nsec / 1000) * 1100; // (usec * 1.1GHz)
|
||||
#else
|
||||
arch_delay(200000); // unit is usec
|
||||
return -ETIMEDOUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
return futex(uaddr, op, val, timeout, uaddr2, val2, val3);
|
||||
|
||||
119
kernel/timer.c
Normal file
119
kernel/timer.c
Normal file
@ -0,0 +1,119 @@
|
||||
#include <types.h>
|
||||
#include <kmsg.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <cpulocal.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
#include <aal/ikc.h>
|
||||
#include <errno.h>
|
||||
#include <cls.h>
|
||||
#include <syscall.h>
|
||||
#include <page.h>
|
||||
#include <amemcpy.h>
|
||||
#include <uio.h>
|
||||
#include <aal/lock.h>
|
||||
#include <ctype.h>
|
||||
#include <waitq.h>
|
||||
#include <rlimit.h>
|
||||
#include <affinity.h>
|
||||
#include <time.h>
|
||||
#include <lwk/stddef.h>
|
||||
#include <futex.h>
|
||||
#include <bitops.h>
|
||||
#include <timer.h>
|
||||
|
||||
//#define DEBUG_PRINT_TIMER
|
||||
|
||||
#ifdef DEBUG_PRINT_TIMER
|
||||
#define dkprintf kprintf
|
||||
#else
|
||||
#define dkprintf(...)
|
||||
#endif
|
||||
|
||||
#define LOOP_TIMEOUT 1000 /* default 1000 */
|
||||
|
||||
struct list_head timers;
|
||||
aal_spinlock_t timers_lock;
|
||||
|
||||
|
||||
void init_timers(void)
|
||||
{
|
||||
aal_mc_spinlock_init(&timers_lock);
|
||||
INIT_LIST_HEAD(&timers);
|
||||
}
|
||||
|
||||
uint64_t schedule_timeout(uint64_t timeout)
|
||||
{
|
||||
struct waitq_entry my_wait;
|
||||
struct timer my_timer;
|
||||
unsigned long irqflags;
|
||||
|
||||
/* Init waitq and wait entry for this timer */
|
||||
my_timer.timeout = (timeout < LOOP_TIMEOUT) ? LOOP_TIMEOUT : timeout;
|
||||
my_timer.proc = cpu_local_var(current);
|
||||
waitq_init(&my_timer.processes);
|
||||
waitq_init_entry(&my_wait, cpu_local_var(current));
|
||||
|
||||
/* Add ourself to the timer queue */
|
||||
irqflags = aal_mc_spinlock_lock(&timers_lock);
|
||||
list_add_tail(&my_timer.list, &timers);
|
||||
aal_mc_spinlock_unlock(&timers_lock, irqflags);
|
||||
|
||||
dkprintf("schedule_timeout() sleep timeout: %lu\n", my_timer.timeout);
|
||||
|
||||
/* Add ourself to the waitqueue and sleep */
|
||||
waitq_prepare_to_wait(&my_timer.processes, &my_wait, PS_INTERRUPTIBLE);
|
||||
schedule();
|
||||
waitq_finish_wait(&my_timer.processes, &my_wait);
|
||||
|
||||
irqflags = aal_mc_spinlock_lock(&timers_lock);
|
||||
|
||||
/* Waken up by someone else then timeout? */
|
||||
if (my_timer.timeout) {
|
||||
list_del(&my_timer.list);
|
||||
}
|
||||
aal_mc_spinlock_unlock(&timers_lock, irqflags);
|
||||
|
||||
dkprintf("schedule_timeout() woken up, timeout: %lu\n",
|
||||
my_timer.timeout);
|
||||
|
||||
return my_timer.timeout;
|
||||
}
|
||||
|
||||
|
||||
void wake_timers_loop(void)
|
||||
{
|
||||
unsigned long loop_s;
|
||||
unsigned long irqflags;
|
||||
struct timer *timer;
|
||||
struct timer *timer_next;
|
||||
|
||||
dkprintf("timers thread, entering loop\n");
|
||||
for (;;) {
|
||||
loop_s = rdtsc();
|
||||
|
||||
while (rdtsc() < (loop_s + LOOP_TIMEOUT)) {
|
||||
cpu_pause();
|
||||
}
|
||||
|
||||
/* Iterate and decrease timeout for all timers,
|
||||
* wake up if timeout reaches zero. */
|
||||
irqflags = aal_mc_spinlock_lock(&timers_lock);
|
||||
|
||||
list_for_each_entry_safe(timer, timer_next, &timers, list) {
|
||||
|
||||
timer->timeout -= LOOP_TIMEOUT;
|
||||
if (timer->timeout < LOOP_TIMEOUT) {
|
||||
timer->timeout = 0;
|
||||
list_del(&timer->list);
|
||||
|
||||
dkprintf("timers timeout occurred, waking up pid: %d\n",
|
||||
timer->proc->pid);
|
||||
|
||||
waitq_wakeup(&timer->processes);
|
||||
}
|
||||
}
|
||||
|
||||
aal_mc_spinlock_unlock(&timers_lock, irqflags);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user