source: rtems/cpukit/posix/src/nanosleep.c @ 6eba7c85

4.115
Last change on this file since 6eba7c85 was 6eba7c85, checked in by Sebastian Huber <sebastian.huber@…>, on 06/10/13 at 14:15:46

scheduler: Specify thread of yield operation

The yielding thread of the yield operation is now specified by a
parameter. The tick operation may be performed for each executing
thread in a SMP configuration.

  • 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/system.h>
25#include <rtems/score/isr.h>
26#include <rtems/score/scheduler.h>
27#include <rtems/score/thread.h>
28#include <rtems/score/tod.h>
29
30#include <rtems/seterr.h>
31#include <rtems/score/timespec.h>
32
33/*
34 *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
35 */
36
37int nanosleep(
38  const struct timespec  *rqtp,
39  struct timespec        *rmtp
40)
41{
42  /*
43   * It is critical to obtain the executing thread after thread dispatching is
44   * disabled on SMP configurations.
45   */
46  Thread_Control *executing;
47
48  Watchdog_Interval  ticks;
49
50
51  /*
52   *  Return EINVAL if the delay interval is negative.
53   *
54   *  NOTE:  This behavior is beyond the POSIX specification.
55   *         FSU and GNU/Linux pthreads shares this behavior.
56   */
57  if ( !_Timespec_Is_valid( rqtp ) )
58    rtems_set_errno_and_return_minus_one( EINVAL );
59
60  ticks = _Timespec_To_ticks( rqtp );
61
62  /*
63   *  A nanosleep for zero time is implemented as a yield.
64   *  This behavior is also beyond the POSIX specification but is
65   *  consistent with the RTEMS API and yields desirable behavior.
66   */
67
68  if ( !ticks ) {
69    _Thread_Disable_dispatch();
70      executing = _Thread_Executing;
71      _Scheduler_Yield( executing );
72    _Thread_Enable_dispatch();
73    if ( rmtp ) {
74       rmtp->tv_sec = 0;
75       rmtp->tv_nsec = 0;
76    }
77    return 0;
78  }
79
80  /*
81   *  Block for the desired amount of time
82   */
83  _Thread_Disable_dispatch();
84    executing = _Thread_Executing;
85    _Thread_Set_state(
86      executing,
87      STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
88    );
89    _Watchdog_Initialize(
90      &executing->Timer,
91      _Thread_Delay_ended,
92      executing->Object.id,
93      NULL
94    );
95    _Watchdog_Insert_ticks( &executing->Timer, ticks );
96  _Thread_Enable_dispatch();
97
98  /* calculate time remaining */
99
100  if ( rmtp ) {
101    ticks -= executing->Timer.stop_time - executing->Timer.start_time;
102
103    _Timespec_From_ticks( ticks, rmtp );
104
105    /*
106     *  Only when POSIX is enabled, can a sleep be interrupted.
107     */
108    #if defined(RTEMS_POSIX_API)
109        /*
110         *  If there is time remaining, then we were interrupted by a signal.
111         */
112        if ( ticks )
113          rtems_set_errno_and_return_minus_one( EINTR );
114    #endif
115  }
116
117  return 0;
118}
Note: See TracBrowser for help on using the repository browser.