diff options
-rw-r--r-- | arch/um/include/os.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 9 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 9 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 27 |
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 | ||
253 | extern void switch_timers(int to_real); | 253 | extern int switch_timers(int to_real); |
254 | extern void idle_sleep(int secs); | 254 | extern void idle_sleep(int secs); |
255 | extern int set_interval(int is_virtual); | 255 | extern int set_interval(int is_virtual); |
256 | extern void disable_timer(void); | 256 | extern 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(®s, sc); | 63 | copy_sc(®s, sc); |
67 | regs.is_user = 0; | 64 | regs.is_user = 0; |
68 | unblock_signals(); | 65 | unblock_signals(); |
69 | timer_handler(sig, ®s); | 66 | timer_handler(sig, ®s); |
70 | |||
71 | if (sig == SIGALRM) | ||
72 | switch_timers(1); | ||
73 | } | 67 | } |
74 | 68 | ||
75 | void alarm_handler(int sig, struct sigcontext *sc) | 69 | void alarm_handler(int sig, struct sigcontext *sc) |
@@ -116,6 +110,7 @@ void (*handlers[_NSIG])(int sig, struct sigcontext *sc); | |||
116 | void handle_signal(int sig, struct sigcontext *sc) | 110 | void 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 | ||
157 | extern void hard_handler(int sig); | 154 | extern 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 | ||
15 | static int is_real_timer = 0; | ||
16 | |||
15 | int set_interval(int is_virtual) | 17 | int 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 | ||
42 | void switch_timers(int to_real) | 44 | int 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 | ||
64 | unsigned long long os_nsecs(void) | 77 | unsigned long long os_nsecs(void) |