resched_cntl(2) CX/UX resched_cntl(2)
NAME
reschedcntl, reschednlocks, reschedlock, reschedunlock -
rescheduling control
SYNOPSIS
#include <sys/types.h>
#include <sys/time.h>
#include <sys/threadsynch.h>
int reschedcntl (cmd, arg)
int cmd;
char *arg;
int reschednlocks (r)
struct reschedvar *r;
void reschedlock (r)
struct reschedvar *r;
void reschedunlock (r)
struct reschedvar *r;
DESCRIPTION
Multi-thread, real-time applications frequently wish to
defer CPU rescheduling for brief periods of time. For exam-
ple, to use busy-wait mutual exclusion effectively (see
spintrylock(2)), spinlock hold times should be small and
predictable. CPU rescheduling is a source of unpredictabil-
ity. A thread would like to make itself immune to
rescheduling when it acquires a spinlock, and vulnerable
again when it releases the lock. A system call could raise
the caller's priority to the highest in the system, but the
overhead of doing so is prohibitive. The primitives
described here provide low overhead control of CPU
rescheduling and signal delivery.
A "rescheduling variable" is a data structure,
struct reschedvar {
pidt rvpid;
tidt rvtid;
...
};
defined in <sys/threadsynch.h>, that controls a single
thread's vulnerability to rescheduling. It is allocated on
a per-thread basis by the application, not by the kernel.
The reschedcntl system call informs the kernel of the loca-
tion of the variable, and the kernel examines the variable
before making rescheduling decisions. Direct manipulation
of the variable from user mode with the reschedlock and
reschedunlock macros disables and re-enables rescheduling.
Page 1 CX/UX Programmer's Reference Manual
resched_cntl(2) CX/UX resched_cntl(2)
For convenience, a rescheduling variable also contains the
owning thread's thread ID and process ID.
The reschedcntl system call performs different functions
depending on the value of cmd:
RESCHED_SET_VARIABLE
This command informs the kernel of the loca-
tion of the caller's rescheduling variable.
If arg is not NULL, the struct reschedvar it
points to is initialized and locked into phy-
sical memory. If arg is NULL, the caller is
disassociated from any existing variable, and
the appropriate pages are unlocked. No two
threads should use the same rescheduling
variable. After a fork(2), the child process
does NOT inherit a rescheduling variable from
its parent. Use of this command requires
ACC_SETPRI privilege, unless the caller is
the super-user.
RESCHED_GET_VARIABLE
This command returns the location of the
caller's rescheduling variable. Arg must
point to a rescheduling variable pointer.
The pointer referenced by arg is set to NULL
if the caller has no rescheduling variable,
and is set to the location of the reschedul-
ing variable otherwise.
RESCHED_SET_LIMIT
This command is a debugging tool. If arg is
not NULL, it points to a struct timeval
specifying the maximum length of time the
caller expects to defer rescheduling. The
SIGRESCHED signal is sent to the caller when
this limit is exceeded. The signal's default
action is to terminate the thread, but it may
also be ignored or caught. If arg is NULL
any previous limit is forgotten.
RESCHED_SERVE This command is used by reschedunlock to
service pending signals and context switches.
Applications should not need to use this com-
mand directly. Arg must be 0.
RESCHED_YIELD This command causes the calling process to
relinquish control of the CPU to other
equal-priority processes. If there are no
other processes of equal priority, the cal-
ling process retains control of the CPU. Arg
must be 0.
Page 2 CX/UX Programmer's Reference Manual
resched_cntl(2) CX/UX resched_cntl(2)
The reschednlocks macro returns the number of rescheduling
locks currently in effect.
The reschedlock macro increments the number of rescheduling
locks held by the calling thread. As long as the thread
does not enter the kernel, quantum expirations, preemptions,
and some signal deliveries are deferred until all reschedul-
ing locks are released. However, if the thread generates an
exception (e.g., a page fault) or makes a system call, it
may receive signals or otherwise context switch regardless
of the number of rescheduling locks it holds. The following
signals represent error conditions and are NOT affected by
rescheduling locks: SIGILL, SIGTRAP, SIGFPE, SIGKILL,
SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGXCPU, SIGXFSZ, and
SIGRESCHED.
The reschedunlock macro decrements the number of reschedul-
ing locks held by the calling thread. If there are no out-
standing locks after the decrement, and a context switch or
signal are pending, they are serviced immediately. No
checks are made to prevent the number of rescheduling locks
from becoming negative, which will happen if more
reschedunlock requests are made than reschedlock requests.
Applications concerned about this possibility should use
reschednlocks to make the appropriate assertions.
EXAMPLES
A rescheduling variable may be declared as a global vari-
able. After initialization with reschedcntl, reschedlock
and reschedunlock disable and re-enable rescheduling.
01 struct reschedvar rv;
02
03 void
04 main ()
05 {
06 reschedcntl (RESCHEDSETVARIABLE, &rv);
07
08 reschedlock (&rv);
09
10 /* non-preemptible code */
11 ...
12
13 assert (reschednlocks (&rv) > 0);
14 reschedunlock (&rv);
15 }
The assertion in line 13 may be a useful debugging tool.
RETURN VALUE
Reschedlock and reschedunlock do not return values.
Reschednlocks returns the number of rescheduling locks
Page 3 CX/UX Programmer's Reference Manual
resched_cntl(2) CX/UX resched_cntl(2)
currently in effect. Upon successful completion of
reschedcntl, 0 is returned. Otherwise, a value of -1 is
returned and errno is set to indicate the error.
ERRORS
reschedcntl will fail if any of the following are true:
[EINVAL] Cmd was not one of the values documented
above.
[EINVAL] An attempt was made to establish a reschedul-
ing variable when one already existed.
[EINVAL] An attempt was made to remove a rescheduling
variable when none existed.
[EINVAL] The struct timeval pointed to by arg was
invalid.
[EFAULT] Arg contains an invalid address.
SEE ALSO
CX/UX Programmer's Guide.
gettid(2), spintrylock(2), serverblock(2),
clientblock(2), assert(3X).
Page 4 CX/UX Programmer's Reference Manual