aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/process.c')
-rw-r--r--arch/i386/kernel/process.c64
1 files changed, 28 insertions, 36 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 5296e284ea3..1cb261f225d 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -99,14 +99,22 @@ EXPORT_SYMBOL(enable_hlt);
99 */ 99 */
100void default_idle(void) 100void default_idle(void)
101{ 101{
102 local_irq_enable();
103
102 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
103 local_irq_disable(); 105 clear_thread_flag(TIF_POLLING_NRFLAG);
104 if (!need_resched()) 106 smp_mb__after_clear_bit();
105 safe_halt(); 107 while (!need_resched()) {
106 else 108 local_irq_disable();
107 local_irq_enable(); 109 if (!need_resched())
110 safe_halt();
111 else
112 local_irq_enable();
113 }
114 set_thread_flag(TIF_POLLING_NRFLAG);
108 } else { 115 } else {
109 cpu_relax(); 116 while (!need_resched())
117 cpu_relax();
110 } 118 }
111} 119}
112#ifdef CONFIG_APM_MODULE 120#ifdef CONFIG_APM_MODULE
@@ -120,29 +128,14 @@ EXPORT_SYMBOL(default_idle);
120 */ 128 */
121static void poll_idle (void) 129static void poll_idle (void)
122{ 130{
123 int oldval;
124
125 local_irq_enable(); 131 local_irq_enable();
126 132
127 /* 133 asm volatile(
128 * Deal with another CPU just having chosen a thread to 134 "2:"
129 * run here: 135 "testl %0, %1;"
130 */ 136 "rep; nop;"
131 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 137 "je 2b;"
132 138 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
133 if (!oldval) {
134 set_thread_flag(TIF_POLLING_NRFLAG);
135 asm volatile(
136 "2:"
137 "testl %0, %1;"
138 "rep; nop;"
139 "je 2b;"
140 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
141
142 clear_thread_flag(TIF_POLLING_NRFLAG);
143 } else {
144 set_need_resched();
145 }
146} 139}
147 140
148#ifdef CONFIG_HOTPLUG_CPU 141#ifdef CONFIG_HOTPLUG_CPU
@@ -181,6 +174,8 @@ void cpu_idle(void)
181{ 174{
182 int cpu = smp_processor_id(); 175 int cpu = smp_processor_id();
183 176
177 set_thread_flag(TIF_POLLING_NRFLAG);
178
184 /* endless idle loop with no priority at all */ 179 /* endless idle loop with no priority at all */
185 while (1) { 180 while (1) {
186 while (!need_resched()) { 181 while (!need_resched()) {
@@ -246,15 +241,12 @@ static void mwait_idle(void)
246{ 241{
247 local_irq_enable(); 242 local_irq_enable();
248 243
249 if (!need_resched()) { 244 while (!need_resched()) {
250 set_thread_flag(TIF_POLLING_NRFLAG); 245 __monitor((void *)&current_thread_info()->flags, 0, 0);
251 do { 246 smp_mb();
252 __monitor((void *)&current_thread_info()->flags, 0, 0); 247 if (need_resched())
253 if (need_resched()) 248 break;
254 break; 249 __mwait(0, 0);
255 __mwait(0, 0);
256 } while (!need_resched());
257 clear_thread_flag(TIF_POLLING_NRFLAG);
258 } 250 }
259} 251}
260 252