aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/include/os.h2
-rw-r--r--arch/um/kernel/process.c9
-rw-r--r--arch/um/os-Linux/signal.c9
-rw-r--r--arch/um/os-Linux/time.c27
4 files changed, 26 insertions, 21 deletions
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index e861c8adb44f..12de1ea68370 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -250,7 +250,7 @@ extern void os_dump_core(void);
250/* time.c */ 250/* time.c */
251#define BILLION (1000 * 1000 * 1000) 251#define BILLION (1000 * 1000 * 1000)
252 252
253extern void switch_timers(int to_real); 253extern int switch_timers(int to_real);
254extern void idle_sleep(int secs); 254extern void idle_sleep(int secs);
255extern int set_interval(int is_virtual); 255extern int set_interval(int is_virtual);
256extern void disable_timer(void); 256extern void disable_timer(void);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 8a6882dfba01..56d75afedbf7 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -95,18 +95,11 @@ void *_switch_to(void *prev, void *next, void *last)
95 do { 95 do {
96 current->thread.saved_task = NULL; 96 current->thread.saved_task = NULL;
97 97
98 /* XXX need to check runqueues[cpu].idle */
99 if (current->pid == 0)
100 switch_timers(0);
101
102 switch_threads(&from->thread.switch_buf, 98 switch_threads(&from->thread.switch_buf,
103 &to->thread.switch_buf); 99 &to->thread.switch_buf);
104 100
105 arch_switch_to(current->thread.prev_sched, current); 101 arch_switch_to(current->thread.prev_sched, current);
106 102
107 if (current->pid == 0)
108 switch_timers(1);
109
110 if (current->thread.saved_task) 103 if (current->thread.saved_task)
111 show_regs(&(current->thread.regs)); 104 show_regs(&(current->thread.regs));
112 next= current->thread.saved_task; 105 next= current->thread.saved_task;
@@ -251,7 +244,9 @@ void default_idle(void)
251 if (need_resched()) 244 if (need_resched())
252 schedule(); 245 schedule();
253 246
247 switch_timers(1);
254 idle_sleep(10); 248 idle_sleep(10);
249 switch_timers(0);
255 } 250 }
256} 251}
257 252
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 49c113b576b7..1c5267ec13b0 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -59,17 +59,11 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
59{ 59{
60 struct uml_pt_regs regs; 60 struct uml_pt_regs regs;
61 61
62 if (sig == SIGALRM)
63 switch_timers(0);
64
65 if (sc != NULL) 62 if (sc != NULL)
66 copy_sc(&regs, sc); 63 copy_sc(&regs, sc);
67 regs.is_user = 0; 64 regs.is_user = 0;
68 unblock_signals(); 65 unblock_signals();
69 timer_handler(sig, &regs); 66 timer_handler(sig, &regs);
70
71 if (sig == SIGALRM)
72 switch_timers(1);
73} 67}
74 68
75void alarm_handler(int sig, struct sigcontext *sc) 69void alarm_handler(int sig, struct sigcontext *sc)
@@ -116,6 +110,7 @@ void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
116void handle_signal(int sig, struct sigcontext *sc) 110void handle_signal(int sig, struct sigcontext *sc)
117{ 111{
118 unsigned long pending = 1UL << sig; 112 unsigned long pending = 1UL << sig;
113 int timer = switch_timers(0);
119 114
120 do { 115 do {
121 int nested, bail; 116 int nested, bail;
@@ -152,6 +147,8 @@ void handle_signal(int sig, struct sigcontext *sc)
152 if (!nested) 147 if (!nested)
153 pending = from_irq_stack(nested); 148 pending = from_irq_stack(nested);
154 } while (pending); 149 } while (pending);
150
151 switch_timers(timer);
155} 152}
156 153
157extern void hard_handler(int sig); 154extern void hard_handler(int sig);
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 5939653f99ea..a16a0f484edc 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -12,6 +12,8 @@
12#include "os.h" 12#include "os.h"
13#include "user.h" 13#include "user.h"
14 14
15static int is_real_timer = 0;
16
15int set_interval(int is_virtual) 17int set_interval(int is_virtual)
16{ 18{
17 int usec = 1000000/UM_HZ; 19 int usec = 1000000/UM_HZ;
@@ -39,12 +41,14 @@ void disable_timer(void)
39 signal(SIGVTALRM, SIG_IGN); 41 signal(SIGVTALRM, SIG_IGN);
40} 42}
41 43
42void switch_timers(int to_real) 44int switch_timers(int to_real)
43{ 45{
44 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); 46 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
45 struct itimerval enable = ((struct itimerval) { { 0, 1000000/UM_HZ }, 47 struct itimerval enable;
46 { 0, 1000000/UM_HZ }}); 48 int old, new, old_type = is_real_timer;
47 int old, new; 49
50 if(to_real == old_type)
51 return to_real;
48 52
49 if (to_real) { 53 if (to_real) {
50 old = ITIMER_VIRTUAL; 54 old = ITIMER_VIRTUAL;
@@ -55,10 +59,19 @@ void switch_timers(int to_real)
55 new = ITIMER_VIRTUAL; 59 new = ITIMER_VIRTUAL;
56 } 60 }
57 61
58 if ((setitimer(old, &disable, NULL) < 0) || 62 if (setitimer(old, &disable, &enable) < 0)
59 (setitimer(new, &enable, NULL))) 63 printk(UM_KERN_ERR "switch_timers - setitimer disable failed, "
60 printk(UM_KERN_ERR "switch_timers - setitimer failed, " 64 "errno = %d\n", errno);
65
66 if((enable.it_value.tv_sec == 0) && (enable.it_value.tv_usec == 0))
67 enable.it_value = enable.it_interval;
68
69 if (setitimer(new, &enable, NULL))
70 printk(UM_KERN_ERR "switch_timers - setitimer enable failed, "
61 "errno = %d\n", errno); 71 "errno = %d\n", errno);
72
73 is_real_timer = to_real;
74 return old_type;
62} 75}
63 76
64unsigned long long os_nsecs(void) 77unsigned long long os_nsecs(void)