diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 27 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 17 |
2 files changed, 39 insertions, 5 deletions
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 0036164bb0fb..3e64814e888e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -287,10 +287,18 @@ int start_userspace(unsigned long stub_stack) void userspace(struct uml_pt_regs *regs) { + struct itimerval timer; + unsigned long long nsecs, now; int err, status, op, pid = userspace_pid[0]; /* To prevent races if using_sysemu changes under us.*/ int local_using_sysemu; + if (getitimer(ITIMER_VIRTUAL, &timer)) + printk("Failed to get itimer, errno = %d\n", errno); + nsecs = timer.it_value.tv_sec * BILLION + + timer.it_value.tv_usec * 1000; + nsecs += os_nsecs(); + while (1) { restore_registers(pid, regs); @@ -333,8 +341,18 @@ void userspace(struct uml_pt_regs *regs) case SIGTRAP: relay_signal(SIGTRAP, regs); break; - case SIGIO: case SIGVTALRM: + now = os_nsecs(); + if(now < nsecs) + break; + block_signals(); + (*sig_info[sig])(sig, regs); + unblock_signals(); + nsecs = timer.it_value.tv_sec * BILLION + + timer.it_value.tv_usec * 1000; + nsecs += os_nsecs(); + break; + case SIGIO: case SIGILL: case SIGBUS: case SIGFPE: @@ -378,6 +396,7 @@ __initcall(init_thread_regs); int copy_context_skas0(unsigned long new_stack, int pid) { + struct timeval tv = { .tv_sec = 0, .tv_usec = 1000000 / UM_HZ }; int err; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; @@ -392,9 +411,9 @@ int copy_context_skas0(unsigned long new_stack, int pid) *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), .fd = new_fd, .timer = ((struct itimerval) - { { 0, 1000000 / UM_HZ }, - { 0, 1000000 / UM_HZ }}) - }); + { .it_value = tv, + .it_interval = tv }) }); + err = ptrace_setregs(pid, thread_regs); if (err < 0) panic("copy_context_skas0 : PTRACE_SETREGS failed, " diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6ff3d98281ba..9ffc61ac8ed6 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -26,6 +26,21 @@ int set_interval(void) return 0; } +int timer_one_shot(int ticks) +{ + unsigned long usec = ticks * 1000000 / UM_HZ; + unsigned long sec = usec / 1000000; + struct itimerval interval; + + usec %= 1000000; + interval = ((struct itimerval) { { 0, 0 }, { sec, usec } }); + + if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1) + return -errno; + + return 0; +} + void disable_timer(void) { struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); @@ -74,7 +89,7 @@ unsigned long long os_nsecs(void) struct timeval tv; gettimeofday(&tv, NULL); - return (unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000; + return timeval_to_ns(&tv); } void idle_sleep(int secs) |