timer sleep and wakeup functions by Balazs-san

This commit is contained in:
Masamichi Takagi m-takagi@ab.jp.nec.com
2012-11-26 15:14:41 +09:00
parent 22bd5d8247
commit 337fe4b20d
7 changed files with 221 additions and 5 deletions

View File

@ -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
View 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

View File

@ -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
View 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);

View File

@ -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)

View File

@ -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
View 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);
}
}