pthread_create (BPX1PTC, BPX4PTC) — Create a thread

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.
Start of changeENOMEM (132)End of change Start of changeNot enough space is available.End of change
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:
  1. 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.
  2. 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.
  3. This routine performs its own initialization and cleanup processing for each thread that is to be processed.
  4. When this routine gains control, signals and cancellation requests are blocked.
  5. 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
  6. 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:
      1. The address of an initial work area for use by the initialization routine during its setup processing.
      2. 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.
  7. 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.
  8. To provide the most efficient interface with the high-level-language environment, the following characteristics apply to the thread initialization routine:
    1. 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.
    2. 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.
    3. 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.
  9. Start of changeA 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.End of change

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:

  1. 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.
  2. 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.
  3. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.

      Start of changeThe 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.End of change

      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.
  5. 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.

Related services

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.

Examples

See BPX1PTC (pthread_create) example.