| 67 |
67 |
* timers when they expire.
|
| 68 |
68 |
*/
|
| 69 |
69 |
|
| 70 |
|
static int nanosleep1 (struct timespec *rqt,
|
| 71 |
|
struct timespec *rmt);
|
| 72 |
|
static int settime (struct timeval *);
|
| 73 |
|
static void timevalfix (struct timeval *);
|
|
70 |
static int nanosleep1(struct timespec *rqt, struct timespec *rmt);
|
|
71 |
static int settime(struct timeval *);
|
|
72 |
static void timevalfix(struct timeval *);
|
| 74 |
73 |
|
| 75 |
74 |
static int sleep_hard_us = 100;
|
| 76 |
75 |
SYSCTL_INT(_kern, OID_AUTO, sleep_hard_us, CTLFLAG_RW, &sleep_hard_us, 0, "")
|
| ... | ... | |
| 140 |
139 |
return (0);
|
| 141 |
140 |
}
|
| 142 |
141 |
|
| 143 |
|
/* ARGSUSED */
|
| 144 |
142 |
int
|
| 145 |
|
sys_clock_gettime(struct clock_gettime_args *uap)
|
|
143 |
kern_clock_gettime(clockid_t clock_id, struct timespec *ats)
|
| 146 |
144 |
{
|
| 147 |
|
struct timespec ats;
|
| 148 |
|
|
| 149 |
|
switch(uap->clock_id) {
|
|
145 |
switch(clock_id) {
|
| 150 |
146 |
case CLOCK_REALTIME:
|
| 151 |
|
nanotime(&ats);
|
| 152 |
|
return (copyout(&ats, uap->tp, sizeof(ats)));
|
|
147 |
nanotime(ats);
|
| 153 |
148 |
case CLOCK_MONOTONIC:
|
| 154 |
|
nanouptime(&ats);
|
| 155 |
|
return (copyout(&ats, uap->tp, sizeof(ats)));
|
|
149 |
nanouptime(ats);
|
| 156 |
150 |
default:
|
| 157 |
151 |
return (EINVAL);
|
| 158 |
152 |
}
|
|
153 |
|
|
154 |
return (0);
|
| 159 |
155 |
}
|
| 160 |
156 |
|
| 161 |
157 |
/* ARGSUSED */
|
| 162 |
158 |
int
|
| 163 |
|
sys_clock_settime(struct clock_settime_args *uap)
|
|
159 |
sys_clock_gettime(struct clock_gettime_args *uap)
|
|
160 |
{
|
|
161 |
struct timespec ats;
|
|
162 |
int error;
|
|
163 |
|
|
164 |
error = kern_clock_gettime(uap->clock_id, &ats);
|
|
165 |
if (error == 0)
|
|
166 |
error = copyout(&ats, uap->tp, sizeof(ats))
|
|
167 |
|
|
168 |
return (error);
|
|
169 |
}
|
|
170 |
|
|
171 |
int
|
|
172 |
kern_clock_settime(clockid_t clock_id, struct timespec *ats)
|
| 164 |
173 |
{
|
| 165 |
174 |
struct thread *td = curthread;
|
| 166 |
175 |
struct timeval atv;
|
| 167 |
|
struct timespec ats;
|
| 168 |
176 |
int error;
|
| 169 |
177 |
|
| 170 |
178 |
if ((error = priv_check(td, PRIV_ROOT)) != 0)
|
| 171 |
179 |
return (error);
|
| 172 |
|
switch(uap->clock_id) {
|
| 173 |
|
case CLOCK_REALTIME:
|
| 174 |
|
if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
|
| 175 |
|
return (error);
|
| 176 |
|
if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
|
| 177 |
|
return (EINVAL);
|
| 178 |
|
/* XXX Don't convert nsec->usec and back */
|
| 179 |
|
TIMESPEC_TO_TIMEVAL(&atv, &ats);
|
| 180 |
|
error = settime(&atv);
|
| 181 |
|
return (error);
|
| 182 |
|
default:
|
|
180 |
if (clock_id != CLOCK_REALTIME)
|
| 183 |
181 |
return (EINVAL);
|
| 184 |
|
}
|
|
182 |
if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000)
|
|
183 |
return (EINVAL);
|
|
184 |
|
|
185 |
TIMESPEC_TO_TIMEVAL(&atv, ats);
|
|
186 |
error = settime(&atv);
|
|
187 |
return (error);
|
| 185 |
188 |
}
|
| 186 |
189 |
|
|
190 |
/* ARGSUSED */
|
| 187 |
191 |
int
|
| 188 |
|
sys_clock_getres(struct clock_getres_args *uap)
|
|
192 |
sys_clock_settime(struct clock_settime_args *uap)
|
| 189 |
193 |
{
|
| 190 |
|
struct timespec ts;
|
|
194 |
struct timespec ats;
|
|
195 |
int error;
|
|
196 |
|
|
197 |
if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
|
|
198 |
return (error);
|
|
199 |
|
|
200 |
return (kern_clock_settime(uap->clock_id, &ats));
|
|
201 |
}
|
| 191 |
202 |
|
| 192 |
|
switch(uap->clock_id) {
|
|
203 |
int
|
|
204 |
kern_clock_getres(clockid_t clock_id, struct timespec *ts)
|
|
205 |
{
|
|
206 |
switch(clock_id) {
|
| 193 |
207 |
case CLOCK_REALTIME:
|
| 194 |
208 |
case CLOCK_MONOTONIC:
|
| 195 |
209 |
/*
|
| ... | ... | |
| 198 |
212 |
* if rounding down would give 0. Perfect rounding
|
| 199 |
213 |
* is unimportant.
|
| 200 |
214 |
*/
|
| 201 |
|
ts.tv_sec = 0;
|
| 202 |
|
ts.tv_nsec = 1000000000 / sys_cputimer->freq + 1;
|
| 203 |
|
return(copyout(&ts, uap->tp, sizeof(ts)));
|
|
215 |
ts->tv_sec = 0;
|
|
216 |
ts->tv_nsec = 1000000000 / sys_cputimer->freq + 1;
|
| 204 |
217 |
default:
|
| 205 |
218 |
return(EINVAL);
|
| 206 |
219 |
}
|
|
220 |
|
|
221 |
return (0);
|
|
222 |
}
|
|
223 |
|
|
224 |
int
|
|
225 |
sys_clock_getres(struct clock_getres_args *uap)
|
|
226 |
{
|
|
227 |
int error;
|
|
228 |
struct timespec ts;
|
|
229 |
|
|
230 |
error = kern_clock_getres(uap->clock_id, &ts);
|
|
231 |
if (error == 0)
|
|
232 |
error = copyout(&ts, uap->tp, sizeof(ts));
|
|
233 |
|
|
234 |
return (error);
|
| 207 |
235 |
}
|
| 208 |
236 |
|
| 209 |
237 |
/*
|