source: rtems/cpukit/posix/src/nanosleep.c @ 88c74ab

4.115
Last change on this file since 88c74ab was 88c74ab, checked in by Sebastian Huber <sebastian.huber@…>, on 07/25/13 at 13:10:11

score: Merge tod implementation into one file

Delete TOD_MICROSECONDS_PER_SECOND, TOD_MICROSECONDS_TO_TICKS() and
TOD_MILLISECONDS_TO_TICKS().

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Suspends Execution of calling thread until Time elaps
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2007.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <time.h>
22#include <errno.h>
23
24#include <rtems/seterr.h>
25#include <rtems/score/schedulerimpl.h>
26#include <rtems/score/threadimpl.h>
27#include <rtems/score/timespec.h>
28#include <rtems/score/watchdogimpl.h>
29
30/*
31 *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
32 */
33
34int nanosleep(
35  const struct timespec  *rqtp,
36  struct timespec        *rmtp
37)
38{
39  /*
40   * It is critical to obtain the executing thread after thread dispatching is
41   * disabled on SMP configurations.
42   */
43  Thread_Control *executing;
44
45  Watchdog_Interval  ticks;
46
47
48  /*
49   *  Return EINVAL if the delay interval is negative.
50   *
51   *  NOTE:  This behavior is beyond the POSIX specification.
52   *         FSU and GNU/Linux pthreads shares this behavior.
53   */
54  if ( !_Timespec_Is_valid( rqtp ) )
55    rtems_set_errno_and_return_minus_one( EINVAL );
56
57  ticks = _Timespec_To_ticks( rqtp );
58
59  /*
60   *  A nanosleep for zero time is implemented as a yield.
61   *  This behavior is also beyond the POSIX specification but is
62   *  consistent with the RTEMS API and yields desirable behavior.
63   */
64
65  if ( !ticks ) {
66    _Thread_Disable_dispatch();
67      executing = _Thread_Executing;
68      _Scheduler_Yield( executing );
69    _Thread_Enable_dispatch();
70    if ( rmtp ) {
71       rmtp->tv_sec = 0;
72       rmtp->tv_nsec = 0;
73    }
74    return 0;
75  }
76
77  /*
78   *  Block for the desired amount of time
79   */
80  _Thread_Disable_dispatch();
81    executing = _Thread_Executing;
82    _Thread_Set_state(
83      executing,
84      STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
85    );
86    _Watchdog_Initialize(
87      &executing->Timer,
88      _Thread_Delay_ended,
89      executing->Object.id,
90      NULL
91    );
92    _Watchdog_Insert_ticks( &executing->Timer, ticks );
93  _Thread_Enable_dispatch();
94
95  /* calculate time remaining */
96
97  if ( rmtp ) {
98    ticks -= executing->Timer.stop_time - executing->Timer.start_time;
99
100    _Timespec_From_ticks( ticks, rmtp );
101
102    /*
103     *  Only when POSIX is enabled, can a sleep be interrupted.
104     */
105    #if defined(RTEMS_POSIX_API)
106        /*
107         *  If there is time remaining, then we were interrupted by a signal.
108         */
109        if ( ticks )
110          rtems_set_errno_and_return_minus_one( EINTR );
111    #endif
112  }
113
114  return 0;
115}
Note: See TracBrowser for help on using the repository browser.