shmem_mutex_condvar (BPX1SMC, BPX4SMC) — Shared mutex and condition variable service

Function

The shmem_mutex_condvar callable service provides a general-purpose interface for managing and operating mutexes and condition variables in shared memory. An application can:
  • Create and initialize a shared memory mutex or condition variable
  • Destroy a shared memory mutex or condition variable and clean up its resources
  • Post the oldest waiter for a specified mutex or condition variable
  • Post all of the waiters for a specified mutex or condition variable
  • Wait for a specified condition variable
  • Setup to wait for a mutex
  • Cancel setup to wait for a specified mutex
  • Wait for a specified condition variable and post any waiters for the specified mutex

Requirements

Operation Environment
Authorization: Supervisor state or problem state, any PSW key
Dispatchable unit mode: Task
Cross memory mode: PASN = HASN
AMODE (BPX1SMC): 31-bit
AMODE (BPX4SMC): 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  BPX1SMC,(FcnCode,
               FcnFlags,
               ShrObj1Addr,
               ShrObj2Addr,
               EcbAddr,
               TimeStrucAddr,
               UserDataAddr,
               Return_value,
               Return_code,
               Reason_code)   

AMODE 64 callers use BPX4SMC with the same parameters. All parameter addresses and addresses in parameter structures are doublewords.

Parameters

FcnCode
Supplied parameter
Type:
Integer
Length:
Fullword
The name of a fullword that contains a value indicating the function requested. The following values are supported:
SMC_INIT
Create and initialize a new shared memory mutex or condition variable.
SMC_DESTROY
Destroy a shared memory mutex or condition variable and clean up its resources.
SMC_POST
Post the oldest waiter for the specified mutex or condition variable.
SMC_POSTALL
Post all of the waiters for the specified mutex or condition variable.
SMC_WAIT
Wait for the specified condition variable.
SMC_SETUPTOWAIT
Setup to wait for a mutex. This function is not supported for condition variables.
SMC_CANCELSETUPTOWAIT
Cancel set up to wait for the specified mutex or condition variable.
SMC_WAIT+SMC_POST
Wait for the specified condition variable and post any waiters for the specified mutex.

These constants are defined in the BPXYCONS macro (BPXYCONS — Constants used by services).

FcnFlags
Supplied parameter
Type:
Integer
Length:
Fullword
The name of a fullword that contains the function flags for the requested function. The possible values for FcnFlags are:
SMC_Mutex
The input shared memory object represents a mutex. This setting must be specified on all function calls that involve a mutex object.
SMC_Condvar
The input shared memory object represents a condition variable. This setting must be specified on all calls that involve a condition variable. SMC_Condvar or SMC_Mutex must be specified on all calls to BPX1SMC/BPX4SMC.
SMC_TimedWait
Wait for a specified time interval for the specified condition variable. This option is relevant only for a condition variable. When SMC_TimedWait is specified, the TimeStrucAddr parameter points to the time structure that indicates the amount of time to wait.
SMC_OutsideWait
The caller will wait outside of the BPX1SMC/BPX4SMC function for the specified mutex or condition variable. This setting is relevant only for the SMC_SetupToWait function. SMC_OutsideWait must be specified when SMC_Mutex is specified.
ShrObj1Addr
Supplied parameter
Type:
Pointer
Length:
Fullword (doubleword)

The name of a fullword (doubleword) pointer field that contains the address of the shared condition variable or mutex control structure (SMCV or SMMX) that is involved in the specified operation. If SMC_MUTEX is specified in the FcnFlags, this parameter must point to a valid shared mutex control structure (SMMX). If SMC_CONDVAR is specified in the FcnFlags, this parameter must point to a valid shared condition variable control structure (SMCV).

ShrObj2Addr
Supplied parameter
Type:
Pointer
Length:
Fullword (doubleword)

The name of a fullword (doubleword) pointer field that contains the address of the mutex control structure (SMMX) that is associated with the supplied shared condition variable structure (SMCV). When SMC_CONDVAR is specified in the FcnFlags for a SMC_Wait or SMC_SetupToWait function request, this parameter must contain a pointer to a valid SMMX. For all other calls to this service, this parameter must be specified, but its value will not be validity checked.

EcbAddr
Supplied parameter
Type:
Pointer
Length:
Fullword (doubleword)

The name of a fullword (doubleword) pointer field that contains the address of the ECB that the caller will wait on for the specified mutex or condition variable. For the SMC_SetupToWait function for a mutex object, this parameter must contain a valid ECB address. For all other calls to this service, this parameter must be specified, but its value will not be validity checked. For both BPX1SMC and BPX4SMC callers, the ECB must be in below-the-bar storage.

TimeStrucAddr
Supplied parameter
Type:
Pointer
Length:
Fullword (doubleword)

The name of a fullword (doubleword) pointer field that contains the address of the time structure (SMCT) that indicates the amount of time the caller will wait for a specified condition variable. When the SMC_CondVar and SMC_TimedWait function flags are specified with the SMC_SetupToWait or SMC_Wait function, this parameter must point to a valid SMCT structure. For all other calls to this service, this parameter must be specified, but its value will not be validity checked.

UserDataAddr
Supplied parameter
Type:
Pointer
Length:
Fullword (doubleword)

The name of a fullword (doubleword) pointer field that contains the address of user data supplied by the caller for problem determination support. This parameter must be specified, but its value will not be validity checked.

Return_value
Returned parameter
Type:
Integer
Length:
Fullword

The name of a fullword in which the BPX1SMC/BPX4SMC service returns 0 if the request is successful, or -1 if it is not successful. For a successful initialization call (SMC_INIT), the input shared memory object is filled in as appropriate for an SMMX (mutex) or SMCV (condition variable).

Return_code
Returned parameter
Type:
Integer
Length:
Fullword

The name of a fullword in which the BPX1SMC/BPX4SMC service stores the return code. The BPX1SMC/BPX4SMC service returns Return_code only if Return_value is -1. The BPX1SMC/BPX4SMC service can return one of the following values in the Return_code parameter:

Return_code Explanation
EAGAIN The requested service could not be performed at the current time because of a lack of available system resources. The following reason codes can accompany this return code: JRSMCMaxCntSys, JRSMCMaxCntSeg.
ETIMEDOUT The requested service reached the specified time-out interval.
EINTR A signal interrupted the callable service. The following reason code can accompany this return code: JRSignalArrived.
EINVAL One of the parameters contains a value that is not correct. The following reason codes can accompany this return code: JRSMCFcnCode, JRSMCFcnFlags, JRSMCWrongMutex, JRSMCNotMutex, JRSMCNotCondVar, JRSMCAlreadySetUp, JRSMCNotShared, JRSMCUnusable, JRSMCMutexSetUp, JRSMCMemoryMap, JRSMCNotOwner, JRSMCDisabled.
EFAULT One of the parameters contains an address that is not accessible by the caller. The following reason codes can accompany this return code: JRSMCObjAddr, JRSMCEcbAddr, JRSMCTimesTrAddr.
EBUSY The initialization or destroy function cannot be performed because the specified object is already in use. The following reason codes can accompany this return code: JRSMCWaiters, JRSMCMutexLocked, JRSMCCondWaiters, JRSMCAlreadyInit.
EPERM The caller does not have the appropriate privilege to perform the operation. The following reason code can accompany this return code: JRSMCShMAcc.
Reason_code
Returned parameter
Type:
Integer
Length:
Fullword

The name of a fullword in which the BPX1SMC/BPX4SMC service stores the reason code. The BPX1SMC/BPX4SMC service returns Reason_code only if Return_value is -1. Reason_code further qualifies the Return_code value. See z/OS UNIX System Services Messages and Codes for the reason codes.

Usage notes

  1. The initialization function (SMC_INIT)

    You initialize a mutex or condition variable by calling the initialization function (SMC_INIT), supplying the shared memory address of the mutex or condition variable. A valid shared memory address is one that is within a shared memory segment that is read/write accessible to the calling process. If a call to initialize a mutex or condition variable supplies an object that is not in shared memory, the call fails with Return_code EINVAL and Reason_code JRSMCNotShared. In this case, the Language Environment® pthread_cond_init() and pthread_mutex_init() functions treat the object as a non-shared object, because it is not accessible to any other process.

    A mutex or condition variable is represented by two shared memory serialization structures that are maintained between Language Environment and the kernel: the shared memory mutex block (SMMX) and the shared memory condvar block (SMCV). The C/Language Environment pthread_mutex_init() and pthread_cond_init() functions indicate on the initialization call to BPX1SMC/BPX4SMC the type of call that is being requested by setting the FcnFlags value to SMC_Mutex or SMC_Condvar. The BPX1SMC/BPX4SMC initialization function initially fills in an SMMX or SMCV structure with information that is pertinent to the mutex or condition variable, and returns the associated kernel-shared memory serialization token in that structure. This kernel token is used by the kernel as the anchor to the kernel control structures for the object. The address of the SMMX and/or SMCV must be supplied on all subsequent calls to BPX1SMC/BPX4SMC for the waiting, posting and destroying of the shared memory mutex or condition variable that is associated with the SMMX or SMCV structure.

    In order to prevent overuse of kernel resources, z/OS® UNIX imposes limits on the number of shared mutex and condition variables that can be initialized for any one shared memory segment and on any given system. For applications running on behalf of unauthorized users the limits are 65.535 per shared memory segment and 131,072 for the system. For applications running on behalf of authorized users the limits are Start of change4,194,304 (4M)End of change per shared memory segment and Start of change134,217,728 (128M)End of change for the system. An application is authorized if it runs with UID 0 or if it runs with an effective UID that has READ access to the SUPERUSER.SHMMCV.LIMITS resource in the UNIXPRIV class. Each shared memory mutex or condition variable requires roughly 80 bytes of storage in the OMVS address space, so the use of large numbers of mutexes and condition variables causes a significant increase in the amount of storage used in the OMVS address space. Refer to the discussion of the SUPERUSER.SHMMCV.LIMITS resource in for additional considerations.

  2. The post function (SMC_POST)

    The post function is used during a pthread_cond_signal(), or when a mutex is unlocked (pthread_mutex_unlock(), pthread_cond_wait(), or pthread_cond_timed_wait()) and there are waiters for a condition variable or mutex. The post function wakes up the oldest waiter. The post call that is done from pthread_mutex_unlock is made after the lock that is associated with the mutex (SMMX) is released. If a post is done against a mutex or condition variable that has no waiters, the call will succeed, but a subsequent wait call will still block. In other words, pre-signalling of a condition variable cannot be done.

  3. The postall function (SMC_POSTALL)

    The postall function is used during a pthread_cond_broadcast(); it causes all waiters for a condition variable to be awoken. When all waiters have woken up, they contend for the mutex that is associated with the specified condition variable.

  4. The setup to wait function (SMC_SETUPTOWAIT)

    The setup to wait function is used during a pthread_mutex_lock() function when waiting is necessary. Whenever this function needs to block, it must be called prior to waiting outside the kernel. The FcnFlags input parameter indicates an outside wait (SMC_OutsideWait), and the EcbAddr parameter must point to the ECB that will be waited upon. If the SMC_Timed_Wait flag is on, the TimeStrucAddr parameter must point to a valid SMCT time structure that describes the amount of time required for the timed wait. The setup to wait function is supported only for mutex objects.

  5. The wait function (SMC_WAIT)

    The wait function can be used by itself to wait for a condition variable, or it can be combined with the post function as a way to wait for a condition variable, at the same time posting any waiters for a mutex. The wait function cannot be used for mutexes, because mutex waits are not signal enabled.

  6. The wait and post function (SMC_WAIT+SMC_POST)

    The combined wait and post function is intended for use on a pthread_cond_timedwait() and pthread_cond_wait() as a way to minimize system overhead. When SMC_WAIT+SMC_POST is used, the ShrObj1Addr parameter must point to a valid SMCV, and the ShrObj2Addr parameter must point to a valid SMMX. The wait function internally performs a setup to wait for the condition variable, and then performs the post of the mutex. If a thread does a setup to wait function call followed by a wait function call for the same object, the wait function will fail.

    As part of the post operation, the SMMX lock is updated with CDS to indicate that the caller no longer owns the mutex. After attempting the post of the mutex object, the condition variable is waited upon. After waking up from the condition variable wait, the mutex is reobtained by BPX1SMC/BPX4SMC. Because the mutex may not be available immediately, the service may have to wait for the mutex. The first time a condition variable is waited upon with an associated mutex, the condition variable is tied to the specified mutex for the life of the condition variable and mutex. No other mutex can be associated with the specified condition variable, and no other condition variable can be associated with that mutex, until the condition variable or mutex is destroyed.

  7. The cancel setup to wait function (SMC_CANCELSETUPTOWAIT)

    The cancel setup to wait function must be called any time a setup to wait is done and a wait for the resource is not performed. If a cancel setup to wait fails, the caller may have already been posted for the associated resource. This function would probably only be used if it were detected that a resource (such as a mutex) had become available without requiring a wait.

  8. For an asynchronous signal delivered to the thread, or for thread cancelation processing of a thread that is blocked on a condition variable when the cancelability enable state of the thread is set to PTHREAD_CANCEL_DEFERRED, the BPX1SMC/BPX4SMC service unblocks the thread and returns to Language Environment with an EINTR return code. Language Environment handles this in the same way that it handles an EINTR returned from BPX1CWA. The EINTR return code is not surfaced to the C application.
  9. The user data address that is supplied on the call to BPX1SMC/BPX4SMC is used by Language Environment to supply the stack address for the calling thread. This data is recorded for all waiters for a mutex or condition variable, and is displayed for each requestor of a mutex or condition variable on the D OMVS,SER report. When Language Environment successfully obtains a mutex on behalf of a caller, the SMMXOwnerData field is filled in with this information for the same purpose.
  10. If BPX1SMC/BPX4SMC is asynchronously interrupted by an abnormal condition (such as a X'22' abend) during critical condition variable and/or mutex processing, the condition variable and/or mutex are invalidated and made unusable. Only a destroy of the condition variable and/or mutex can be performed on the object after the interrupt.
  11. Shared memory data area structures: the SMMX and the SMCV

    The SMMX (BPXYSMMX) and the SMCV (BPXYSMCV) data area structures represent two new C data types that are supported by the C RTL/Language Environment: the new larger pthread_mutex_t data type for shared-memory-resident mutexes, and the new larger pthread_cond_t data type for shared-memory-resident condition variables, respectively. These data types must be defined to be on a doubleword boundary that is enforced by the definitions of the data type.

    The SMMX and the SMCV are architected for use between Language Environment and the kernel. So that Language Environment can distinguish between the various types of mutexes and condition variables it supports, the first 8 bytes of the SMMX and SMCV must have specific bits on.

    • SMMX

      To represent the new larger type of shared mutex, the SMMX must have bits 0, 31, 62, and 63 on in the first 8 bytes of the structure. The characters SMMX (X'E2D4D4D7'') are chosen for the ID field (the first 4 bytes) so that they meet this requirement for bits 0 and 31, at the same time providing a representative eye-catcher for the structure. The second 4 bytes of the structure are a flag word (SmmxFlags), in which the low-order two flag bits must always be initialized to being on, and must never be moved from their bit positions.

      Language Environment must serialize the use of a mutex that is represented by this structure, using CDS on the lock doubleword. The first half of the lock is an ID that uniquely identifies the owner. Language Environment must use the first four bytes of the thread ID of the calling thread as the lock owner ID, because this is guaranteed to be unique for the life of the owning thread, and is useful in providing problem determination support. The second half of the lock is a 3-byte count field of waiters for the mutex and a status byte. If the mutex is not in use and is not destroyed, the lock doubleword is all zeros. If the mutex is in use with no waiters, the lock owner ID field is nonzero, and the waiter count field is zero. If the mutex is in use with waiters, both fields are nonzero. The kernel uses the information in the SMMX structure to provide cleanup and problem determination support for shared memory mutexes.

      As an example, on a pthread_mutex_lock operation, Language Environment would attempt to set the first word of the lock to the first half (first four bytes) of the caller's thread ID, and set the waiter count field in the lock doubleword to its current value. If it can do this atomically with CDS, the mutex will be obtained without contention, and no call to BPX1SMC/BPX4SMC will be necessary. This allows a minimum of calls to the kernel.

      The pthread_mutex_init() and pthread_mutex_destroy operations against a shared memory mutex are serialized by the BPX1SMC/BPX4SMC service and the use of the lock status byte. The lock status byte is updated atomically with CDS by BPX1SMC/BPX4SMC on a destroy operation, to indicate that the mutex has been destroyed. If the mutex is not in use, the CDS will succeed, and any further operations against the mutex will fail. BPX1SMC/BPX4SMC will also ensure that the same shared memory area is not initialized more than once.

    • SMCV

      The SMCV data area is created for shared memory condition variables. To represent the new larger type of shared mutex , the SMCV must have bits 0, 31, 62 and 63 on in the first 8 bytes of the structure. The characters SMCV (X'E2D4C3E5') are chosen as the ID (the first 4 bytes), so they meet the requirement for bits 0 and 31, and at the same time provide a representative eye-catcher for the structure. The second 4 bytes of the structure are a flag word, in which the low-order two flag bits in the word must always be initialized to being on, and must never be moved from their bit positions.

      Serialization over this structure is provided mainly by the BPX1SMC/BPX4SMC service. This service must be called on all pthread_cond functions for a shared condition variable, unless there are no waiters for the condition variable on a pthread_cond_signal. Language Environment increments the waiter count on a pthread_cond_wait (or timed wait) before doing the call to BPX1SMC/BPX4SMC to wait and post, and decrements the count after waking up and receiving control back from the BPX1SMC/BPX4SMC service. The wait count can be incremented only if the SmcvUnusable flag is off in the lockword flag field. If this flag is on, the condition variable has been destroyed and is no longer usable. On a pthread_cond_signal, if the wait count is found to be zero, no call to the kernel is necessary.

  12. CondTimedWait structure (SMCT)

    The CondTimedWait structure is used for timed waits against shared condition variables, and contains the amount of time to wait in seconds and nanoseconds. The SMCT structure maps directly to the timespec structure that is currently supplied on the C pthread_cond_timedwait() function.

  13. Shared memory remove

    When a shared memory segment is removed with shmctl(), all condition variables and mutexes in the removed shared memory segment must be destroyed if the shared memory segment is to be cleaned up on the remove operation. This may involve waking up any waiters that are still using the mutex or condition variable that is being cleaned up. The actual cleanup for a shared memory segment may be delayed until the last attachor detaches. If the shared memory segment is not actually cleaned up on the remove operation, the shared condition variables and mutexes are still usable by the processes that are still attached to the shared memory segment.

  14. Shared memory detach

    When a shared memory segment is detached with shmctl(), the process loses access to the associated shared memory. If this is done before a process has stopped using all condition variables and mutexes in the detached shared memory segment, unpredictable results will occur in the application, possible leading to hangs and loss of resources. Because a process is implicitly detached from its shared memory attachments when it terminates, it is recommended for most applications that they avoid doing any explicit shmdt() calls before terminating.

  15. Process/thread termination

    When a single thread ends, or when an entire process (possibly, many threads) ends while it is an owner of or a waiter for a shared memory mutex or condition variable, there may be waiters for the mutex or associated condition variable that will get hung up if the application does not perform the necessary cleanup. To prevent hangs, kernel cleanup processing for all ending threads and processes is enhanced to perform cleanup for shared memory condition variables and mutexes, if necessary. If a thread ends (normally or abnormally) while it is a waiter for a shared mutex or condition variable, it is removed from the waiter list. If the thread ends abnormally, further cleanup is performed to ensure that the thread is not the owner of a shared mutex. This extra cleanup is not performed by the kernel for a normal termination, because Language Environment thread cleanup unlocks any mutexes that are held by a normally terminated thread.

    In the case of an abnormally terminating thread, Language Environment thread cleanup may also unlock any held mutexes, if it gets a chance to run. If Language Environment cleanup does not unlock the held mutexes, kernel abnormal task termination will detect that the ending thread still owns a mutex. All of the waiters for a held mutex and the associated condition variable will be awoken. The mutex or condvar operation will then either abnormally terminate (X'EC6-xxxx8040' abend) or return an EINVAL, with the mutex and associated condition variable marked unusable. The object is marked unusable because the state of the data that the mutex or condition variable is serializing is uncertain, because of the abnormal ending of the thread that owned the resource. If BPX1SMC/BPX4SMC is abended while it is waiting for the unusable mutex or condvar, the EC6 abend is percolated to the caller of BPX1SMC/BPX4SMC. An unusable mutex or condition variable can only be destroyed.

  16. No stub is provided in SYS1.CSSLIB to make the call successful. Instead, the method described in Appendix A must be used to invoke the service using the USS CSR table.

Related services

Characteristics and restrictions

None.