source: rtems/cpukit/posix/src/nanosleep.c @ 874297f3

4.104.114.84.9
Last change on this file since 874297f3 was 874297f3, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 16, 2004 at 10:01:03 AM

Remove stray white spaces.

  • Property mode set to 100644
File size: 2.2 KB
Line 
1/*
2 *  $Id$
3 */
4
5#if HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#include <assert.h>
10#include <time.h>
11#include <errno.h>
12
13#include <rtems/system.h>
14#include <rtems/score/isr.h>
15#include <rtems/score/thread.h>
16#include <rtems/score/tod.h>
17
18#include <rtems/seterr.h>
19#include <rtems/posix/time.h>
20
21/*PAGE
22 *
23 *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
24 */
25
26int nanosleep(
27  const struct timespec  *rqtp,
28  struct timespec        *rmtp
29)
30{
31  Watchdog_Interval  ticks;
32  struct timespec   *the_rqtp;
33
34  if ( !rqtp )
35    rtems_set_errno_and_return_minus_one( EINVAL );
36
37  the_rqtp = (struct timespec *)rqtp;
38
39  /*
40   *  Return EAGAIN if the delay interval is negative.
41   *
42   *  NOTE:  This behavior is beyond the POSIX specification.
43   *         FSU pthreads shares this behavior.
44   */
45
46  if ( the_rqtp->tv_sec < 0 )
47    the_rqtp->tv_sec = 0;
48
49  if ( /* the_rqtp->tv_sec < 0 || */ the_rqtp->tv_nsec < 0 )
50    rtems_set_errno_and_return_minus_one( EAGAIN );
51
52  if ( the_rqtp->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
53    rtems_set_errno_and_return_minus_one( EINVAL );
54
55  ticks = _POSIX_Timespec_to_interval( the_rqtp );
56
57  /*
58   *  This behavior is also beyond the POSIX specification but is
59   *  consistent with the RTEMS api and yields desirable behavior.
60   */
61
62  if ( !ticks ) {
63    _Thread_Disable_dispatch();
64      _Thread_Yield_processor();
65    _Thread_Enable_dispatch();
66    if ( rmtp ) {
67       rmtp->tv_sec = 0;
68       rmtp->tv_nsec = 0;
69    }
70    return 0;
71  }
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    _POSIX_Interval_to_timespec( ticks, rmtp );
94
95    /*
96     *  If there is time remaining, then we were interrupted by a signal.
97     */
98
99    if ( ticks )
100      rtems_set_errno_and_return_minus_one( EINTR );
101  }
102
103  return 0;
104}
Note: See TracBrowser for help on using the repository browser.