NAME
rasctl —
restartable atomic
sequences
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <sys/types.h>
#include <sys/ras.h>
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
NetBSD 2.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 rasctl.
-
-
RAS_SIZE(name)
- Returns the size of a RAS and is used as
second argument to rasctl.
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.