/**************************************************************************** * sched/signal/sig_nanosleep.c * * SPDX-License-Identifier: Apache-2.0 * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "clock/clock.h" /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: nxsig_nanosleep * * Description: * The nxsig_nanosleep() function causes the current thread to be * suspended from execution until either the time interval specified by * the rqtp argument has elapsed or a signal is delivered to the calling * thread and its action is to invoke a signal-catching function or to * terminate the process. The suspension time may be longer than requested * because the argument value is rounded up to an integer multiple of the * sleep resolution or because of the scheduling of other activity by the * system. But, except for the case of being interrupted by a signal, the * suspension time will not be less than the time specified by rqtp, as * measured by the system clock, CLOCK_REALTIME. * * The use of the nxsig_nanosleep() function has no effect on the action * or blockage of any signal. * * Input Parameters: * rqtp - The amount of time to be suspended from execution. * rmtp - If the rmtp argument is non-NULL, the timespec structure * referenced by it is updated to contain the amount of time * remaining in the interval (the requested time minus the time * actually slept) * * Returned Value: * If the nxsig_nanosleep() function returns because the requested time * has elapsed, its return value is zero. * * If the nxsig_nanosleep() function returns because it has been * interrupted by a signal, the function returns a negated errno value * indicate the interruption. If the rmtp argument is non-NULL, the * timespec structure referenced by it is updated to contain the amount * of time remaining in the interval (the requested time minus the time * actually slept). If the rmtp argument is NULL, the remaining time is * not returned. * * If nxsig_nanosleep() fails, it returns a negated errno indicating the * cause of the failure. The nxsig_nanosleep() function will fail if: * * EINTR - The nxsig_nanosleep() function was interrupted by a signal. * EINVAL - The rqtp argument specified a nanosecond value less than * zero or greater than or equal to 1000 million. * ENOSYS - The nxsig_nanosleep() function is not supported by this * implementation. * ****************************************************************************/ int nxsig_nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) { int ret; ret = nxsig_clockwait(CLOCK_REALTIME, 0, rqtp, rmtp); return ret == -EAGAIN ? 0 : ret; } /**************************************************************************** * Name: clock_nanosleep * * Description: * If the flag TIMER_ABSTIME is not set in the flags argument, the * clock_nanosleep() function will cause the current thread to be suspended * from execution until either the time interval specified by the rqtp * argument has elapsed, or a signal is delivered to the calling thread * and its action is to invoke a signal-catching function, or the process * is terminated. The clock used to measure the time will be the clock * specified by clock_id. * * If the flag TIMER_ABSTIME is set in the flags argument, the * clock_nanosleep() function will cause the current thread to be * suspended from execution until either the time value of the clock * specified by clock_id reaches the absolute time specified by the rqtp * argument, or a signal is delivered to the calling thread and its action * is to invoke a signal-catching function, or the process is terminated. * If, at the time of the call, the time value specified by rqtp is less * than or equal to the time value of the specified clock, then * clock_nanosleep() will return immediately and the calling process will * not be suspended. * * The suspension time caused by this function may be longer than requested * because the argument value is rounded up to an integer multiple of the * sleep resolution, or because of the scheduling of other activity by the * system. But, except for the case of being interrupted by a signal, the * suspension time for the relative clock_nanosleep() function (that is, * with the TIMER_ABSTIME flag not set) will not be less than the time * interval specified by rqtp, as measured by the corresponding clock. The * suspension for the absolute clock_nanosleep() function (that is, with * the TIMER_ABSTIME flag set) will be in effect at least until the value * of the corresponding clock reaches the absolute time specified by rqtp, * except for the case of being interrupted by a signal. * * The use of the clock_nanosleep() function will have no effect on the * action or blockage of any signal. * * The clock_nanosleep() function will fail if the clock_id argument refers * to the CPU-time clock of the calling thread. It is unspecified whether * clock_id values of other CPU-time clocks are allowed. * * Input Parameters: * clockid - The clock to use to interpret the absolute time * flags - Open flags. TIMER_ABSTIME is the only supported flag. * rqtp - The amount of time to be suspended from execution. * rmtp - If the rmtp argument is non-NULL, the timespec structure * referenced by it is updated to contain the amount of time * remaining in the interval (the requested time minus the time * actually slept) * * Returned Value: * If the clock_nanosleep() function returns because the requested time has * elapsed, its return value is zero. * * If the clock_nanosleep() function returns because it has been * interrupted by a signal, the function returns a value of -1 and sets * errno to indicate the interruption. If the rmtp argument is non-NULL, * the timespec structure referenced by it is updated to contain the amount * of time remaining in the interval (the requested time minus the time * actually slept). If the rmtp argument is NULL, the remaining time is not * returned. * * If clock_nanosleep() fails, it returns a value of errno. The * clock_nanosleep() function will fail if: * * EINTR - The clock_nanosleep() function was interrupted by a signal. * EINVAL - The rqtp argument specified a nanosecond value less than * zero or greater than or equal to 1000 million. Or the clockid that * does not specify a known clock. * ENOSYS - The clock_nanosleep() function is not supported by this * implementation. * ****************************************************************************/ int clock_nanosleep(clockid_t clockid, int flags, FAR const struct timespec *rqtp, FAR struct timespec *rmtp) { int ret; /* clock_nanosleep() is a cancellation point */ enter_cancellation_point(); if (clockid < CLOCK_REALTIME || clockid > CLOCK_BOOTTIME) { leave_cancellation_point(); return EINVAL; } /* Just a wrapper around nxsig_clockwait() */ ret = nxsig_clockwait(clockid, flags, rqtp, rmtp); /* Check if nxsig_clockwait() succeeded */ if (ret == -EAGAIN) { ret = OK; } else if (ret < 0) { /* If not return the errno */ ret = -ret; } leave_cancellation_point(); return ret; }