uml: tickless support
[linux-2.6.git] / arch / um / os-Linux / skas / process.c
index 0036164..3e64814 100644 (file)
@@ -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, "