File indexing completed on 2025-05-11 08:24:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifdef HAVE_CONFIG_H
0040 #include "config.h"
0041 #endif
0042
0043 #include <time.h>
0044
0045 #include <rtems/score/threadimpl.h>
0046 #include <rtems/score/threadqimpl.h>
0047 #include <rtems/score/timespec.h>
0048 #include <rtems/score/timecounter.h>
0049 #include <rtems/score/watchdogimpl.h>
0050 #include <rtems/posix/posixapi.h>
0051
0052 static Thread_queue_Control _Nanosleep_Pseudo_queue =
0053 THREAD_QUEUE_INITIALIZER( "Nanosleep" );
0054
0055
0056
0057
0058 int clock_nanosleep(
0059 clockid_t clock_id,
0060 int flags,
0061 const struct timespec *rqtp,
0062 struct timespec *rmtp
0063 )
0064 {
0065 Thread_queue_Context queue_context;
0066 bool absolute;
0067 Thread_Control *executing;
0068 int eno;
0069
0070 if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
0071 return ENOTSUP;
0072 }
0073
0074 _Thread_queue_Context_initialize( &queue_context );
0075 _Thread_queue_Context_set_thread_state(
0076 &queue_context,
0077 STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
0078 );
0079
0080 if ( ( flags & TIMER_ABSTIME ) != 0 ) {
0081 absolute = true;
0082 rmtp = NULL;
0083 } else {
0084 absolute = false;
0085
0086
0087
0088
0089
0090
0091
0092
0093 clock_id = CLOCK_MONOTONIC;
0094 }
0095
0096 if ( clock_id == CLOCK_REALTIME ) {
0097 _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
0098 &queue_context,
0099 rqtp,
0100 absolute
0101 );
0102 } else {
0103 _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
0104 &queue_context,
0105 rqtp,
0106 absolute
0107 );
0108 }
0109
0110 _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
0111 executing = _Thread_Executing;
0112 _Thread_queue_Enqueue(
0113 &_Nanosleep_Pseudo_queue.Queue,
0114 &_Thread_queue_Operations_FIFO,
0115 executing,
0116 &queue_context
0117 );
0118 eno = _POSIX_Get_error_after_wait( executing );
0119
0120 if ( eno == ETIMEDOUT ) {
0121 eno = 0;
0122 }
0123
0124 if ( rmtp != NULL ) {
0125 #if defined( RTEMS_POSIX_API )
0126 if ( eno == EINTR ) {
0127 struct timespec actual_end;
0128 struct timespec planned_end;
0129
0130 _Assert( clock_id == CLOCK_MONOTONIC );
0131 _Timecounter_Nanouptime( &actual_end );
0132
0133 _Watchdog_Ticks_to_timespec(
0134 executing->Timer.Watchdog.expire,
0135 &planned_end
0136 );
0137
0138 if ( _Timespec_Less_than( &actual_end, &planned_end ) ) {
0139 _Timespec_Subtract( &actual_end, &planned_end, rmtp );
0140 } else {
0141 _Timespec_Set_to_zero( rmtp );
0142 }
0143 } else {
0144 _Timespec_Set_to_zero( rmtp );
0145 }
0146 #else
0147 _Assert( eno != EINTR );
0148 _Timespec_Set_to_zero( rmtp );
0149 #endif
0150 }
0151
0152 return eno;
0153 }