1 /*****************************************************************************
2 * clock_nanosleep.c: POSIX clock_nanosleep() replacement
3 *****************************************************************************
4 * Copyright © 2020 VLC authors and VideoLAN
6 * Author: Marvin Scholz <epirat07 at gmail dot com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
31 #include <sys/errno.h>
32 #include <sys/types.h>
34 #include <sys/sysctl.h>
35 #include <mach/clock_types.h>
37 int clock_nanosleep(clockid_t clock_id
, int flags
,
38 const struct timespec
*rqtp
, struct timespec
*rmtp
)
41 if (rqtp
== NULL
|| rqtp
->tv_sec
< 0 ||
42 rqtp
->tv_nsec
< 0 || (unsigned long)rqtp
->tv_nsec
>= NSEC_PER_SEC
) {
57 if (flags
== TIMER_ABSTIME
) {
58 struct timespec ts_rel
;
59 struct timespec ts_now
;
62 // Get current time with requested clock
63 if (clock_gettime(clock_id
, &ts_now
) != 0)
66 // Calculate relative timespec
67 ts_rel
.tv_sec
= rqtp
->tv_sec
- ts_now
.tv_sec
;
68 ts_rel
.tv_nsec
= rqtp
->tv_nsec
- ts_now
.tv_nsec
;
69 if (ts_rel
.tv_nsec
< 0) {
71 ts_rel
.tv_nsec
+= NSEC_PER_SEC
;
74 // Check if time already elapsed
75 if (ts_rel
.tv_sec
< 0 || (ts_rel
.tv_sec
== 0 && ts_rel
.tv_nsec
== 0)) {
80 // "The absolute clock_nanosleep() function has no effect on the
81 // structure referenced by rmtp", so do not pass rmtp here
82 } while (nanosleep(&ts_rel
, NULL
) == 0);
84 // If nanosleep failed or was interrupted by a signal,
85 // return so the caller can handle it appropriately
87 } else if (flags
== 0) {
88 return nanosleep(rqtp
, rmtp
);