diff options
Diffstat (limited to 'arch/um/os-Linux/time.c')
-rw-r--r-- | arch/um/os-Linux/time.c | 127 |
1 files changed, 28 insertions, 99 deletions
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 0e39b9978729..6d94ff52362c 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
@@ -26,11 +26,11 @@ static inline long long timeval_to_ns(const struct timeval *tv) | |||
26 | 26 | ||
27 | static inline long long timespec_to_ns(const struct timespec *ts) | 27 | static inline long long timespec_to_ns(const struct timespec *ts) |
28 | { | 28 | { |
29 | return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + | 29 | return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec; |
30 | ts->tv_nsec; | ||
31 | } | 30 | } |
32 | 31 | ||
33 | long long os_persistent_clock_emulation (void) { | 32 | long long os_persistent_clock_emulation(void) |
33 | { | ||
34 | struct timespec realtime_tp; | 34 | struct timespec realtime_tp; |
35 | 35 | ||
36 | clock_gettime(CLOCK_REALTIME, &realtime_tp); | 36 | clock_gettime(CLOCK_REALTIME, &realtime_tp); |
@@ -40,94 +40,41 @@ long long os_persistent_clock_emulation (void) { | |||
40 | /** | 40 | /** |
41 | * os_timer_create() - create an new posix (interval) timer | 41 | * os_timer_create() - create an new posix (interval) timer |
42 | */ | 42 | */ |
43 | int os_timer_create(void* timer) { | 43 | int os_timer_create(void) |
44 | 44 | { | |
45 | timer_t* t = timer; | 45 | timer_t *t = &event_high_res_timer; |
46 | |||
47 | if(t == NULL) { | ||
48 | t = &event_high_res_timer; | ||
49 | } | ||
50 | 46 | ||
51 | if (timer_create( | 47 | if (timer_create(CLOCK_MONOTONIC, NULL, t) == -1) |
52 | CLOCK_MONOTONIC, | ||
53 | NULL, | ||
54 | t) == -1) { | ||
55 | return -1; | 48 | return -1; |
56 | } | 49 | |
57 | return 0; | 50 | return 0; |
58 | } | 51 | } |
59 | 52 | ||
60 | int os_timer_set_interval(void* timer, void* i) | 53 | int os_timer_set_interval(unsigned long long nsecs) |
61 | { | 54 | { |
62 | struct itimerspec its; | 55 | struct itimerspec its; |
63 | unsigned long long nsec; | ||
64 | timer_t* t = timer; | ||
65 | struct itimerspec* its_in = i; | ||
66 | |||
67 | if(t == NULL) { | ||
68 | t = &event_high_res_timer; | ||
69 | } | ||
70 | 56 | ||
71 | nsec = UM_NSEC_PER_SEC / UM_HZ; | 57 | its.it_value.tv_sec = nsecs / UM_NSEC_PER_SEC; |
58 | its.it_value.tv_nsec = nsecs % UM_NSEC_PER_SEC; | ||
72 | 59 | ||
73 | if(its_in != NULL) { | 60 | its.it_interval.tv_sec = nsecs / UM_NSEC_PER_SEC; |
74 | its.it_value.tv_sec = its_in->it_value.tv_sec; | 61 | its.it_interval.tv_nsec = nsecs % UM_NSEC_PER_SEC; |
75 | its.it_value.tv_nsec = its_in->it_value.tv_nsec; | ||
76 | } else { | ||
77 | its.it_value.tv_sec = 0; | ||
78 | its.it_value.tv_nsec = nsec; | ||
79 | } | ||
80 | 62 | ||
81 | its.it_interval.tv_sec = 0; | 63 | if (timer_settime(event_high_res_timer, 0, &its, NULL) == -1) |
82 | its.it_interval.tv_nsec = nsec; | ||
83 | |||
84 | if(timer_settime(*t, 0, &its, NULL) == -1) { | ||
85 | return -errno; | 64 | return -errno; |
86 | } | ||
87 | 65 | ||
88 | return 0; | 66 | return 0; |
89 | } | 67 | } |
90 | 68 | ||
91 | /** | 69 | int os_timer_one_shot(unsigned long long nsecs) |
92 | * os_timer_remain() - returns the remaining nano seconds of the given interval | ||
93 | * timer | ||
94 | * Because this is the remaining time of an interval timer, which correspondends | ||
95 | * to HZ, this value can never be bigger than one second. Just | ||
96 | * the nanosecond part of the timer is returned. | ||
97 | * The returned time is relative to the start time of the interval timer. | ||
98 | * Return an negative value in an error case. | ||
99 | */ | ||
100 | long os_timer_remain(void* timer) | ||
101 | { | 70 | { |
102 | struct itimerspec its; | 71 | struct itimerspec its = { |
103 | timer_t* t = timer; | 72 | .it_value.tv_sec = nsecs / UM_NSEC_PER_SEC, |
104 | 73 | .it_value.tv_nsec = nsecs % UM_NSEC_PER_SEC, | |
105 | if(t == NULL) { | ||
106 | t = &event_high_res_timer; | ||
107 | } | ||
108 | |||
109 | if(timer_gettime(t, &its) == -1) { | ||
110 | return -errno; | ||
111 | } | ||
112 | 74 | ||
113 | return its.it_value.tv_nsec; | 75 | .it_interval.tv_sec = 0, |
114 | } | 76 | .it_interval.tv_nsec = 0, // we cheat here |
115 | 77 | }; | |
116 | int os_timer_one_shot(int ticks) | ||
117 | { | ||
118 | struct itimerspec its; | ||
119 | unsigned long long nsec; | ||
120 | unsigned long sec; | ||
121 | |||
122 | nsec = (ticks + 1); | ||
123 | sec = nsec / UM_NSEC_PER_SEC; | ||
124 | nsec = nsec % UM_NSEC_PER_SEC; | ||
125 | |||
126 | its.it_value.tv_sec = nsec / UM_NSEC_PER_SEC; | ||
127 | its.it_value.tv_nsec = nsec; | ||
128 | |||
129 | its.it_interval.tv_sec = 0; | ||
130 | its.it_interval.tv_nsec = 0; // we cheat here | ||
131 | 78 | ||
132 | timer_settime(event_high_res_timer, 0, &its, NULL); | 79 | timer_settime(event_high_res_timer, 0, &its, NULL); |
133 | return 0; | 80 | return 0; |
@@ -135,24 +82,13 @@ int os_timer_one_shot(int ticks) | |||
135 | 82 | ||
136 | /** | 83 | /** |
137 | * os_timer_disable() - disable the posix (interval) timer | 84 | * os_timer_disable() - disable the posix (interval) timer |
138 | * Returns the remaining interval timer time in nanoseconds | ||
139 | */ | 85 | */ |
140 | long long os_timer_disable(void) | 86 | void os_timer_disable(void) |
141 | { | 87 | { |
142 | struct itimerspec its; | 88 | struct itimerspec its; |
143 | 89 | ||
144 | memset(&its, 0, sizeof(struct itimerspec)); | 90 | memset(&its, 0, sizeof(struct itimerspec)); |
145 | timer_settime(event_high_res_timer, 0, &its, &its); | 91 | timer_settime(event_high_res_timer, 0, &its, NULL); |
146 | |||
147 | return its.it_value.tv_sec * UM_NSEC_PER_SEC + its.it_value.tv_nsec; | ||
148 | } | ||
149 | |||
150 | long long os_vnsecs(void) | ||
151 | { | ||
152 | struct timespec ts; | ||
153 | |||
154 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&ts); | ||
155 | return timespec_to_ns(&ts); | ||
156 | } | 92 | } |
157 | 93 | ||
158 | long long os_nsecs(void) | 94 | long long os_nsecs(void) |
@@ -169,21 +105,14 @@ long long os_nsecs(void) | |||
169 | */ | 105 | */ |
170 | void os_idle_sleep(unsigned long long nsecs) | 106 | void os_idle_sleep(unsigned long long nsecs) |
171 | { | 107 | { |
172 | struct timespec ts; | 108 | struct timespec ts = { |
173 | 109 | .tv_sec = nsecs / UM_NSEC_PER_SEC, | |
174 | if (nsecs <= 0) { | 110 | .tv_nsec = nsecs % UM_NSEC_PER_SEC |
175 | return; | 111 | }; |
176 | } | ||
177 | |||
178 | ts = ((struct timespec) { | ||
179 | .tv_sec = nsecs / UM_NSEC_PER_SEC, | ||
180 | .tv_nsec = nsecs % UM_NSEC_PER_SEC | ||
181 | }); | ||
182 | 112 | ||
183 | /* | 113 | /* |
184 | * Relay the signal if clock_nanosleep is interrupted. | 114 | * Relay the signal if clock_nanosleep is interrupted. |
185 | */ | 115 | */ |
186 | if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL)) { | 116 | if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL)) |
187 | deliver_alarm(); | 117 | deliver_alarm(); |
188 | } | ||
189 | } | 118 | } |