source: rtems/cpukit/posix/src/nanosleep.c @ cfe8f7a

5
Last change on this file since cfe8f7a was cfe8f7a, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/20 at 14:14:06

doxygen: Switch @brief and @ingroup

This order change fixes the Latex documentation build via Doxygen.

  • Property mode set to 100644
File size: 3.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup POSIXAPI
5 *
6 * @brief Suspends Execution of calling thread until Time elapses
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2015.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  Copyright (c) 2016. Gedare Bloom.
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.org/license/LICENSE.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <time.h>
25
26#include <rtems/score/threadimpl.h>
27#include <rtems/score/threadqimpl.h>
28#include <rtems/score/timespec.h>
29#include <rtems/score/timecounter.h>
30#include <rtems/score/watchdogimpl.h>
31#include <rtems/posix/posixapi.h>
32#include <rtems/seterr.h>
33
34static Thread_queue_Control _Nanosleep_Pseudo_queue =
35  THREAD_QUEUE_INITIALIZER( "Nanosleep" );
36
37/*
38 *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
39 */
40int nanosleep(
41  const struct timespec  *rqtp,
42  struct timespec        *rmtp
43)
44{
45  int eno;
46
47  eno = clock_nanosleep( CLOCK_REALTIME, 0, rqtp, rmtp );
48
49  if ( eno != 0 ) {
50    rtems_set_errno_and_return_minus_one( eno );
51  }
52
53  return eno;
54}
55
56/*
57 * High Resolution Sleep with Specifiable Clock, IEEE Std 1003.1, 2001
58 */
59int clock_nanosleep(
60  clockid_t               clock_id,
61  int                     flags,
62  const struct timespec  *rqtp,
63  struct timespec        *rmtp
64)
65{
66  Thread_queue_Context   queue_context;
67  struct timespec        uptime;
68  const struct timespec *end;
69  Thread_Control        *executing;
70  int                    eno;
71
72  if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
73    return ENOTSUP;
74  }
75
76  _Thread_queue_Context_initialize( &queue_context );
77  _Thread_queue_Context_set_thread_state(
78    &queue_context,
79    STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
80  );
81
82  if ( ( flags & TIMER_ABSTIME ) != 0 ) {
83    end = rqtp;
84
85    if ( clock_id == CLOCK_REALTIME ) {
86      _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
87        &queue_context,
88        end
89      );
90    } else {
91      _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
92        &queue_context,
93        end
94      );
95    }
96  } else {
97    _Timecounter_Nanouptime( &uptime );
98    end = _Watchdog_Future_timespec( &uptime, rqtp );
99    _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
100      &queue_context,
101      end
102    );
103  }
104
105  _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
106  executing = _Thread_Executing;
107  _Thread_queue_Enqueue(
108    &_Nanosleep_Pseudo_queue.Queue,
109    &_Thread_queue_Operations_FIFO,
110    executing,
111    &queue_context
112  );
113  eno = _POSIX_Get_error_after_wait( executing );
114
115  if ( eno == ETIMEDOUT ) {
116    eno = 0;
117  }
118
119  if ( rmtp != NULL && ( flags & TIMER_ABSTIME ) == 0 ) {
120    if ( eno == EINTR ) {
121      struct timespec actual_end;
122
123      _Timecounter_Nanouptime( &actual_end );
124
125      if ( _Timespec_Less_than( &actual_end, end ) ) {
126        _Timespec_Subtract( &actual_end, end, rmtp );
127      } else {
128        _Timespec_Set_to_zero( rmtp );
129      }
130    } else {
131      _Timespec_Set_to_zero( rmtp );
132    }
133  }
134
135  return eno;
136}
Note: See TracBrowser for help on using the repository browser.