Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ thr_create(3T) — SunOS 5.3

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

_lwp_create(2)

thr_continue(3T)

thr_exit(3T)

thr_join(3T)

thr_setconcurrency(3T)

thr_create(3T)

NAME

thr_create − create a new thread of control

SYNOPSIS

#include <thread.h>

int thr_create(void ∗stack_base, size_t stack_size, void ∗(∗start_routine)(void ∗),

void ∗arg, long flags, thread_t ∗new_thread);

size_t thr_min_stack(void);

MT-LEVEL

MT-Safe

DESCRIPTION

thr_create() adds a new thread of control to the current process.  The new thread begins execution by calling the function specified by start_routine with a single argument, arg. If start_routine returns, the thread exits with the exit status set to the value returned by start_routine (see thr_exit(3T)). 

The new thread will use the stack starting at the address specified by stack_base and continuing for stack_size bytes.  stack_size must be greater than the value returned by thr_min_stack().  If stack_base is NULL then thr_create() allocates a stack for the new thread with at least stack_size bytes.  If stack_size is zero then a default size is used.  If stack_size is not zero then it must be greater than the value returned by thr_min_stack().  A stack of minimum size may not accommodate the stack frame for start_function. If a stack size is specified, it must take into account the requirements start_function and the functions that it may call in turn, in addition to the minimum requirement. 

flags specifies additional attributes for the created thread.  The value in flags is constructed from the bitwise inclusive OR of the following:

THR_SUSPENDED
The new thread is created suspended and will not execute start_routine until it is started by thr_continue(). 

THR_DETACHED
The new thread is created detached. Its thread ID and other resources may be re-used as soon as the thread terminates.  A detached thread cannot be waited for via thr_join(). 

THR_BOUND The new thread is created permanently bound to an LWP (i.e. it is a bound thread).

THR_NEW_LWP
The desired concurrency level for unbound threads is increased by one. This is similar to incrementing concurrency by one via thr_setconcurrency(3T).  Typically, this adds a new LWP to the pool of LWPs running unbound threads. 

THR_DAEMON The thread is marked as a daemon.  The process will exit when all non-daemon threads exit. 

If both THR_BOUND and THR_NEW_LWP are specified then, typically, two LWPs are created, one for the bound thread and another for the pool of LWPs running unbound threads. 

When new_thread is not NULL then it points to a location where the ID of the new thread is stored if thr_create() is successful.  The ID is only valid within the calling process. 

The new thread inherits the calling thread’s signal mask and priority.  Pending signals are not inherited. 

RETURN VALUES

Zero is returned when successful.  A non-zero value indicates an error. 

ERRORS

If any of the following conditions are detected, thr_create() fails and returns the corresponding value:

EAGAIN A system limit is exceeded, e.g., too many LWPs were created. 

ENOMEM Not enough memory was available to create the new thread. 

EINVAL stack_base is not NULL and stack_size is less than the value returned by thr_min_stack(). 

EINVAL stack_base is NULL and stack_size is not zero and is less than the value returned by thr_min_stack(). 

EXAMPLES

This example shows how to create a default thread with a new signal mask.  new_mask is assumed to have a different value than the creator’s signal mask (orig_mask).  new_mask is set to block all signals except for SIGINT.  The creator’s signal mask is changed so that the new thread inherits a different mask, and is restored to its original value after thr_create() returns.  This examples asssumes that SIGINT is also unmasked in the creator.  If it is masked by the creator, then unmasking the signal opens the creator up to this signal. The other alternative is to have the new thread set its own signal mask in its start routine. 

thread_t tid;
sigset_t new_mask, orig_mask;
int error;
(void)sigfillset(&new_mask);
(void)sigdelset(&new_mask, SIGINT);
(void)thr_sigsetmask(SIG_SETMASK, &new_mask, &orig_mask):
error = thr_create(NULL, 0, do_func, NULL, 0, &tid);
(void)thr_sigsetmask(SIG_SETMASK, NULL, &orig_mask);

SEE ALSO

_lwp_create(2), thr_continue(3T), thr_exit(3T), thr_join(3T), thr_setconcurrency(3T)

NOTES

Typically, thread stacks allocated by thr_create() begin on page boundaries and any specified size is rounded up to the next page boundary.  A page with no access permission is appended to the top of the stack so that most stack overflows will result in a SIGSEGV signal being sent to the offending thread.  Thread stacks allocated by the caller are used as is. 

If there is no explicit synchronization to prevent it, an unsuspended, detached thread can die and have its thread ID re-assigned to another new thread before its creator returns from thr_create(). 

Sun Microsystems  —  Last change: 24 Mar 1993

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026