pthread_attr_setstack() - Set stack attribute

Standards

Standards / Extensions C or C++ Dependencies

Single UNIX Specification, Version 3

both

z/OS V1R9
POSIX(ON)

Format

#define _UNIX03_THREADS
#include <pthread.h>

int pthread_attr_setstack(pthread_attr_t *attr, void *addr, size_t size);

General description

The pthread_attr_setstack() function sets the stackaddr and stacksize attributes in attr from the values of addr and size respectively.

When a thread is created, the stackaddr attribute locates the base (lowest addressable byte) of the created thread's initial stack segment. The stacksize attribute is the size, in bytes, of the initial stack segment allocated for the thread.

attr is a pointer to a thread attribute object initialized by pthread_attr_init().

addr is the memory location to use for the initial stack segment and must be aligned appropriately to be used as a stack. For 31-bit applications, stack alignment is on a 4K boundary; in AMODE64, the alignment is on a one megabyte boundary.

size must be at least as large as PTHREAD_STACK_MIN. This constant is defined in the <limits.h> header.

The minimum stacksize in 31-bit is 4096 (4K) and in 64-bit 1048576 (1M). In addition, the system will allocate an equivalent-sized guardpage. There is no specified maximum stacksize. If more storage is requested than the system can satisfy at pthread creation, then pthread_create() will fail and return EINVAL.

Usage notes

  1. An XPLINK application uses two stacks, an upward-growing stack and a downward-growing stack. The "size" argument refers to the size of the downward-growing stack.
  2. The Language Environment® storage report tolerates but does not maintain statistics on application-managed stacks. Also, the runtime storage option, suboption for dsa initialization does not support application-managed stacks.

Returned value

If successful, pthread_attr_setstack() returns 0; otherwise, it returns an error number.

Error Code
Description
EINVAL
Can be one of the following error conditions:
  • size is less than PTHREAD_STACK_MIN
  • addr does not have proper alignment to be used as a stack
  • (addr + size) lacks proper alignment
  • attr does not refer to an initialized thread attribute object.

Example

⁄* CELEBP65 *⁄                                   
⁄* Example using SUSv3 pthread_attr_setstack() interface *⁄ 

#define _UNIX03_THREADS 1  

#include <stdio.h>                                                              
#include <stdlib.h>
#include <pthread.h>                                                            
#include <limits.h>                                                            
#include <errno.h>                                                            
                                                                                
int main(void)
{                                                                               
   pthread_attr_t attr;                                                         
   int              rc; 

   void * stackaddr;
   void  *mystack;
                                                                                
   size_t stacksize;
   size_t mystacksize = 2 * PTHREAD_STACK_MIN;
                                                                                
   if (pthread_attr_init(&attr) == -1) {                                        
      perror("error in pthread_attr_init");                                     
      exit(1);                                                                  
   }                                                                            
                                                                                
   ⁄* Get a big enough stack and align it on 4K boundary. *⁄
   mystack = malloc(PTHREAD_STACK_MIN * 3);
   if (mystack != NULL) {
      printf("Using PTHREAD_STACK_MIN to align stackaddr %x.\n", mystack);
      mystack = (void *)((((long)mystack + (PTHREAD_STACK_MIN - 1)) ⁄
                          PTHREAD_STACK_MIN) * PTHREAD_STACK_MIN);
   } else {
      perror("Unable to acquire storage.");
      exit(2);
   }
                                                                                
   printf("Setting stackaddr to %x\n", mystack);
   printf("Setting stacksize to %x\n", mystacksize);
   rc = pthread_attr_setstack(&attr, mystack, mystacksize);
   if (rc != 0) {                                           
      printf("pthread_attr_setstack returned: %d\n", rc); 
      printf("Error: %d, Errno_Jr: %08x\n", errno, __errno2());
      exit(3);                                                                  
   } else {
      printf("Set stackaddr to %x\n", mystack);
      printf("Set stacksize to %x\n", mystacksize);
   }

   rc = pthread_attr_getstack(&attr, &stackaddr, &stacksize);
   if (rc != 0) {                                           
      printf("pthread_attr_getstack returned: %d\n", rc); 
      printf("Error: %d, Errno_Jr: %08x\n", errno, __errno2());
      exit(4);                                                                  
   } else {
      printf("Retrieved stackaddr is %x\n", mystack);
      printf("Retrieved stacksize is %x\n", mystacksize);
   }

   rc = pthread_attr_destroy(&attr);
   if (rc != 0) {                                     
      perror("error in pthread_attr_destroy");                                  
      printf("Returned: %d, Error: %d\n", rc, errno); 
      printf("Errno_Jr: %x\n", __errno2());
      exit(5);                                                                  
   }                                                                            

   exit(0);                                                                     
}                                                                               

Related information