Function
The pthread_create callable service
creates new threads in the calling process. Each thread that is created
represents a single flow of control within the process with its own
unique attributes.
Requirements
Operation |
Environment |
Authorization: |
Supervisor state or problem state, any PSW key |
Dispatchable unit mode: |
Task |
Cross memory mode: |
PASN = HASN |
AMODE (BPX1PTC): |
31-bit |
AMODE (BPX4PTC): |
64-bit |
ASC mode: |
Primary mode |
Interrupt status: |
Enabled for interrupts |
Locks: |
Unlocked |
Control parameters: |
All parameters must be addressable by the caller and in the
primary address space. |
Format
CALL BPX1PTC,(Init_rtn_addr,
Work_area_addr,
Attribute_area_addr,
Thread_ID,
Return_value,
Return_code,
Reason_code)
|
AMODE 64 callers use BPX4PTC with the same parameters.
Init_rtn_addr, Work_area_addr and Attribute_area_addr are doublewords.
Parameters
- Init_rtn_addr
- Supplied parameter
- Type:
- Address
- Length:
- Fullword (doubleword)
The name of a fullword (doubleword) field that
contains the address of the initialization routine for the thread
that is to be created. This routine is given first control when a
new thread task is created to run the thread. In both AMODE 31 and
AMODE 64, the actual address of the initialization routine is a 31-bit
address.
- Work_area_addr
- Supplied parameter
- Type:
- Address
- Length:
- Fullword (doubleword)
The name of a fullword (doubleword) that contains
the address of a user-supplied work area that is later passed to the
initialization routine. This address is in the parameter list that
is returned by pthread_exit_and_get on a thread get request. For a
description of this parameter list, see BPXYPTXL — Map the parameter list for pthread_create.
- Attribute_area_addr
- Supplied parameter
- Type:
- Address
- Length:
- Fullword (doubleword)
The name of a fullword (doubleword) that contains
the address of the pthread attribute area that is used to define the
attributes of the thread to be created. If a zero address is specified,
the attributes are set to their default value. For the mapping of
the pthread attribute area and the definition and defaults of the
supported attributes, see BPXYPTAT — Map attributes for pthread_exit_and_get. The address
of the pthread attribute area is in the parameter list that is returned
by pthread_exit_and_get on a thread get request. The BPXYPTXL macro
also has a description of this parameter list; see BPXYPTXL — Map the parameter list for pthread_create.
- Thread_ID
- Returned parameter
- Type:
- Character string
- Length:
- 8 bytes
The name of an 8-byte field in which the service
returns the thread ID for the thread that is created. This field
is valid only if the service returns successfully with a return value
of 0.
- Return_value
- Returned parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword in which the pthread_create
service returns 0 if the request is successful, or
-1 if it is not successful.
- Return_Code
- Returned parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword in which the pthread_create
service stores the return code. The pthread_create service returns
Return_code only if Return_value is -
1. For a complete
list of possible return code values, see
z/OS UNIX System Services Messages and Codes.
The pthread_create service can return one of the following values
in the Return_code parameter:
Return code |
Explanation |
EINVAL |
One of the parameters contains a value that is not correct.
Consult Reason_code to determine the exact reason that the error occurred.
The following reason codes can accompany this return code: JRPtatEye,
JRPtatSysLen, JRPtatSysOff, JRPtatLen, JRInitRtn, JRShSpMask, JRPtatWeight,
JRPtatDetachState, and JRPtatSyncType. |
EAGAIN |
The system lacked the necessary resources to create the new
thread. |
EINVAL |
The pthread_create service was requested in a multiprocess/multiuser
process. The following reason code can accompany this return code:
JRMultiProcUser. |
ENOMEM (132) |
Not enough space is available. |
- Reason_code
- Returned parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword in which the pthread_create
service stores the reason code. The pthread_create service returns
Reason_code only if Return_value is -1. Reason_code
further qualifies the Return_code value. For the reason codes, see z/OS UNIX System Services Messages and Codes.
Usage notes
The thread initialization routine:
- The pthread-creating task initialization routine has a user-specified
routine to initialize the user environment for each new task that
is created to process thread requests, and to control the processing
of each thread that is to be run on that task.
- The pthread-creating task initialization routine is first given
control when a new MVS™ task is
created to process a thread request. At this point, the initialization
routine should set up the user environment for the new task. After
performing its initialization, the initialization routine can retrieve
the first thread to process by invoking the pthread_exit_and_get callable
service.
- This routine performs its own initialization and cleanup processing
for each thread that is to be processed.
- When this routine gains control, signals and cancellation requests
are blocked.
- The environment in which the initialization routine receives control
is described in the following table:
Operation |
Environment |
Authorization: |
Problem program, key that is inherited from TCB key of initial
pthread creating task |
Dispatchable unit mode: |
Task |
Cross memory mode: |
PASN = HASN |
AMODE: |
31(64), the same as the caller of pthread_create |
ASC mode: |
Primary address space control (ASC) mode |
Serialization: |
Enabled for interrupts |
Locks: |
No locks held |
Control parameters: |
All parameters addressable in Primary |
- Upon entry to the initialization routine, the register contents
are as follows:
- R1 contains the address of a standard MVS parameter
list. In AMODE 31 the parameter list consists of two 4-byte pointers.
In AMODE 64 the parameter list consists of two 8-byte pointers. The
parameter list consists of the following parameters:
- The address of an initial work area for use by the initialization
routine during its setup processing.
- The address of a fullword field that contains the length of the
initial work area.
- R2–R12 are unspecified.
- R13 contains the address of a 208-byte save area for use by the
initialization routine to perform standard save area linkage and save
the general and access registers.
- R14 contains the return address for the initialization routine
to return control to the system. This address must be preserved by
the initialization routine. When the initialization routine is given
control in AMODE 31, the high-order bit (bit 0) of
this address is ON. When it is given control in AMODE 64, bits 32
and 33 of the 64-bit R14 are OFF. The initialization routine can always
do a simple branch to return to its caller.
- R15 contains the address of the initialization routine.
- After the first thread request is received, in order for the initialization
routine to process subsequent thread requests, it invokes pthread_exit_and_get
within a loop. It can then exit the previous thread and obtain a
new thread to process.
- To provide the most efficient interface with the high-level-language
environment, the following characteristics apply to the thread initialization
routine:
- Only one pthread-creating task initialization routine is allowed
per process image. When a process image is cleaned up after an invocation
of the exec or execmvs service, the address can be changed. If the
specified address is different within a given process image, the pthread_create
invocation fails with a return value of -1, a return
code of EINVAL, and a reason code of JRInitRtn.
- Only one shared subpool mask is allowed per process image. When
a process image is cleaned up after an invocation of the exec or execmvs
service, the subpool mask can be changed. If the specified shared
subpool mask is different within a given process image, the pthread_create
invocation fails with a return value of -1, a return
code of EINVAL, and a reason code of JRShSpMask.
- The work area and pthread attribute area are passed through from
pthread_create to the caller of pthread_exit_and_get without each
being copied. The caller of pthread_create must therefore ensure
that the storage that is provided for these items is not released
or modified before these items are used by the caller of pthread_exit_and_get.
- A minimum of 256 KB is required in the high private
below the line. If this is not available, the pthread_create() terminates
with a RC=ENOMEM and a RSNcode=0B510292.
Handling MVS tasks
and threads:
Each thread that is created with pthread_create
runs as an MVS subtask of the
initial pthread-creating task (IPT). The IPT is the task that issued
the first pthread_create call within the address space.
Note: The
IPT is not the same as the pthread-creating task initialization routine.
The IPT refers to the task that the first thread runs on, whereas
the pthread-creating task initialization routine is the routine given
control when a pthread_create is done.
When all the threads
created with pthread_create and the IPT have ended, the next task
in the address space to issue a pthread_create call is made the IPT.
Handling
thread IDs:
- Threads that are created by pthread_create are represented by
8-character thread IDs. A thread ID is unique only for a given process;
multiple processes can have threads that are represented by the same
thread ID.
- Threads that are to be managed by a user application should also
represent their threads with 8-character values. To distinguish between
thread IDs that are managed by the system and those that are managed
by a user application, the high-order bit of the thread ID indicates
the origination of the thread ID. Thread IDs that are managed by
a user application must have the high-order bit turned on. Thread
IDs that are managed by the system have the high-order bit turned
off.
- Since thread IDs that are managed by the system can represent
only mediumweight or heavyweight threads, those that are managed by
a user application are considered to be lightweight threads. Any z/OS UNIX service
that expects a thread ID as input fails if the thread ID represents
a user-application-managed, or lightweight, thread.
When exiting from the initial pthread-creating task (IPT):
When
exiting back to the operating system from the IPT, the caller may
receive an A03 abend if any pthread_created tasks are still running.
These tasks may still be running even if the IPT has called pthread_join
for all the threads that it created. To avoid the A03 abend, the
IPT should call the _exit service when it is ready to return to the
operating system. The _exit service ends the IPT and all of its pthread_created
subtasks without causing an A03 abend to occur.
Other usage
notes
- The pthread attribute area is passed as input to the pthread_create
callable service to describe the attributes of the thread that is
to be created. The area is split into two sections. The first section
is the system attribute area, which is used by the system to build
the new thread. The second section is the user area, which is intended
for use by the pthread-creating task initialization routine that receives
the address of the entire pthread attribute area from pthread_exit_and_get.
- The system offset and user offset fields indicate where the start
of each area begins. The system offset field (PTATSYSOFFSET) must
be set to (PTATSYSOFFVAL), or pthread_create fails with a -1 return
value, a return code of EINVAL, and a reason code that indicates the
exact error. The user offset field PTATUSEROFFSET must be set to 0 if
no user attributes are specified.
- The system length and user length fields indicate the length of
each area. The system length field (PTATSYSLENGTH) must be set to
PTATSYSLENVAL. If it is not, pthread_create fails with a -1 return
value, a return code of EINVAL, and a reason code that indicates the
exact error. The user length field PTATUSERLENGTH can be set to any
length. However, if the sum of PTATUSERLENGTH + PTATSYSLENGTH does
not equal PTATLENGTH, pthread_create fails with a -1 return
value, a return code of EINVAL, and a reason code that indicates the
exact error.
- The characteristics of each thread attribute and its impact on
the pthread_create are as follows:
- Detach state specifies the detach state of the
thread that is to be created. A thread that is created in a DETACHED
state cannot be joined (with the pthread_join callable service) by
other threads, and has its system-obtained storage freed when it exits.
A thread that is created in an UNDETACHED state can be joined by
other threads, and does not have its system-obtained storage freed
until it has been detached with pthread_detach. If the pthread attribute
area is not specified on a pthread_create invocation, the default
value is UNDETACHED.
- Weight specifies the weight of the thread that
is to be created. A thread that is created with the MEDIUMWEIGHT
attribute allows the executing task to be reused when the thread exits.
The thread is assumed to clean up all resources that it
used. Due to system limits, the medium weight thread can sometimes
be terminated. Pthreads in a wait for greater that 30 seconds are
ended. If your application requires obtained resources to remain
intact even if a medium weight thread is terminated, then consider
using the ipt_affinity() service to associate the resource with the
IPT. If the medium weight thread goes away, the resources are still
associated with the IPT. If you use spawn() to start your application,
you can use environment variable _BPXK_UNUSEDTASKS to keep idle medium
weight threads in a wait. If you have hundreds of idle medium weight
threads, system resources are used, which can degrade performance.
For more information about the _BPXK_UNUSEDTASKS environment variable,
see z/OS UNIX System Services Planning.
When
a heavyweight pthread exits, the associated MVS task can no longer request threads to process.
If the pthread attribute area is not specified on a pthread_create
invocation, the default value is HEAVYWEIGHT.
- Sync type specifies the synchronous processing
type of the thread to be created. The supported sync types are SYNCHRONOUS
and ASYNCHRONOUS. A SYNCHRONOUS thread is one that is created only
if the resources are immediately available to create it. An ASYNCHRONOUS
thread is one that is queued until resources are available. An EAGAIN
return code is received from a pthread_create invocation for a SYNCHRONOUS
thread if the resources are not available. This situation can occur
if the thread or task limit was already reached for the calling process.
If the task limit was reached, only ASYNCHRONOUS threads can be created.
If the thread limit was reached, the service fails regardless of the
SYNC TYPE. The thread or task limit is specified by parmlib member
BPXPRMxx. If the pthread attribute area is not specified on a pthread_create
invocation, the default value is SYNCHRONOUS.
- Shared Subpool Mask type specifies the set of
subpools that are to be shared between threads. The bit positions
of the mask represent the subpool number to be shared. If a bit is
on, the subpool is shared. Specify subpools 1-127 by turning on their
corresponding bit positions in the mask. Turning on the first bit
indicates that subpool 1 is to be shared, and so on, to bit position
127. Bit 128 is the enabling bit; if it is off the subpool mask is
ignored and the system default is used. The default shared subpools
are 1, 2 and 78. The shared subpools must remain constant within
the process image; any variation results in the failure of the pthread_create
service.
- If the calling thread is in a Workload Manager (WLM) enclave,
the newly created thread is joined to the same WLM enclave. After
the thread is joined, WLM can manage the calling thread and the newly
created thread as one "business unit of work" entity for system accounting
and management purposes.
Characteristics and restrictions
To prevent
unauthorized programs from gaining control in an authorized environment,
pthread_create does not allow unauthorized callers if the IPT is running
in an authorized key (0–7). Unauthorized callers are problem
program state, key 8, and not job-step authorized). This restriction
is required because the tasks that are created by pthread_create inherit
the TCB key of the IPT.
To prevent deadlocking tasks within
an MVS address space, pthread_create
is supported only from the initial pthread_create task and from any
of its daughter tasks. Invocations of pthread_create from any other
tasks fail with a -1 return value, an EMVSERR return
code, and a reason code of JRPTCNotSupp.