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

4.104.115
Last change on this file since e7de563a was e7de563a, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 14, 2009 at 12:14:22 AM

2009-09-13 Joel Sherrill <joel.sherrill@…>

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