From: Jeff Dike <jdike@addtoit.com>
To: Andrew Morton <akpm@osdl.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
uml-devel <user-mode-linux-devel@lists.sourceforge.net>
Subject: [uml-devel] [PATCH 9/11] UML - Eliminate interrupts in the idle loop
Date: Wed, 19 Sep 2007 13:02:29 -0400 [thread overview]
Message-ID: <20070919170229.GA10202@c2.user-mode-linux.org> (raw)
Now, the idle loop now longer needs SIGALRM firing - it can just sleep
for the requisite amount of time and fake a timer interrupt when it
finishes.
Any use of ITIMER_REAL now goes away. disable_timer only turns off
ITIMER_VIRTUAL. switch_timers is no longer needed, so it, and all
calls, goes away.
disable_timer now returns the amount of time remaining on the timer.
default_idle uses this to tell idle_sleep how long to sleep.
idle_sleep will call alarm_handler if nanosleep returns 0, which is
the case if it didn't return early due to an interrupt. Otherwise, it
just returns.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
---
arch/um/include/os.h | 5 +---
arch/um/kernel/process.c | 7 +++--
arch/um/os-Linux/signal.c | 3 --
arch/um/os-Linux/time.c | 54 +++++++++-------------------------------------
4 files changed, 17 insertions(+), 52 deletions(-)
Index: linux-2.6.20/arch/um/os-Linux/time.c
===================================================================
--- linux-2.6.20.orig/arch/um/os-Linux/time.c 2007-09-19 12:25:07.000000000 -0400
+++ linux-2.6.20/arch/um/os-Linux/time.c 2007-09-19 12:25:08.000000000 -0400
@@ -12,8 +12,6 @@
#include "os.h"
#include "user.h"
-static int is_real_timer = 0;
-
int set_interval(void)
{
int usec = 1000000/UM_HZ;
@@ -53,47 +51,15 @@ static inline unsigned long long tv_to_n
tv->tv_usec * 1000;
}
-void disable_timer(void)
+unsigned long long disable_timer(void)
{
- struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
+ struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
- if ((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
- (setitimer(ITIMER_REAL, &disable, NULL) < 0))
+ if(setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
printk(UM_KERN_ERR "disable_timer - setitimer failed, "
"errno = %d\n", errno);
-}
-
-int switch_timers(int to_real)
-{
- struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
- struct itimerval enable;
- int old, new, old_type = is_real_timer;
-
- if(to_real == old_type)
- return to_real;
-
- if (to_real) {
- old = ITIMER_VIRTUAL;
- new = ITIMER_REAL;
- }
- else {
- old = ITIMER_REAL;
- new = ITIMER_VIRTUAL;
- }
-
- if (setitimer(old, &disable, &enable) < 0)
- printk(UM_KERN_ERR "switch_timers - setitimer disable failed, "
- "errno = %d\n", errno);
-
- if((enable.it_value.tv_sec == 0) && (enable.it_value.tv_usec == 0))
- enable.it_value = enable.it_interval;
- if (setitimer(new, &enable, NULL))
- printk(UM_KERN_ERR "switch_timers - setitimer enable failed, "
- "errno = %d\n", errno);
-
- is_real_timer = to_real;
- return old_type;
+ return tv_to_nsec(&time.it_value);
}
unsigned long long os_nsecs(void)
@@ -104,11 +70,13 @@ unsigned long long os_nsecs(void)
return tv_to_nsec(&tv);
}
-void idle_sleep(int secs)
+extern void alarm_handler(int sig, struct sigcontext *sc);
+
+void idle_sleep(unsigned long long nsecs)
{
- struct timespec ts;
+ struct timespec ts = { .tv_sec = nsecs / BILLION,
+ .tv_nsec = nsecs % BILLION };
- ts.tv_sec = secs;
- ts.tv_nsec = 0;
- nanosleep(&ts, NULL);
+ if (nanosleep(&ts, &ts) == 0)
+ alarm_handler(SIGVTALRM, NULL);
}
Index: linux-2.6.20/arch/um/os-Linux/signal.c
===================================================================
--- linux-2.6.20.orig/arch/um/os-Linux/signal.c 2007-09-19 12:25:06.000000000 -0400
+++ linux-2.6.20/arch/um/os-Linux/signal.c 2007-09-19 12:25:08.000000000 -0400
@@ -120,7 +120,6 @@ void (*handlers[_NSIG])(int sig, struct
void handle_signal(int sig, struct sigcontext *sc)
{
unsigned long pending = 0;
- int timer = switch_timers(0);
do {
int nested, bail;
@@ -157,8 +156,6 @@ void handle_signal(int sig, struct sigco
if (!nested)
pending = from_irq_stack(nested);
} while (pending);
-
- switch_timers(timer);
}
extern void hard_handler(int sig);
Index: linux-2.6.20/arch/um/kernel/process.c
===================================================================
--- linux-2.6.20.orig/arch/um/kernel/process.c 2007-09-19 12:25:07.000000000 -0400
+++ linux-2.6.20/arch/um/kernel/process.c 2007-09-19 12:25:08.000000000 -0400
@@ -235,6 +235,8 @@ void initial_thread_cb(void (*proc)(void
void default_idle(void)
{
+ unsigned long long nsecs;
+
while(1) {
/* endless idle loop with no priority at all */
@@ -246,9 +248,8 @@ void default_idle(void)
schedule();
tick_nohz_stop_sched_tick();
- switch_timers(1);
- idle_sleep(10);
- switch_timers(0);
+ nsecs = disable_timer();
+ idle_sleep(nsecs);
tick_nohz_restart_sched_tick();
}
}
Index: linux-2.6.20/arch/um/include/os.h
===================================================================
--- linux-2.6.20.orig/arch/um/include/os.h 2007-09-19 12:25:07.000000000 -0400
+++ linux-2.6.20/arch/um/include/os.h 2007-09-19 12:25:08.000000000 -0400
@@ -251,11 +251,10 @@ extern void os_dump_core(void);
/* time.c */
#define BILLION (1000 * 1000 * 1000)
-extern int switch_timers(int to_real);
-extern void idle_sleep(int secs);
+extern void idle_sleep(unsigned long long nsecs);
extern int set_interval(void);
extern int timer_one_shot(int ticks);
-extern void disable_timer(void);
+extern unsigned long long disable_timer(void);
extern void uml_idle_timer(void);
extern unsigned long long os_nsecs(void);
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
WARNING: multiple messages have this Message-ID (diff)
From: Jeff Dike <jdike@addtoit.com>
To: Andrew Morton <akpm@osdl.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
uml-devel <user-mode-linux-devel@lists.sourceforge.net>
Subject: [PATCH 9/11] UML - Eliminate interrupts in the idle loop
Date: Wed, 19 Sep 2007 13:02:29 -0400 [thread overview]
Message-ID: <20070919170229.GA10202@c2.user-mode-linux.org> (raw)
Now, the idle loop now longer needs SIGALRM firing - it can just sleep
for the requisite amount of time and fake a timer interrupt when it
finishes.
Any use of ITIMER_REAL now goes away. disable_timer only turns off
ITIMER_VIRTUAL. switch_timers is no longer needed, so it, and all
calls, goes away.
disable_timer now returns the amount of time remaining on the timer.
default_idle uses this to tell idle_sleep how long to sleep.
idle_sleep will call alarm_handler if nanosleep returns 0, which is
the case if it didn't return early due to an interrupt. Otherwise, it
just returns.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
---
arch/um/include/os.h | 5 +---
arch/um/kernel/process.c | 7 +++--
arch/um/os-Linux/signal.c | 3 --
arch/um/os-Linux/time.c | 54 +++++++++-------------------------------------
4 files changed, 17 insertions(+), 52 deletions(-)
Index: linux-2.6.20/arch/um/os-Linux/time.c
===================================================================
--- linux-2.6.20.orig/arch/um/os-Linux/time.c 2007-09-19 12:25:07.000000000 -0400
+++ linux-2.6.20/arch/um/os-Linux/time.c 2007-09-19 12:25:08.000000000 -0400
@@ -12,8 +12,6 @@
#include "os.h"
#include "user.h"
-static int is_real_timer = 0;
-
int set_interval(void)
{
int usec = 1000000/UM_HZ;
@@ -53,47 +51,15 @@ static inline unsigned long long tv_to_n
tv->tv_usec * 1000;
}
-void disable_timer(void)
+unsigned long long disable_timer(void)
{
- struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
+ struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
- if ((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
- (setitimer(ITIMER_REAL, &disable, NULL) < 0))
+ if(setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
printk(UM_KERN_ERR "disable_timer - setitimer failed, "
"errno = %d\n", errno);
-}
-
-int switch_timers(int to_real)
-{
- struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
- struct itimerval enable;
- int old, new, old_type = is_real_timer;
-
- if(to_real == old_type)
- return to_real;
-
- if (to_real) {
- old = ITIMER_VIRTUAL;
- new = ITIMER_REAL;
- }
- else {
- old = ITIMER_REAL;
- new = ITIMER_VIRTUAL;
- }
-
- if (setitimer(old, &disable, &enable) < 0)
- printk(UM_KERN_ERR "switch_timers - setitimer disable failed, "
- "errno = %d\n", errno);
-
- if((enable.it_value.tv_sec == 0) && (enable.it_value.tv_usec == 0))
- enable.it_value = enable.it_interval;
- if (setitimer(new, &enable, NULL))
- printk(UM_KERN_ERR "switch_timers - setitimer enable failed, "
- "errno = %d\n", errno);
-
- is_real_timer = to_real;
- return old_type;
+ return tv_to_nsec(&time.it_value);
}
unsigned long long os_nsecs(void)
@@ -104,11 +70,13 @@ unsigned long long os_nsecs(void)
return tv_to_nsec(&tv);
}
-void idle_sleep(int secs)
+extern void alarm_handler(int sig, struct sigcontext *sc);
+
+void idle_sleep(unsigned long long nsecs)
{
- struct timespec ts;
+ struct timespec ts = { .tv_sec = nsecs / BILLION,
+ .tv_nsec = nsecs % BILLION };
- ts.tv_sec = secs;
- ts.tv_nsec = 0;
- nanosleep(&ts, NULL);
+ if (nanosleep(&ts, &ts) == 0)
+ alarm_handler(SIGVTALRM, NULL);
}
Index: linux-2.6.20/arch/um/os-Linux/signal.c
===================================================================
--- linux-2.6.20.orig/arch/um/os-Linux/signal.c 2007-09-19 12:25:06.000000000 -0400
+++ linux-2.6.20/arch/um/os-Linux/signal.c 2007-09-19 12:25:08.000000000 -0400
@@ -120,7 +120,6 @@ void (*handlers[_NSIG])(int sig, struct
void handle_signal(int sig, struct sigcontext *sc)
{
unsigned long pending = 0;
- int timer = switch_timers(0);
do {
int nested, bail;
@@ -157,8 +156,6 @@ void handle_signal(int sig, struct sigco
if (!nested)
pending = from_irq_stack(nested);
} while (pending);
-
- switch_timers(timer);
}
extern void hard_handler(int sig);
Index: linux-2.6.20/arch/um/kernel/process.c
===================================================================
--- linux-2.6.20.orig/arch/um/kernel/process.c 2007-09-19 12:25:07.000000000 -0400
+++ linux-2.6.20/arch/um/kernel/process.c 2007-09-19 12:25:08.000000000 -0400
@@ -235,6 +235,8 @@ void initial_thread_cb(void (*proc)(void
void default_idle(void)
{
+ unsigned long long nsecs;
+
while(1) {
/* endless idle loop with no priority at all */
@@ -246,9 +248,8 @@ void default_idle(void)
schedule();
tick_nohz_stop_sched_tick();
- switch_timers(1);
- idle_sleep(10);
- switch_timers(0);
+ nsecs = disable_timer();
+ idle_sleep(nsecs);
tick_nohz_restart_sched_tick();
}
}
Index: linux-2.6.20/arch/um/include/os.h
===================================================================
--- linux-2.6.20.orig/arch/um/include/os.h 2007-09-19 12:25:07.000000000 -0400
+++ linux-2.6.20/arch/um/include/os.h 2007-09-19 12:25:08.000000000 -0400
@@ -251,11 +251,10 @@ extern void os_dump_core(void);
/* time.c */
#define BILLION (1000 * 1000 * 1000)
-extern int switch_timers(int to_real);
-extern void idle_sleep(int secs);
+extern void idle_sleep(unsigned long long nsecs);
extern int set_interval(void);
extern int timer_one_shot(int ticks);
-extern void disable_timer(void);
+extern unsigned long long disable_timer(void);
extern void uml_idle_timer(void);
extern unsigned long long os_nsecs(void);
next reply other threads:[~2007-09-19 17:02 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-19 17:02 Jeff Dike [this message]
2007-09-19 17:02 ` [PATCH 9/11] UML - Eliminate interrupts in the idle loop Jeff Dike
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070919170229.GA10202@c2.user-mode-linux.org \
--to=jdike@addtoit.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=user-mode-linux-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.