Open System Services Programmer's Guide

Making Process-Blocking Calls
When a thread calls a Guardian procedure that blocks the process, all other threads in the process
are also prevented from executing. If a thread is blocked for a significant period of time, it can
delay or even prevent the execution of time-critical run-time functions.
Examples of programs that can block include:
Pathway servers, which can wait indefinitely while reading $RECEIVE
The Inspect, Native Inspect, and Visual Inspect symbolic debuggers, whose use can block a
process indefinitely
Using Nowait Input or Output
Programs that use threads cannot call the Guardian AWAITIO or AWAITIOX procedure with -1
as a file parameter (applying the call to the oldest incomplete operation pending on each file).
AWAITIOX can be used to poll for completion on a specific file, although a thread must complete
all nowait input or output operations before yielding control to another thread. In summary:
No calls to AWAITIO[X]() with a file number of -1 are made outside of pthreads.
No calls to AWAITIO[X]() with a file number registered with pthreads are made outside of
pthreads.
Yielding Control
Because the PUT Model library are never preempted, a call to the sched_yield() function might
be needed to allow time-critical run-time threads to execute. This function releases the processor
to another thread of the same or higher priority. The calling thread may get control immediately
if no threads of the same or higher priority are ready to run.
Be careful using the sched_yield() function. Misuse causes unnecessary context switching,
which increases overhead without allowing the other threads to execute. For example, it is
counterproductive for a thread to yield control while it has a needed resource locked.
Spawning a New Process
Using the fork() or tdm_fork() function in a multithreaded environment can cause problems.
Applications can use either of these functions safely as follows: A parent process that has already
called a function can also use either of the fork functions to create a child process if the child
process calls any of the exec functions, the tdm_execve(), or tdm_execep() function
immediately upon its creation.
A threaded application might alternatively use pthread_atfork() to declare as many as three
fork handlers: a prepare handler called before the fork, a parent handler called after the fork in
the parent process, and a child handler called after the fork in the child process.
When a fork is called, only the calling thread is duplicated in the child process. The expected
usage of pthread_atfork() is for the prepare handler to acquire all mutex locks of interest to
the child, and the other two fork handlers to release them.
Beginning with the H06.24 and J06.13 RVUs, 64-bit OSS processes are supported. See “64-Bit
OSS Processes” (page 286) for details of creating 64-bit OSS processes.
Isolating Faults
Because all threads created by a process share the process address space, there is no address
space protection between the application threads in a process. One application thread can corrupt
data, causing other threads or the entire process to fail.
430 Using the POSIX User Thread (PUT) Model Library