Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions docs/src/man/man3/rtapi_delay.3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

== NAME

rtapi_delay, rtapi_delay_max - Busy-loop for short delays
rtapi_delay, rtapi_delay_max - Short delays

== SYNTAX

Expand All @@ -22,17 +22,28 @@ nsec::
== DESCRIPTION

*rtapi_delay* is a simple delay.
It is intended only for short delays, since it simply loops, wasting CPU cycles.

*rtapi_delay_max* returns the max delay permitted (usually approximately 1/4 of the clock period).
It is intended only for short delays.
In RTAI kernel modules it busy-waits, wasting CPU cycles.
Everywhere else it sleeps: in uspace realtime modules through the realtime backend
(clock_nanosleep() on POSIX and Xenomai, evl_sleep_until() on EVL, rt_sleep() on RTAI),
in user processes with clock_nanosleep().
The calling thread may be scheduled out and wake up later than requested.

*rtapi_delay_max* returns the max delay permitted. The value is implementation dependent:
1/4 of the clock period in RTAI kernel modules (10 µs until the clock is set),
10 µs in uspace realtime modules, just under one second in user processes.
Any call to *rtapi_delay* requesting a delay longer than the max will delay for the max time only.

*rtapi_delay_max* should be called before using *rtapi_delay* to make sure the required delays can be achieved.
The actual resolution of the delay may be as good as one nano-second, or as bad as a several microseconds.

== REALTIME CONSIDERATIONS

May be called from init/cleanup code, and from within realtime tasks.
May be called from init/cleanup code.

Calling *rtapi_delay* from a realtime task, while possible, is very strongly discouraged.
Everywhere except in RTAI kernel modules it sleeps and may wake up considerably later than requested,
which throws off the realtime thread's timing.

== RETURN VALUE

Expand Down
17 changes: 11 additions & 6 deletions include/rtapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,26 +244,31 @@ RTAPI_BEGIN_DECLS
#endif /* RTAPI */

/**
* @brief Simple delay, intended only for short delays, since it simply loops,
* wasting CPU cycles.
* @brief Simple delay, intended only for short delays.
*
* In RTAI kernel modules it busy-waits, wasting CPU cycles. Everywhere else
* it sleeps: in uspace realtime modules through the realtime backend
* (clock_nanosleep() on POSIX and Xenomai, evl_sleep_until() on EVL,
* rt_sleep() on RTAI), in user processes with clock_nanosleep(). The calling
* thread may be scheduled out and wake up later than requested.
*
* Any call to rtapi_delay() requesting a delay longer than the max will delay
* for the max time only. rtapi_delay_max() should be called before using
* rtapi_delay() to make sure the required delays can be achieved. The actual
* resolution of the delay may be as good as one nano-second, or as bad as a
* several microseconds.
* @param nsec Desired delay in nano-seconds.
* @note This timing function is only available in realtime modules. User
* processes may not call them!
*/
extern void rtapi_delay(long int nsec);


/**
* @brief Returns the max delay permitted for rtapi_delay().
*
* The value is implementation dependent: 1/4 of the clock period in RTAI
* kernel modules (10 us until the clock is set), 10 us in uspace realtime
* modules, just under one second in user processes.
* @return Max delay permitted in nano-seconds.
* @note This timing function is only available in realtime modules. User
* processes may not call them!
*/
extern long int rtapi_delay_max(void);

Expand Down
2 changes: 2 additions & 0 deletions src/hal/hal_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,8 @@ const char *hal_strerror(int err)
case -EPROTO: return "hal data version mismatch";
case -EPERM: return "hal is locked";
case -ENOEXEC: return "missing constructor";
case -EALREADY: return "init cycle already executed";
case -EBUSY: return "in use by a running thread";
default: return "unknown error";
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/hal/utils/halcmd_commands.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ static int unloadrt_delf(const char *comp)
rv = hal_del_init_funct_from_thread(e.first.c_str(), e.second.c_str());
if(0 != rv) {
halcmd_error("init function '%s' not removed from thread '%s', error=%d (%s)\n",
e.first.c_str(), e.second.c_str(), rv, strerror(-rv));
e.first.c_str(), e.second.c_str(), rv, hal_strerror(rv));
return rv;
}
halcmd_info("Init function '%s' removed from thread '%s'\n",
Expand Down
Loading