2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
11 #include <sys/resource.h>
16 #include <errno_private.h>
17 #include <syscall_utils.h>
23 clock_getres(clockid_t clockID
, struct timespec
* resolution
)
29 case CLOCK_PROCESS_CPUTIME_ID
:
30 case CLOCK_THREAD_CPUTIME_ID
:
34 RETURN_AND_SET_ERRNO(EINVAL
);
36 // For clock IDs we can't otherwise verify, try to get the time.
37 if (clockID
!= getpid()) {
39 if (clock_gettime(clockID
, &dummy
) != 0)
44 // currently resolution is always 1us
45 if (resolution
!= NULL
) {
46 resolution
->tv_sec
= 0;
47 resolution
->tv_nsec
= 1000;
55 clock_gettime(clockid_t clockID
, struct timespec
* time
)
57 // get the time in microseconds
58 bigtime_t microSeconds
;
62 microSeconds
= system_time();
65 microSeconds
= real_time_clock_usecs();
67 case CLOCK_PROCESS_CPUTIME_ID
:
68 case CLOCK_THREAD_CPUTIME_ID
:
71 status_t error
= _kern_get_clock(clockID
, µSeconds
);
73 RETURN_AND_SET_ERRNO(error
);
78 time
->tv_sec
= microSeconds
/ 1000000;
79 time
->tv_nsec
= (microSeconds
% 1000000) * 1000;
86 clock_settime(clockid_t clockID
, const struct timespec
* time
)
88 // can't set the monotonic clock
89 if (clockID
== CLOCK_MONOTONIC
)
90 RETURN_AND_SET_ERRNO(EINVAL
);
92 // check timespec validity
93 if (time
->tv_sec
< 0 || time
->tv_nsec
< 0 || time
->tv_nsec
>= 1000000000)
94 RETURN_AND_SET_ERRNO(EINVAL
);
96 // convert to microseconds and set the clock
97 bigtime_t microSeconds
= (bigtime_t
)time
->tv_sec
* 1000000
98 + time
->tv_nsec
/ 1000;
100 RETURN_AND_SET_ERRNO(_kern_set_clock(clockID
, microSeconds
));
105 clock_nanosleep(clockid_t clockID
, int flags
, const struct timespec
* time
,
106 struct timespec
* remainingTime
)
108 // convert time to microseconds (round up)
109 if (time
->tv_sec
< 0 || time
->tv_nsec
< 0 || time
->tv_nsec
>= 1000000000)
110 RETURN_AND_TEST_CANCEL(EINVAL
);
112 bigtime_t microSeconds
= (bigtime_t
)time
->tv_sec
* 1000000
113 + (time
->tv_nsec
+ 999) / 1000;
117 if ((flags
& TIMER_ABSTIME
) != 0) {
118 timeoutFlags
= B_ABSOLUTE_TIMEOUT
;
120 // ignore remainingTime for absolute waits
121 remainingTime
= NULL
;
123 timeoutFlags
= B_RELATIVE_TIMEOUT
;
126 bigtime_t remainingMicroSeconds
;
127 status_t error
= _kern_snooze_etc(microSeconds
, clockID
, timeoutFlags
,
128 remainingTime
!= NULL
? &remainingMicroSeconds
: NULL
);
130 // If interrupted and this is a relative wait, compute and return the
131 // remaining wait time.
132 if (error
== B_INTERRUPTED
&& remainingTime
!= NULL
) {
133 if (remainingMicroSeconds
> 0) {
134 remainingTime
->tv_sec
= remainingMicroSeconds
/ 1000000;
135 remainingTime
->tv_nsec
= (remainingMicroSeconds
% 1000000) * 1000;
137 // We were slow enough that the wait time passed anyway.
142 RETURN_AND_TEST_CANCEL(error
);
147 clock_getcpuclockid(pid_t pid
, clockid_t
* _clockID
)
152 // The CPU clock ID for a process is simply the team ID. For pid == 0 we're
153 // supposed to return the current process' clock.
155 *_clockID
= getpid();
159 // test-get the time to verify the team exists and we have permission
160 bigtime_t microSeconds
;
161 status_t error
= _kern_get_clock(pid
, µSeconds
);
163 // Since pid is > 0, B_BAD_VALUE always means a team with that ID
164 // doesn't exist. Translate the error code accordingly.
165 if (error
== B_BAD_VALUE
)