source: rtems/cpukit/posix/src/clocknanosleep.c @ 0a645dad

Last change on this file since 0a645dad was 0a645dad, checked in by Joel Sherrill <joel@…>, on 02/16/22 at 22:31:50

cpukit/posix/src/[a-o]*.c: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup POSIXAPI
7 *
8 * @brief Suspends Execution of calling thread until Time elapses
9 */
10
11/*
12 *  COPYRIGHT (c) 1989-2015.
13 *  On-Line Applications Research Corporation (OAR).
14 *
15 *  Copyright (c) 2016. Gedare Bloom.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#ifdef HAVE_CONFIG_H
40#include "config.h"
41#endif
42
43#include <time.h>
44
45#include <rtems/score/threadimpl.h>
46#include <rtems/score/threadqimpl.h>
47#include <rtems/score/timespec.h>
48#include <rtems/score/timecounter.h>
49#include <rtems/score/watchdogimpl.h>
50#include <rtems/posix/posixapi.h>
51
52static Thread_queue_Control _Nanosleep_Pseudo_queue =
53  THREAD_QUEUE_INITIALIZER( "Nanosleep" );
54
55/*
56 * High Resolution Sleep with Specifiable Clock, IEEE Std 1003.1, 2001
57 */
58int clock_nanosleep(
59  clockid_t               clock_id,
60  int                     flags,
61  const struct timespec  *rqtp,
62  struct timespec        *rmtp
63)
64{
65  Thread_queue_Context queue_context;
66  bool                 absolute;
67  Thread_Control      *executing;
68  int                  eno;
69
70  if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
71    return ENOTSUP;
72  }
73
74  _Thread_queue_Context_initialize( &queue_context );
75  _Thread_queue_Context_set_thread_state(
76    &queue_context,
77    STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
78  );
79
80  if ( ( flags & TIMER_ABSTIME ) != 0 ) {
81    absolute = true;
82    rmtp = NULL;
83  } else {
84    absolute = false;
85  }
86
87  if ( clock_id == CLOCK_REALTIME ) {
88    _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
89      &queue_context,
90      rqtp,
91      absolute
92    );
93  } else {
94    _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
95      &queue_context,
96      rqtp,
97      absolute
98    );
99  }
100
101  _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
102  executing = _Thread_Executing;
103  _Thread_queue_Enqueue(
104    &_Nanosleep_Pseudo_queue.Queue,
105    &_Thread_queue_Operations_FIFO,
106    executing,
107    &queue_context
108  );
109  eno = _POSIX_Get_error_after_wait( executing );
110
111  if ( eno == ETIMEDOUT ) {
112    eno = 0;
113  }
114
115  if ( rmtp != NULL ) {
116#if defined( RTEMS_POSIX_API )
117    if ( eno == EINTR ) {
118      struct timespec actual_end;
119      struct timespec planned_end;
120
121      if ( clock_id == CLOCK_REALTIME ) {
122        _Timecounter_Nanotime( &actual_end );
123      } else {
124        _Timecounter_Nanouptime( &actual_end );
125      }
126
127      _Watchdog_Ticks_to_timespec(
128        executing->Timer.Watchdog.expire,
129        &planned_end
130      );
131
132      if ( _Timespec_Less_than( &actual_end, &planned_end ) ) {
133        _Timespec_Subtract( &actual_end, &planned_end, rmtp );
134      } else {
135        _Timespec_Set_to_zero( rmtp );
136      }
137    } else {
138      _Timespec_Set_to_zero( rmtp );
139    }
140#else
141    _Assert( eno != EINTR );
142    _Timespec_Set_to_zero( rmtp );
143#endif
144  }
145
146  return eno;
147}
Note: See TracBrowser for help on using the repository browser.