xref: /openbsd-src/gnu/llvm/libcxx/include/__support/ibm/nanosleep.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
976d0caaeSpatrick 
10*4bdff4beSrobert #ifndef _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
11*4bdff4beSrobert #define _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
1276d0caaeSpatrick 
1376d0caaeSpatrick #include <unistd.h>
1476d0caaeSpatrick 
nanosleep(const struct timespec * __req,struct timespec * __rem)1576d0caaeSpatrick inline int nanosleep(const struct timespec* __req, struct timespec* __rem) {
1676d0caaeSpatrick   // The nanosleep() function is not available on z/OS. Therefore, we will call
1776d0caaeSpatrick   // sleep() to sleep for whole seconds and usleep() to sleep for any remaining
1876d0caaeSpatrick   // fraction of a second. Any remaining nanoseconds will round up to the next
1976d0caaeSpatrick   // microsecond.
2076d0caaeSpatrick   if (__req->tv_sec < 0 || __req->tv_nsec < 0 || __req->tv_nsec > 999999999) {
2176d0caaeSpatrick     errno = EINVAL;
2276d0caaeSpatrick     return -1;
2376d0caaeSpatrick   }
24*4bdff4beSrobert   long __micro_sec = (__req->tv_nsec + 999) / 1000;
2576d0caaeSpatrick   time_t __sec = __req->tv_sec;
2676d0caaeSpatrick   if (__micro_sec > 999999) {
2776d0caaeSpatrick     ++__sec;
2876d0caaeSpatrick     __micro_sec -= 1000000;
2976d0caaeSpatrick   }
30*4bdff4beSrobert   __sec = static_cast<time_t>(sleep(static_cast<unsigned int>(__sec)));
3176d0caaeSpatrick   if (__sec) {
3276d0caaeSpatrick     if (__rem) {
3376d0caaeSpatrick       // Updating the remaining time to sleep in case of unsuccessful call to sleep().
3476d0caaeSpatrick       __rem->tv_sec = __sec;
3576d0caaeSpatrick       __rem->tv_nsec = __micro_sec * 1000;
3676d0caaeSpatrick     }
3776d0caaeSpatrick     errno = EINTR;
3876d0caaeSpatrick     return -1;
3976d0caaeSpatrick   }
4076d0caaeSpatrick   if (__micro_sec) {
41*4bdff4beSrobert     int __rt = usleep(static_cast<unsigned int>(__micro_sec));
4276d0caaeSpatrick     if (__rt != 0 && __rem) {
4376d0caaeSpatrick       // The usleep() does not provide the amount of remaining time upon its failure,
4476d0caaeSpatrick       // so the time slept will be ignored.
4576d0caaeSpatrick       __rem->tv_sec = 0;
4676d0caaeSpatrick       __rem->tv_nsec = __micro_sec * 1000;
4776d0caaeSpatrick       // The errno is already set.
4876d0caaeSpatrick       return -1;
4976d0caaeSpatrick     }
5076d0caaeSpatrick     return __rt;
5176d0caaeSpatrick   }
5276d0caaeSpatrick   return 0;
5376d0caaeSpatrick }
5476d0caaeSpatrick 
55*4bdff4beSrobert #endif // _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
56