mpcntl(3X) mpcntl(3X)
NAME
mpcntl - standard interface for multiprocessing
SYNOPSIS
cc [flag ...] file ... -lmproc
#include <sys/types.h>
#include <sys/mpcntl.h>
mpcntl(int req, void *arg);
DESCRIPTION
mpcntl() provides a number of multiprocessor services to application
programmers wishing to exploit this environment.
Binding: allows a process to explicitly bind itself to a particular
CPU. The binding may exclusive, where multiple processes are allowed
to bind to a single CPU, and all other processes not exclusively bound
are excluded. Or the alternative is the default situation, where mul-
tiple processes share one CPU (without excluding other processes).
Affinity Control: defeats or re-enables the default affinity policies
used by the kernel for scheduling a process in such a way as to try to
preserve its cache state. A process for which affinity has been
defeated will be available to any processor for scheduling.
Limited Scheduler Control: allows a process to temporarily suspend
preemption by other processes until the process blocks or re-enables
preemption. This also makes the process immune to all signals (except
SIGKILL). The process can also elect to give up, or yield, the CPU to
allow the system to schedule other processes. If the yielding process
has high enough priority, it will not be preempted.
CPU Status: returns the number of CPUs in the machine and information
on specific CPUs as requested. This also allows one to change the
state information of a CPU.
req specifies the service requested.
arg, a pointer which may be a null pointer for certain requests. In
most cases, arg is interpreted as a pointer to an mpcntl() request
structure. It is defined in mpcntl.h as follows:
typedef uintt cpumaskt;
typedef struct mpcreq {
cpumaskt mpccpu; /* CPU identifier */
pidt mpcpid; /* valid process ID */
} mpcreqt;
The field mpccpu is a cpumaskt (an int) in which each bit is used to
represent a logical CPU (bit 0 represents CPU 0, bit 1, CPU 1 etc.)
Page 1 Reliant UNIX 5.44 Printed 11/98
mpcntl(3X) mpcntl(3X)
This allows more than 1 CPU id to be passed on to the system at a
time. The macro CPUNOTOLCPUID can be used to convert between cpu
numbers and a bit in the cpumaskt mask. No requests require more than
1 CPU to be specified. The mcppid is a pidt set to a valid process
ID, as returned by a getpid() system call.
Inappropriate use of some of the mpcntl() operations could result in
degraded system performance or, in some cases, deadlocks. To prevent
naive uses, the user of these particular mpcntl() options must be
either the superuser (user ID 0) or have been granted specific
mpcntl() privileges by the superuser.
The following is a list of valid requests to mpcntl() and a descrip-
tion of arg for each:
MPCNTLBIND and MPCNTLBINDXCLU
Binds (or exclusively binds) a specified process to the specified
CPU(s). Exclusive binding is similar to regular binding except
that a CPU with one or more processes exclusively bound to it
will not execute any processes other than those in the bound set.
This provides a primitive form of CPU/process set management. arg
points to the data structure mpcreqt filled out to indicate the
target logical CPU(s) and a valid PID. MPCNTLBIND and
MPCNTLBINDXCLU will allow a process to bind to a set of CPUs if
multiple bits are set in mpccpu. This has the effect of reserv-
ing all processors in the bound set since it prevents those CPUs
from executing other processes that are not bound explicitly to
them. Thus, this should be used with extreme caution.
On asymmetric systems, care must be exercised to ensure that a
process is not being bound away from a resource that it needs
(for example, hardware floating point unit), since the system
will attempt to correct such conditions by altering or canceling
the binding. Upon successful return from the call, the process is
run on a CPU in the target set (for example, it is already
bound).
The binding attributes are inherited across fork(2) and exec(2)
system calls. These options may fail if a CPU in the target set
has been altered by MPCNTLCPUINFOSET to preclude the requested
operation (for example, if the CPU is marked as unavailable
(CPIFSNAVAIL) or if the type of binding requested is precluded
by CPIFSBINDOFF or CPIFSXBINDOFF).
MPCNTLBINDXCLU requires superuser privileges.
MPCNTLUNBIND
Effectively this is the inverse of MPCNTLBIND and
MPCNTLBINDXCLU since it unbinds the specified process from its
current CPU(s). If an exclusive binding is being removed and the
target process is the last process exclusively bound to one or
more CPUs, those processors then become public. arg points to the
Page 2 Reliant UNIX 5.44 Printed 11/98
mpcntl(3X) mpcntl(3X)
data structure mpcreqt, filled out to indicate the target PID.
Existing bindings may be altered by successive calls to
MPCNTLBIND and/or MPCNTLBINDXCLU. This allows old bindings to
be canceled and new bindings set up without calling
MPCNTLUNBIND.
MPCNTLAFFINOFF and MPCNTLAFFINON
Defeats or re-enables the normal affinity mechanisms which
attempt to weakly bind a process to the last CPU it ran on. A
process which has affinity turned off is eligible to run on the
next available CPU (still considering all normal priority lev-
els). arg points to the data structure mpcreqt, filled out to
indicate the target PID. The default state, MPCNTLAFFINON is
restored upon the issuance of an exec(2) system call but disabled
affinity is inherited across fork(2) system calls. These calls
are ineffectual if affinity is disabled through a system tunable
parameter.
MPCNTLNOPRMPT and MPCNTLPRMPT
Disables/enables the preemptability of the current process and
optionally makes the process immune to signals that it is catch-
ing. The intent of this option is to allow a process to run in a
critical region of user code without being preempted. A possible
application for this would be where a "spinlock" situation
applied. This behavior may be modified by argp which may take on
the values of:
MPCNTLNOPRMPTSIGS
The preemptability status of the process does not affect
signal handling (for example, held/ignored signals remain
held/ignored, caught signals will be processed, and ignored
signals will be ignored).
The process cannot be preempted whenever it is running. This
attribute persists across voluntary process blocking (for
example, system call) and involuntary blocking (for example,
page fault). If a non-preemptable process gives up the CPU,
it will then compete with other processes normally to obtain
access to a CPU. It then becomes once more non-preemptable
until it again blocks.
MPCNTLNOPRMPTNOSIGS
Masked, ignored or caught signals will affect the process'
signal handling. The unpreemptable behavior will apply only
until the kernel is involved (voluntarily by a system call
or involuntarily due to an exception). Interrupts do not
affect the preemptability of the process directly and are
not considered to be an involuntary entry into the kernel.
The first call to MPCNTLNOPRMPT results in a system call to
prime the mechanism. Subsequent MPCNTLPRMPT and
MPCNTLNOPRMPT calls result in library-only operations (for
example, the library simply updates the value of this
Page 3 Reliant UNIX 5.44 Printed 11/98
mpcntl(3X) mpcntl(3X)
location in user space without need for entering the operat-
ing system). This optimization is intended to make the
adjustment of process preemptability very fast. Upon suc-
cess, the call returns the previous preemptability status of
the process (>0 if not preemptable, 0 if preemptable) and
otherwise returns -1.
Extended privileges are required to use this option. This
attribute is not inherited across fork() or exec() system
calls.
MPCNTLGETFLAG
Returns the target process' mpcntl flags and binding information.
In this case, arg points to the mpcreqt data structure, which
specifies the target PID and the cpumaskt data structure that is
used to return the target process' binding information. Upon suc-
cess, MPCNTLGETFLAG returns the flags and the mpccpu field of
the structure pointed to by arg is filled in with the target pro-
cess' binding information. On failure, -1 is returned.
The flags can be interpreted by looking at the #define statements
in sys/proc.h. The relevant flags are PBIND, PBINDXCLU, PAFFINOFF
and PNOPRMPT (which is divided into PNOPRMPTSIG and
PNOPRMPTNSIG).
MPCNTLRDTIMER
Reads the system "high resolution" timer and returns the value of
the timer to the caller. The timer units are approximately
microseconds and the user must expect to deal with a "wrap-around
condition" since there may only be limited amount of resolution.
The timer values are not meaningful with respect to wall clock
time and should only be used to measure interval duration. For
implementations that do not have hardware to support this capa-
bility the call may return -1 to indicate that the functionality
is not available. The parameter arg is ignored and extended priv-
ileges are not required to use this option.
MPCNTLYIELD
Forces the calling process to voluntarily give up the CPU. The
system call does not return until the caller is rescheduled. If
there is nothing else to run or this process has the best prior-
ity on the system, the yield will return immediately.
MPCNTLCPUCNT
Returns a count of the CPUs on the system. arg points to a
cpumaskt in user-space which is filled out as a bit mask to
indicate CPUs that are in service and not marked as not-availa-
ble. The return value from the mpcntl() call indicates the total
count of configured CPUs.
Page 4 Reliant UNIX 5.44 Printed 11/98
mpcntl(3X) mpcntl(3X)
The logical CPU spectrum extends from 0 to (cpucnt -1) without
holes and all CPUs are configured and started at system boot
time. If arg is null, only the count is returned.
MPCNTLCPUINFOGET
Returns a filled out cpuinfot structure which gives specific
additional information about a particular CPU. The cpuinfot
structure is defined as follows:
typedef struct cpuinfo {
cpuidt cpicpuid; /* logical ID of this CPU */
int cpicpustatus; /* alterable CPU state flags */
int cpicpuattr; /* CPU attribute flags */
enum cputype cpicputype; /* type of processor */
int cpicpurev; /* revision of CPU */
enum fputype cpifptype; /* type of FP coprocessor */
int cpifprev; /* revision of FP coprocessor */
enum fputype cpifptype2; /* type of FP coprocessor [2] */
int cpifprev2; /* revision of FP coprocessor [2] */
int cpicachsize; /* size (bytes) of secondary cache */
int cpicpuclock; /* Speed in MHz of the CPU */
int cpibind; /* # processes explicitly bound */
int cpixbind; /* # processes explicitly bound */
int cpidrvbind; /* # drivers bound to CPU */
int cpiphyscpuid; /* physical cpu ID */
int cpiphysintbind; /* physical device intrs bound
to cpu */
int cpipad[8]; /* reserved */
} cpui nfot;
MPCNTLCPUINFOSET
This option is used to set the cpicpustatus flags (for example,
to disable binding on the CPU or to remove the CPU from service)
and the remainder of the cpuinfot structure is ignored. Typi-
cally, one should execute MPCNTLCPUINFOGET to populate the
structure, alter the flags as appropriate, and issue the
MPCNTLCPUINFOSET command. The following flags are available:
CPIFSINSVC
The CPU is in service. Clearing the flag removes the CPU
from service. This may not be supported by all hardware
(normal operation has this flag set). Removing a CPU from
service causes process bindings to that CPU to be cleared.
CPIFSNAVAIL
The CPU is not available for executing processes but may or
may not be in service (normal operation has this flag
cleared). Marking a CPU not-available causes process bind-
ings to that CPU to be cleared.
Page 5 Reliant UNIX 5.44 Printed 11/98
mpcntl(3X) mpcntl(3X)
CPIFSBINDOFF
The CPU is unavailable for normal binding operations
(MPCNTLBIND) but existing processes that are bound to the
processor are not moved (normal operation has this flag
cleared). This influences the inherited binding attributes
(across fork() or exec() system calls) by causing them to be
ignored until binding is again allowed on the CPU.
CPIFSXBINDOFF
The CPU is unavailable for exclusive binding operations
(MPCNTLBINDXCLU) but existing processes that are bound to
the CPU are not moved (normal operation has this flag
cleared). This influences the inherited binding attributes
(across fork() or exec() system calls) by causing them to be
ignored until binding is again allowed on the CPU.
CPIFSCACHEOFF
The designated CPU cache is turned off. This may not be sup-
ported by all hardware (normal operation has this flag
cleared).
CPIFSIOINTROFF
The designated CPU is not taking IO interrupts. This may not
be supported by all hardware (normal operation has this flag
cleared). The user must have superuser privileges to exer-
cise this option.
RESULT
On success, mpcntl() returns zero or the return value when one is war-
ranted (for example, MPCNTLRDTIMER); on failure mpcntl() returns a -1
and errno is set to indicate the cause of the error.
The following error code descriptions are function-specific. You will
find a general description in introprm2(2) or in errno(5).
EINVAL One or more of the arguments to mpcntl() are invalid. This
may be caused by an invalid PID or flag.
EPERM The user ID is not that of superuser (0) or has not been
granted the appropriate privileges to perform the request.
This may also occur when attempting to issue an option for a
target PID that the caller does not have permissions to
alter.
ENXIO The option is not supported by the hardware, the CPU ID is
out of range, or the CPU is not in a state that will allow
the operation.
FAULT A pointer to an argument (for example, arg) is illegal.
Page 6 Reliant UNIX 5.44 Printed 11/98
mpcntl(3X) mpcntl(3X)
BUSY The CPU has a type of binding which explicitly disallows the
options, or an exclusive operation is attempting to leave no
CPUs in a non-exclusive state.
SEE ALSO
getpid(2), signal(2), types(5).
Page 7 Reliant UNIX 5.44 Printed 11/98