1
0
Files
irix-657m-src/eoe/man/man2/sproc.2
2022-09-29 17:59:04 +03:00

469 lines
19 KiB
Groff

'\"macro stdmacro
.TH SPROC 2 LOCAL
.SH NAME
sproc, sprocsp, nsproc \- create a new share group process
.Op c p a
.SH C SYNOPSIS
.B #include <sys/types.h>
.br
.B #include <sys/prctl.h>
.sp
.br
.B "pid_t sproc (void (\(**entry) (void \(**), unsigned inh, ...);"
.sp
Type of optional third argument:
.br
.B "void \(**arg;"
.sp
.B "pid_t sprocsp (void (\(**entry) (void \(**, size_t), unsigned inh,
.br
.B " void \(**arg, caddr_t sp, size_t len);"
.Op
.Op f
.SH FORTRAN SYNOPSIS
.B #include <sys/prctl.h>
.br
.B "integer*4 function sproc (entry, inh, arg)"
.br
.B external entry
.br
.B integer*4 inh
.br
.B integer*4 arg
.nf
.Op
.SH DESCRIPTION
The \f4sproc\fP and \f4sprocsp\fP system calls are a variant of the standard
\f4fork\fP(2) call. Like \f4fork\f1, the \f4sproc\f1 calls create a new
process that is a clone of the calling process. The difference is that after
an \f4sproc\f1 call, the new child process shares the virtual address space of
the parent process (assuming that this sharing option is selected, as described
below), rather than simply being a copy of the parent. The parent and the
child each have their own program counter value and stack pointer, but all the
text and data space is visible to both processes. This provides one of the
basic mechanisms upon which parallel programs can be built.
.PP
The system call \f4nsproc\fP is no longer supported as an external interface;
any calls to it should be replaced with \f4sprocsp\fP.
.PP
A group of processes created by \f4sproc\f1 calls from a common ancestor is
referred to as a \f2share group\f1 or \f2shared process group\f1. A share
group is initially formed when a process first executes an \f4sproc\fP or
\f4sprocsp\fP call. All subsequent \f4sproc\fP calls by either the parent or
other children in this share group will add another process to the share group.
In addition to virtual address space, members of a share group can share other
attributes such as file tables, current working directories, effective userids
and others described below.
.PP
The three calls differ in just two ways - how the stack for the new process is
initialized and in the interpretation of the \f3inh\fP argument. If the
argument \f2sp\fP is set to
.SM
.B NULL
then the system will create a stack region for the child. This stack region
will not overlap with any other area of the share group's address space. These
stack regions grow downward, and are automatically grown if the process
accesses new areas of the stack. The \f2len\fP argument specifies how much
margin (in bytes) the system should attempt to leave for the child's stack.
This margin is used when the system attempts to place additional stacks or
other virtual spaces (e.g. from \f4mmap\fP). The system will attempt to leave
enough room such that the stack could grow to \f2len\fP bytes if it needs to.
This margin in no way sets a limit on stack growth nor guarantees a particular
stack size. The process can continue to grow its stack up to the maximum
permissible size (specified via the resource limit \f4RLIMIT_STACK\fP) as long
as it doesn't run into any other virtual space of the share group. Conversely,
if the share group's virtual space gets crowded, parts of the stack that
haven't yet been claimed could be used for additional stacks or other requested
virtual spaces. A minimum of 16K for \f2len\fP is recommended. Note that
there are no 'red' zones - a process growing its stack could easily start
accessing the stack of another process in the share group.
.PP
If \f2len\fP is set to be smaller than the stack size required by the sproc at
creation time, an error message indicating that there is "not enough memory to
lock stack" may be reported to the system log. This indicates that the system
attempted to place the sproc's stack using the \f2len\fP value supplied in the
\f4sprocsp\fP call, but that the initial size of the sproc's stack would
overlap into other portions of the share group's virtual space. The offending
sproc will be killed.
.PP
If \f2sp\fP is set to a valid virtual address in the share group then the stack
of the new process is set to this value. With this option, the entire
responsibility of stack management is the calling process's. The system will
no longer attempt to automatically grow the process's stack region. \f2sp\fP
should point to the top (highest address) of the new stack. It will
automatically be rounded down to provide the appropriate alignment. No
validity checks are made on \f2sp\fP.
.PP
\f4sproc\fP is equivalent to calling \f4sprocsp\fP with the \f2sp\fP argument
set to
.SM
.B NULL
and the \f2len\fP argument set to the \f2rlim_cur\fP value of the resource
limit
.SM
.BR RLIMIT_STACK .
This means that each time a process calls \f4sproc\fP, the total size of each
member of the share group increases by the size of the new process's stack.
.PP
Calling \f4sproc\fP or \f4sprocsp\fP too often, when the stack size is set
very large can easily cause the share group to grow larger than the per-process
maximum allowable size \f2{PROCSIZE_MAX}\fP [see \f4intro\fP(2)]. In this
case, the call will fail and return
.SM
.BR ENOMEM .
.PP
A process with lots of distinct virtual spaces (e.g. lots of files mapped
via \f4mmap\fP(2)) can fragment the calling process's address space such that
it is impossible to find a suitable place for the new child's stack. This
case will also cause \f4sproc\fP or \f4sprocsp\fP to fail.
.PP
The new child process resulting from \f4sproc\f1(2) differs from a normally
forked process in the following ways:
.RS 0.3i
.PP
If the
.SM
.B PR_SADDR
bit is set in \f2inh\fP then the new process will share ALL the virtual space
of the parent, except the PRDA (see below). During a normal \f4fork\f1(2) or
if the
.SM
.B PR_SADDR
is not set, the writable portions of the process's address space are marked
copy-on-write. If either process writes into a given page, then a copy is
made of the page and given to the process. Thus writes by one process will
not be visible to the other forks. With the
.SM
.B PR_SADDR
option of \f4sproc(2)\f1, however, all the processes have read/write privileges
to the entire virtual space.
.PP
The new process can reference the parent's stack.
.PP
The new process has its own
.I process data area
.SM (PRDA)
which contains, among other things, the \f2process id\f1. Part of the
.SM PRDA
is used by the system, part by system libraries, and part is available to the
application program [see
.BR <sys/prctl.h> ].
The
.SM PRDA
is at a fixed virtual address in each process which is given by the constant
.SM
.B PRDA
defined in
.BR prctl.h .
.PP
The machine state (general/floating point registers) is not duplicated with the
exception of the floating point control register. This means that if a process
has enabled floating point traps, these will be enabled in the child process.
.PP
If created via \f4sproc\fP the new process will be invoked as follows:
.PP
.ti 2i
.B "entry(void \(**arg)"
.br
.sp
If created via \f4sprocsp\fP the new process will be invoked as follows:
.PP
.ti 2i
.B "entry(void \(**arg, size_t stksize)"
.br
.sp
where
.I stksize
is the
.I len
argument the parent passed to \f4sprocsp\fP.
.RE
.PP
In addition to the attributes inherited during the \f4sproc\fP call itself,
the \f2inh\fP flag to \f4sproc\fP can request that the new process have future
changes in any member of the share group be applied to itself. A process can
only request that a child process share attributes that it itself is sharing.
The creator of a share group is effectively sharing everything. These
persisting attributes are selectable via the \f2inh\fP flag:
.TP 1i
.SM
.B PR_SADDR
All virtual space attributes (shared memory, mapped files, data space) are
shared. If one process in a share group attaches to a shared memory segment,
all processes in the group can access that segment.
.TP 1i
.SM
.B PR_SFDS
The open file table is kept synchronized. If one member of the share group
opens a file, the open file descriptor will appear in the file tables of all
members of the share group.
.sp
Note especially that the converse is also true: if one member closes a file,
it is closed for all members of the group; this has been known to surprise
applications programmers! Note also that there is only one file pointer for
each file descriptor shared within a shared process group.
.TP 1i
.SM
.B PR_SDIR
The current and root directories are kept synchronized. If one member of the
group issues a \f4chdir\f1(2) or \f4chroot\f1(2) call, the current working
directory or root directory will be changed for all members of the share group.
.TP 1i
.SM
.B PR_SUMASK
The file creation mask,
.I umask
is kept synchronized.
.TP 1i
.SM
.B PR_SULIMIT
The limit on maximum file size is kept synchronized.
.TP 1i
.SM
.B PR_SID
The real and effective user and group ids are kept synchronized.
.PP
To take advantage of sharing all possible attributes, the constant
.SM
.B PR_SALL
may be used.
.PP
In addition to specifying shared attributes, the
.I inh
flag can be used to pass flags that govern certain operations within the
\f4sproc\fP call itself. Currently two flags are supported:
.TP 1i
.SM
.BR PR_BLOCK
causes the calling process to be blocked [see \f4blockproc\f1(2)] before
returning from a successful call. This can be used to allow the child process
access to the parent's stack without the possibility of collision.
.TP 1i
.SM
.B PR_NOLIBC
causes the child to not join the C library (libc) arena (see below). If all
\f4sproc\fP calls that a process makes specify this flag then the C library
arena will never be created. The creation of the C library arena includes the
initialization of the per-thread system error value \f2errno\fP.
.PP
No scheduling synchronization is implied between shared processes: they are
free to run on any processor in any sequence. Any required synchronization
must be provided by the application using locks and semaphores [see
\f4usinit\f1(3P)] or other mechanisms.
.PP
If one member of a share group exits or otherwise dies, its stack is removed
from the virtual space of the share group. If the process which first created
the share group exits, its stack is not removed. This ensures continued access by other share group members to the
environment and starting argument vectors. In addition, if the
.SM
.B PR_SETEXITSIG
option [see \f4prctl\fP(2)] has been enabled then all remaining members of the
share group will be signaled.
.PP
By default, standard C library routines such as \f4printf\fP and \f4malloc\fP
function properly even though two or more shared processes access them
simultaneously. To accomplish this, a special arena is set up [see
\f4usinit\fP(3P)] to hold the locks and semaphores required. Unless the
.SM
.B PR_NOLIBC
flag is present, the parent will initialize and each child will join the C
library arena. Arenas have a configurable maximum number of processes that
can join, that is set when the arena is first created. This maximum (default
8) can be configured using \f4usconfig\fP(3P).
Each process in the share group needs access to this arena and requires a
single file lock [see \f4fcntl\fP(2)]. This may require more file locks to be
configured into the system than the default system configuration provides.
Programs using share groups that are invoking system services (either system
calls or \f3libc\fP routines), should be compiled with the feature test macro
.SM
.B _SGI_MP_SOURCE
set in any file containing functions that share group members might access
(see CAVEATS section below). Currently, this is only required for correct
treatment of the system error value
.I errno
(see discussion below) but in the future may be required for the correct
functioning of other services.
.PP
\f4sproc\fP
will fail and no new process will be created if one or more of the following
are true:
.TP 15
.SM
\%[ENOMEM]
If there is not enough virtual space to allocate a new stack. The default
stack size is settable via \f4prctl\fP(2), or \f4setrlimit\fP(2).
.TP 15
.SM
\%[EAGAIN]
The system-imposed limit on the total number of processes under execution,
.SM
.I {NPROC}
[see
.BR intro (2)],
would be exceeded.
.TP
.SM
\%[EAGAIN]
The system-imposed limit on the total number of processes under execution
by a single user
.SM
.I {CHILD_MAX}
[see
.BR intro (2)],
would be exceeded.
.TP
.SM
\%[EAGAIN]
Amount of system memory required is temporarily unavailable.
.TP
.SM
\%[EINVAL]
.I sp
was null and
.I len
was less than 8192.
.TP
.SM
\%[EPERM]
The system call is not permitted from a pthreaded program (see CAVEATS section
below).
.PP
When called with the
.SM
.B PR_NOLIBC
flag not set, in addition to the above errors \f4sproc\fP will fail and no new
process will be created if one or more of the following are true:
.TP 15
.SM
\%[ENOSPC]
If the size of the share group exceeds the number of users specified via
\f4usconfig\fP(3P) (8 by default). Any changes via \f4usconfig\fP(3P) must be
done BEFORE the first \f4sproc\fP is performed.
.TP 15
.SM
\%[ENOLCK]
There are not enough file locks in the system.
.TP 15
.SM
\%[EACCES]
The shared arena file (located in /usr/tmp) used in conjunction with the C
library could not be opened or created for read/write.
.TP 15
.I "New process pid # could not join I/O arena:<..>"
if the new share group member could not properly join the C library arena.
The new process exits with a \-1.
.PP
See also the possible errors from \f4usinit\fP(3P).
.SH NOTES
IrisGL processes that share virtual address space will share access to the
graphics hardware and associated data structures. IrisGL calls made by such
processes must be single threaded to avoid simultaneous access to these
resources. Furthermore, \f4gflush\fP(3G) must be called prior to leaving the
critical section represented by the set of graphics calls.
.PP
This manual entry has described ways in which processes created by \f4sproc\f1
differ from those created by \f4fork\f1. Attributes and behavior not mentioned
as different should be assumed to work the same way for \f4sproc\f1 processes
as for processes created by \f4fork\f1. Here are some respects in which the
two types of processes are the same:
.RS 0.3i
.PP
The parent and child after an \f4sproc\f1 each have a unique process id
(\f2pid\f1), but are in the same process group.
.PP
A signal sent to a specific \f2pid\f1 in a share group [see \f4kill\f1(2)]
will be received by only the process to which it was sent. Other members of
the share group will not be affected. A signal sent to an entire process group
will be received by all the members of the process group, regardless of share
group affiliations [see \f4killpg\f1(3B)]. See \f4prctl\fP(2) for ways to
alter this behavior.
.PP
If the child process resulting from an \f4sproc\f1 dies or calls \f4exit\f1(2),
the parent process receives the
.SM SIGCLD
signal [see \f4sigset\f1(2), \f4sigaction\f1(2), and \f4sigvec\f1(3B)].
.RE
.SH CAVEATS
Removing virtual space (e.g. unmapping a file) is an expensive operation and
forces all processes in the share group to single thread their memory
management operations for the duration of the unmap system call. The reason
for this is that the system must insure that no other processes in the share
group can reference the virtual space that is being removed or the underlying
physical pages during or after the removal. To accomplish this, the system
memory management code does the following:
.RS 0.3i
.PP
Locks a lock on the share group that prevents any other process in the group
from doing any memory management operations (page faults, protection faults,
second level TLB misses, \f4mmap\f1(2), \f4munmap\f1(2), \f4sbrk\f1(2)).
.PP
Sends TLB shootdown interrupts to all other cpus in the system that cause them
to remove any entries from the processor's Translation Lookaside Buffer (TLB)
for the share group for the address range being deleted.
.PP
Removes the virtual mapping from the share group's memory management data
structures and frees any underlying physical pages.
.PP
Releases the lock to allow parallel operations to continue.
.RE
.PP
\f4pixie\fP(1) and \f4prof\fP(1) do not work on processes that call \f4sproc\fP
and do not share address space (i.e.
.SM
.B PR_SADDR
is not set).
.PP
Note that the global variable
.I errno
is normally a single location shared by all processes in a share group in which
address space is a shared attribute. This means that if multiple processes in
the group make system calls or other library functions which set \f2errno\fP,
the value of
.I errno
is no longer useful, since it may be overwritten at any time by a call in
another process in the share group. To have each thread have its own private
version of
.IR errno ,
programs should be compiled with the feature test macro
.SM
.B _SGI_MP_SOURCE
defined before including the header file
.IR "errno.h" .
Note however that some system supplied libraries have not been converted to set
the per-thread error value - they will only set the global error value.
This will be corrected in future releases. This means an application compiled
with \f4_SGI_MP_SOURCE\fP and directly referencing \f2errno\fP will reference
the per-thread error value and not get the global error value that a
non-converted library might have set. There are two workarounds to this
problem: 1) define the feature test macro \f4_SGI_MP_SOURCE\fP only in files
that test \f2errno\fP as the result of an error from a function defined in
\f2libc\fP, \f2libw\fP, \f2libm\fP, \f2libadm\fP, \f2libgen\fP, or
\f2libmalloc\fP; or
2) for accesses of \f2errno\fP in response to errors from functions not in one
of the above mentioned libraries, call \f4goserror\fP(3C) (which always returns
the global error value). \f4perror\fP(3C) always reads the 'appropriate' error
value so for a threaded application it will read the per-thread value. This
means that threaded programs that call errno setting functions in non-converted
libraries and attempt to have \f4perror\fP print out the error will not get the
correct error value. In this case \f2strerror(goserror())\fP should be used
instead.
.PP
\f4rld\fP(1) does not support execution of \f4sproc\fP during shared object
initialization, such as that described under the -init flag to \f4ld\fP(1).
In particular, C++ users must take care that their code does not contain global
objects which have constructors which call \f4sproc\fP(2). Should
\f4sproc\fP(2) be called during object initialization, results will generally
be non-deterministic and unpredictable.
.PP
The \f4sproc\fP model of threading is incompatible with POSIX threads.
Attempts to create an sproc process from a pthreaded program will be rejected
[see \f4pthreads\f1(5)].
.SH "SEE ALSO"
blockproc(2), fcntl(2), fork(2), intro(2), prctl(2), setrlimit(2), goserror(3C),
oserror(3C), pcreate(3C), pthreads(5), usconfig(3P), usinit(3P), rld(1), ld(1).
.SH DIAGNOSTICS
Upon successful completion, \f4sproc\fP returns the process id of the new
process. Otherwise, a value of \-1 is returned to the calling process, and
.I errno\^
is set to indicate the error.