source: rtems/c/src/exec/posix/src/nanosleep.c @ 811fae1

4.104.114.84.95
Last change on this file since 811fae1 was 9f95a19, checked in by Joel Sherrill <joel.sherrill@…>, on 11/02/99 at 18:35:52

Split time.c into multiple files.

  • Property mode set to 100644
File size: 2.1 KB
Line 
1/*
2 *  $Id$
3 */
4
5#include <assert.h>
6#include <time.h>
7#include <errno.h>
8
9#include <rtems/system.h>
10#include <rtems/score/isr.h>
11#include <rtems/score/thread.h>
12#include <rtems/score/tod.h>
13
14#include <rtems/posix/seterr.h>
15#include <rtems/posix/time.h>
16
17/*PAGE
18 *
19 *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
20 */
21
22int nanosleep(
23  const struct timespec  *rqtp,
24  struct timespec        *rmtp
25)
26{
27  Watchdog_Interval  ticks;
28  struct timespec   *the_rqtp;
29
30  if ( !rqtp )
31    set_errno_and_return_minus_one( EINVAL );
32
33  the_rqtp = (struct timespec *)rqtp;
34
35  /*
36   *  Return EAGAIN if the delay interval is negative. 
37   *
38   *  NOTE:  This behavior is beyond the POSIX specification. 
39   *         FSU pthreads shares this behavior.
40   */
41
42  if ( the_rqtp->tv_sec < 0 )
43    the_rqtp->tv_sec = 0;
44
45  if ( /* the_rqtp->tv_sec < 0 || */ the_rqtp->tv_nsec < 0 )
46    set_errno_and_return_minus_one( EAGAIN );
47
48  if ( the_rqtp->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
49    set_errno_and_return_minus_one( EINVAL );
50 
51  ticks = _POSIX_Timespec_to_interval( the_rqtp );
52
53  /*
54   *  This behavior is also beyond the POSIX specification but is
55   *  consistent with the RTEMS api and yields desirable behavior.
56   */
57
58  if ( !ticks ) {
59    _Thread_Disable_dispatch();
60      _Thread_Yield_processor();
61    _Thread_Enable_dispatch();
62    if ( rmtp ) {
63       rmtp->tv_sec = 0;
64       rmtp->tv_nsec = 0;
65    }
66    return 0;
67  }
68 
69  _Thread_Disable_dispatch();
70    _Thread_Set_state(
71      _Thread_Executing,
72      STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
73    );
74    _Watchdog_Initialize(
75      &_Thread_Executing->Timer,
76      _Thread_Delay_ended,
77      _Thread_Executing->Object.id,
78      NULL
79    );
80    _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
81  _Thread_Enable_dispatch();
82
83  /* calculate time remaining */
84
85  if ( rmtp ) {
86    ticks -=
87      _Thread_Executing->Timer.stop_time - _Thread_Executing->Timer.start_time;
88
89    _POSIX_Interval_to_timespec( ticks, rmtp );
90
91    /*
92     *  If there is time remaining, then we were interrupted by a signal.
93     */
94
95    if ( ticks )
96      set_errno_and_return_minus_one( EINTR );
97  }
98
99  return 0;
100}
Note: See TracBrowser for help on using the repository browser.