UML - Eliminate ticking in the idle loop
PATCH 9/11 UML - Eliminate ticking in the idle loop
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.
--
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 | 58 ++++++++-------------------------------------- 4 files changed, 17 insertions(+), 56 deletions(-)
arch/um/os-Linux/time.c +11 -47
@@ -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,51 +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); -/* If there are signals already queued, after unblocking ignore them */ -signal (SIGALRM ,SIG_IGN ); -signal (SIGVTALRM ,SIG_IGN ); -} - -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 )
@@ -108,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 ); }
arch/um/os-Linux/signal.c +0 -3
@@ -120,7 +120,6 @@ void (*handlers[_NSIG])(int sig, structvoid 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 sigcoif (!nested) pending =from_irq_stack (nested); }while (pending); - -switch_timers (timer); }extern void hard_handler (int sig);
arch/um/kernel/process.c +4 -3
@@ -235,6 +235,8 @@ void initial_thread_cb(void (*proc)(voidvoid 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 (); } }
arch/um/include/os.h +2 -3
@@ -252,11 +252,10 @@ extern void os_log_info(char *fmt, va_li/* 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 [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel