X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fos-Linux%2Ftime.c;h=2115b8beb54167ffe9c522a5fbe6727b1e547137;hb=refs%2Fheads%2Fvserver;hp=cf30a39bc4841a58ec27d0a1863732c4a4ee1ebd;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index cf30a39bc..2115b8beb 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -1,21 +1,102 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include #include +#include +#include #include +#include +#include +#include "user_util.h" +#include "kern_util.h" +#include "user.h" +#include "process.h" +#include "kern_constants.h" +#include "os.h" +#include "uml-config.h" + +int set_interval(int is_virtual) +{ + int usec = 1000000/hz(); + int timer_type = is_virtual ? ITIMER_VIRTUAL : ITIMER_REAL; + struct itimerval interval = ((struct itimerval) { { 0, usec }, + { 0, usec } }); + + if(setitimer(timer_type, &interval, NULL) == -1) + return -errno; + + return 0; +} + +#ifdef UML_CONFIG_MODE_TT +void enable_timer(void) +{ + set_interval(1); +} +#endif + +void disable_timer(void) +{ + struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); + if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) || + (setitimer(ITIMER_REAL, &disable, NULL) < 0)) + printk("disnable_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); +} -unsigned long long os_usecs(void) +void switch_timers(int to_real) +{ + struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); + struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() }, + { 0, 1000000/hz() }}); + int old, new; + + if(to_real){ + old = ITIMER_VIRTUAL; + new = ITIMER_REAL; + } + else { + old = ITIMER_REAL; + new = ITIMER_VIRTUAL; + } + + if((setitimer(old, &disable, NULL) < 0) || + (setitimer(new, &enable, NULL))) + printk("switch_timers - setitimer failed, errno = %d\n", + errno); +} + +#ifdef UML_CONFIG_MODE_TT +void uml_idle_timer(void) +{ + if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) + panic("Couldn't unset SIGVTALRM handler"); + + set_handler(SIGALRM, (__sighandler_t) alarm_handler, + SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + set_interval(0); +} +#endif + +unsigned long long os_nsecs(void) { struct timeval tv; gettimeofday(&tv, NULL); - return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec); + return((unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000); } -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ +void idle_sleep(int secs) +{ + struct timespec ts; + + ts.tv_sec = secs; + ts.tv_nsec = 0; + nanosleep(&ts, NULL); +}