blob: a16a0f484edc8f3fa517c7e2d8a479ef6f2624c3 [file] [log] [blame]
Gennady Sharapovcff65c42006-01-18 17:42:42 -08001/*
Jeff Dike4c9e1382007-10-16 01:26:54 -07002 * Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com)
Gennady Sharapovcff65c42006-01-18 17:42:42 -08003 * Licensed under the GPL
4 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005
Jeff Dike4c9e1382007-10-16 01:26:54 -07006#include <stddef.h>
7#include <errno.h>
8#include <signal.h>
Gennady Sharapovcff65c42006-01-18 17:42:42 -08009#include <time.h>
10#include <sys/time.h>
Gennady Sharapovcff65c42006-01-18 17:42:42 -080011#include "kern_constants.h"
12#include "os.h"
Jeff Dike4c9e1382007-10-16 01:26:54 -070013#include "user.h"
Gennady Sharapovcff65c42006-01-18 17:42:42 -080014
Jeff Dike181bde82007-10-16 01:27:22 -070015static int is_real_timer = 0;
16
Jeff Dike537ae942006-09-25 23:33:05 -070017int set_interval(int is_virtual)
Gennady Sharapovcff65c42006-01-18 17:42:42 -080018{
Jeff Dike532d0fa2007-10-16 01:27:21 -070019 int usec = 1000000/UM_HZ;
Jeff Dike537ae942006-09-25 23:33:05 -070020 int timer_type = is_virtual ? ITIMER_VIRTUAL : ITIMER_REAL;
Gennady Sharapovcff65c42006-01-18 17:42:42 -080021 struct itimerval interval = ((struct itimerval) { { 0, usec },
22 { 0, usec } });
23
Jeff Dike4c9e1382007-10-16 01:26:54 -070024 if (setitimer(timer_type, &interval, NULL) == -1)
Jeff Dike537ae942006-09-25 23:33:05 -070025 return -errno;
26
27 return 0;
Gennady Sharapovcff65c42006-01-18 17:42:42 -080028}
29
Gennady Sharapovcff65c42006-01-18 17:42:42 -080030void disable_timer(void)
31{
32 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
Jeff Dike4c9e1382007-10-16 01:26:54 -070033
34 if ((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
35 (setitimer(ITIMER_REAL, &disable, NULL) < 0))
36 printk(UM_KERN_ERR "disable_timer - setitimer failed, "
37 "errno = %d\n", errno);
38
Gennady Sharapovcff65c42006-01-18 17:42:42 -080039 /* If there are signals already queued, after unblocking ignore them */
Jeff Dike4b84c692006-09-25 23:33:04 -070040 signal(SIGALRM, SIG_IGN);
41 signal(SIGVTALRM, SIG_IGN);
Gennady Sharapovcff65c42006-01-18 17:42:42 -080042}
43
Jeff Dike181bde82007-10-16 01:27:22 -070044int switch_timers(int to_real)
Gennady Sharapovcff65c42006-01-18 17:42:42 -080045{
46 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
Jeff Dike181bde82007-10-16 01:27:22 -070047 struct itimerval enable;
48 int old, new, old_type = is_real_timer;
49
50 if(to_real == old_type)
51 return to_real;
Gennady Sharapovcff65c42006-01-18 17:42:42 -080052
Jeff Dike4c9e1382007-10-16 01:26:54 -070053 if (to_real) {
Gennady Sharapovcff65c42006-01-18 17:42:42 -080054 old = ITIMER_VIRTUAL;
55 new = ITIMER_REAL;
56 }
57 else {
58 old = ITIMER_REAL;
59 new = ITIMER_VIRTUAL;
60 }
61
Jeff Dike181bde82007-10-16 01:27:22 -070062 if (setitimer(old, &disable, &enable) < 0)
63 printk(UM_KERN_ERR "switch_timers - setitimer disable failed, "
Jeff Dike4c9e1382007-10-16 01:26:54 -070064 "errno = %d\n", errno);
Jeff Dike181bde82007-10-16 01:27:22 -070065
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, "
71 "errno = %d\n", errno);
72
73 is_real_timer = to_real;
74 return old_type;
Gennady Sharapovcff65c42006-01-18 17:42:42 -080075}
76
Gennady Sharapovcff65c42006-01-18 17:42:42 -080077unsigned long long os_nsecs(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070078{
79 struct timeval tv;
80
81 gettimeofday(&tv, NULL);
Jeff Dike4c9e1382007-10-16 01:26:54 -070082 return (unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083}
84
Gennady Sharapovcff65c42006-01-18 17:42:42 -080085void idle_sleep(int secs)
86{
87 struct timespec ts;
88
89 ts.tv_sec = secs;
90 ts.tv_nsec = 0;
91 nanosleep(&ts, NULL);
92}