forked from Imagelibrary/rtems
posix: Move clock_nanosleep()
Move clock_nanosleep() to a separate file to avoid a dependency on errno which pulls in the Newlib reentrancy support. This is an issue since most parts which are pulled in cannot be garbage collected by the linker due to the system initialization linker set.
This commit is contained in:
@@ -490,6 +490,7 @@ librtemscpu_a_SOURCES += posix/src/cleanuppush.c
|
||||
librtemscpu_a_SOURCES += posix/src/clockgetcpuclockid.c
|
||||
librtemscpu_a_SOURCES += posix/src/clockgetres.c
|
||||
librtemscpu_a_SOURCES += posix/src/clockgettime.c
|
||||
librtemscpu_a_SOURCES += posix/src/clocknanosleep.c
|
||||
librtemscpu_a_SOURCES += posix/src/clocksettime.c
|
||||
librtemscpu_a_SOURCES += posix/src/condattrdestroy.c
|
||||
librtemscpu_a_SOURCES += posix/src/condattrgetclock.c
|
||||
|
||||
116
cpukit/posix/src/clocknanosleep.c
Normal file
116
cpukit/posix/src/clocknanosleep.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup POSIXAPI
|
||||
*
|
||||
* @brief Suspends Execution of calling thread until Time elapses
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2015.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Copyright (c) 2016. Gedare Bloom.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
#include <rtems/score/timespec.h>
|
||||
#include <rtems/score/timecounter.h>
|
||||
#include <rtems/score/watchdogimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
static Thread_queue_Control _Nanosleep_Pseudo_queue =
|
||||
THREAD_QUEUE_INITIALIZER( "Nanosleep" );
|
||||
|
||||
/*
|
||||
* High Resolution Sleep with Specifiable Clock, IEEE Std 1003.1, 2001
|
||||
*/
|
||||
int clock_nanosleep(
|
||||
clockid_t clock_id,
|
||||
int flags,
|
||||
const struct timespec *rqtp,
|
||||
struct timespec *rmtp
|
||||
)
|
||||
{
|
||||
Thread_queue_Context queue_context;
|
||||
struct timespec uptime;
|
||||
const struct timespec *end;
|
||||
Thread_Control *executing;
|
||||
int eno;
|
||||
|
||||
if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_set_thread_state(
|
||||
&queue_context,
|
||||
STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
|
||||
);
|
||||
|
||||
if ( ( flags & TIMER_ABSTIME ) != 0 ) {
|
||||
end = rqtp;
|
||||
|
||||
if ( clock_id == CLOCK_REALTIME ) {
|
||||
_Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
);
|
||||
} else {
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
);
|
||||
}
|
||||
} else {
|
||||
_Timecounter_Nanouptime( &uptime );
|
||||
end = _Watchdog_Future_timespec( &uptime, rqtp );
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
);
|
||||
}
|
||||
|
||||
_Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
|
||||
executing = _Thread_Executing;
|
||||
_Thread_queue_Enqueue(
|
||||
&_Nanosleep_Pseudo_queue.Queue,
|
||||
&_Thread_queue_Operations_FIFO,
|
||||
executing,
|
||||
&queue_context
|
||||
);
|
||||
eno = _POSIX_Get_error_after_wait( executing );
|
||||
|
||||
if ( eno == ETIMEDOUT ) {
|
||||
eno = 0;
|
||||
}
|
||||
|
||||
if ( rmtp != NULL && ( flags & TIMER_ABSTIME ) == 0 ) {
|
||||
if ( eno == EINTR ) {
|
||||
struct timespec actual_end;
|
||||
|
||||
_Timecounter_Nanouptime( &actual_end );
|
||||
|
||||
if ( _Timespec_Less_than( &actual_end, end ) ) {
|
||||
_Timespec_Subtract( &actual_end, end, rmtp );
|
||||
} else {
|
||||
_Timespec_Set_to_zero( rmtp );
|
||||
}
|
||||
} else {
|
||||
_Timespec_Set_to_zero( rmtp );
|
||||
}
|
||||
}
|
||||
|
||||
return eno;
|
||||
}
|
||||
@@ -23,17 +23,8 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
#include <rtems/score/timespec.h>
|
||||
#include <rtems/score/timecounter.h>
|
||||
#include <rtems/score/watchdogimpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
static Thread_queue_Control _Nanosleep_Pseudo_queue =
|
||||
THREAD_QUEUE_INITIALIZER( "Nanosleep" );
|
||||
|
||||
/*
|
||||
* 14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
|
||||
*/
|
||||
@@ -52,85 +43,3 @@ int nanosleep(
|
||||
|
||||
return eno;
|
||||
}
|
||||
|
||||
/*
|
||||
* High Resolution Sleep with Specifiable Clock, IEEE Std 1003.1, 2001
|
||||
*/
|
||||
int clock_nanosleep(
|
||||
clockid_t clock_id,
|
||||
int flags,
|
||||
const struct timespec *rqtp,
|
||||
struct timespec *rmtp
|
||||
)
|
||||
{
|
||||
Thread_queue_Context queue_context;
|
||||
struct timespec uptime;
|
||||
const struct timespec *end;
|
||||
Thread_Control *executing;
|
||||
int eno;
|
||||
|
||||
if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_set_thread_state(
|
||||
&queue_context,
|
||||
STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
|
||||
);
|
||||
|
||||
if ( ( flags & TIMER_ABSTIME ) != 0 ) {
|
||||
end = rqtp;
|
||||
|
||||
if ( clock_id == CLOCK_REALTIME ) {
|
||||
_Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
);
|
||||
} else {
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
);
|
||||
}
|
||||
} else {
|
||||
_Timecounter_Nanouptime( &uptime );
|
||||
end = _Watchdog_Future_timespec( &uptime, rqtp );
|
||||
_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
|
||||
&queue_context,
|
||||
end
|
||||
);
|
||||
}
|
||||
|
||||
_Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
|
||||
executing = _Thread_Executing;
|
||||
_Thread_queue_Enqueue(
|
||||
&_Nanosleep_Pseudo_queue.Queue,
|
||||
&_Thread_queue_Operations_FIFO,
|
||||
executing,
|
||||
&queue_context
|
||||
);
|
||||
eno = _POSIX_Get_error_after_wait( executing );
|
||||
|
||||
if ( eno == ETIMEDOUT ) {
|
||||
eno = 0;
|
||||
}
|
||||
|
||||
if ( rmtp != NULL && ( flags & TIMER_ABSTIME ) == 0 ) {
|
||||
if ( eno == EINTR ) {
|
||||
struct timespec actual_end;
|
||||
|
||||
_Timecounter_Nanouptime( &actual_end );
|
||||
|
||||
if ( _Timespec_Less_than( &actual_end, end ) ) {
|
||||
_Timespec_Subtract( &actual_end, end, rmtp );
|
||||
} else {
|
||||
_Timespec_Set_to_zero( rmtp );
|
||||
}
|
||||
} else {
|
||||
_Timespec_Set_to_zero( rmtp );
|
||||
}
|
||||
}
|
||||
|
||||
return eno;
|
||||
}
|
||||
|
||||
@@ -990,6 +990,7 @@ source:
|
||||
- cpukit/posix/src/clockgetcpuclockid.c
|
||||
- cpukit/posix/src/clockgetres.c
|
||||
- cpukit/posix/src/clockgettime.c
|
||||
- cpukit/posix/src/clocknanosleep.c
|
||||
- cpukit/posix/src/clocksettime.c
|
||||
- cpukit/posix/src/condattrdestroy.c
|
||||
- cpukit/posix/src/condattrgetclock.c
|
||||
|
||||
Reference in New Issue
Block a user