NAME
rasctl
- restartable atomic sequences
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
int
rasctl(
void *addr
, size_t len
, int op
)
DESCRIPTION
Restartable atomic sequences are code sequences which are guaranteed
to execute without preemption.
This property is assured by the kernel
by re-executing a preempted sequence from the start.
This functionality enables applications to build atomic sequences which,
when executed to completion, will have executed atomically.
Restartable atomic sequences are intended to be used on systems that
do not have hardware support for low-overhead atomic primitives.
The
rasctl
function manipulates a process's set of restartable atomic sequences.
If a restartable atomic sequence is registered and the process is
preempted within the range
addr
and
addr
+
len
,
then the process is resumed at
addr
.
As the process execution can be rolled-back, the code in the sequence
should have no side effects other than a final store at
addr
+
len
-1.
The kernel does not guarantee that the sequences are successfully
restartable.
It assumes that the application knows what it is doing.
Restartable atomic sequences should adhere to the following guidelines:
-
have a single entry point and a single exit point;
-
not execute emulated instructions; and
-
not invoke any functions or system calls.
Restartable atomic sequences are inherited from the parent by the
child during the
fork(2)
operation.
Restartable atomic sequences for a process are removed during
exec(3).
The operations that can be applied to a restartable atomic sequence
are specified by the
op
argument.
Possible operations are:
RAS_INSTALL
-
Install this sequence.
RAS_PURGE
-
Remove the specified registered sequence for this process.
RAS_PURGE_ALL
-
Remove all registered sequences for this process.
The
RAS_PURGE
and
RAS_PURGE_ALL
operations should be considered to have
undefined behaviour if there are any other runnable threads in the
address space which might be executing within the restartable atomic
sequence(s) at the time of the purge.
The caller must be responsible for ensuring that there is some form of
coordination with other threads to prevent unexpected behaviour.
To preserve the atomicity of sequences, the kernel attempts to protect
the sequences from alteration by the
ptrace(2)
facility.
RETURN VALUES
Upon successful completion,
rasctl(
)
returns zero.
Otherwise, -1 is returned and
errno
is set to indicate the error.
ERRORS
The
rasctl
function will fail if:
- [
EINVAL
] -
Invalid input was supplied, such as an invalid operation, an invalid
address, or an invalid length.
A process may have a finite number of
atomic sequences that is defined at compile time.
- [
EOPNOTSUPP
] -
Restartable atomic sequences are not supported by the kernel.
- [
ESRCH
] -
Restartable atomic sequence not registered.
SEE ALSO
ptrace(2)
HISTORY
The
rasctl
functionality first appeared in
NetBSD2.0
based on a similar interface that appeared in Mach 2.5.
CAVEATS
Modern compilers reorder instruction sequences to optimize speed.
The start address and size of a
RAS
need to be protected against this.
One level of protection is created by compiler dependent instructions,
abstracted from user level code via the following macros:
RAS_DECL(name)
-
Declares the start and end labels used internally by the
other macros to mark a
RAS.
The name uniquely identifies the
RAS.
RAS_START(name)
-
Marks the start of the code.
Each restart returns to the instruction following this macro.
RAS_END(name)
-
Marks the end of the restartable code.
RAS_ADDR(name)
-
Returns the start address of a
RAS
and is used to create the first argument to
.
RAS_SIZE(name)
-
Returns the size of a
RAS
and is used as second argument to
.
Recent versions of
gcc(1)
require the
-fno-reorder-blocks
flag to prevent blocks of code wrapped with
RAS_START
/
RAS_END
being moved outside these labels.
However, be aware that this may not always be sufficient to prevent
gcc(1)
from generating non-restartable code within the
RAS
due to register clobbers.
It is, therefore, strongly recommended that restartable atomic sequences
are coded in assembly.
RAS
blocks within assembly code can be specified by using the following macros:
RAS_START_ASM(name)
-
Similar to
RAS_START
but for use in assembly source code.
RAS_END_ASM(name)
-
Similar to
RAS_END
but for use in assembly source code.
RAS_START_ASM_HIDDEN(name)
-
Similar to
RAS_START_ASM
except that the symbol will not be placed in the dynamic symbol table.
RAS_END_ASM_HIDDEN(name)
-
Similar to
RAS_END_ASM
except that the symbol will not be placed in the dynamic symbol table.