Home | History | Annotate | Download | only in pthread_attr_setstack
      1 /*
      2  * Copyright (c) 2004, Intel Corporation. All rights reserved.
      3  * Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
      4  * This file is licensed under the GPL license.  For the full content
      5  * of this license, see the COPYING file at the top level of this
      6  * source tree.
      7 
      8  * Test pthread_attr_setstack()
      9  *
     10  * Steps:
     11  * 1.  Initialize pthread_attr_t object (attr)
     12  * 2.  set the stackaddr and stacksize to attr
     13  * 3.  create a thread with the attr
     14  * 4.  In the created thread, read the stacksize and stackaddr
     15  */
     16 
     17 /* For pthread_getattr_np(3) -- not a POSIX compliant API. */
     18 #ifndef _GNU_SOURCE
     19 #define _GNU_SOURCE
     20 #endif
     21 #include <sys/param.h>
     22 #include <errno.h>
     23 #include <limits.h>
     24 #include <pthread.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include <unistd.h>
     29 #include "posixtest.h"
     30 
     31 #define TEST "2-1"
     32 #define FUNCTION "pthread_attr_setstack"
     33 #define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": "
     34 
     35 static void *stack_addr;
     36 size_t stack_size;
     37 
     38 void *thread_func()
     39 {
     40 	pthread_attr_t attr;
     41 	void *saddr;
     42 	size_t ssize;
     43 	int rc;
     44 
     45 	if ((rc = pthread_getattr_np(pthread_self(), &attr)) != 0) {
     46 		printf(ERROR_PREFIX "pthread_getattr_np: %s", strerror(rc));
     47 		pthread_exit((void *)PTS_UNRESOLVED);
     48 	}
     49 	if ((rc = pthread_attr_getstack(&attr, &saddr, &ssize)) != 0) {
     50 		printf(ERROR_PREFIX "pthread_attr_getstack: %s", strerror(rc));
     51 		pthread_exit((void *)PTS_UNRESOLVED);
     52 	}
     53 	if (ssize != stack_size || saddr != stack_addr) {
     54 		printf(ERROR_PREFIX "got the wrong stacksize or stackaddr");
     55 		pthread_exit((void *)PTS_FAIL);
     56 	}
     57 
     58 	pthread_exit(NULL);
     59 	return NULL;
     60 }
     61 
     62 int main(void)
     63 {
     64 	pthread_t new_th;
     65 	pthread_attr_t attr;
     66 	size_t ssize;
     67 	void *saddr;
     68 	int rc;
     69 
     70 	/* Initialize attr */
     71 	rc = pthread_attr_init(&attr);
     72 	if (rc != 0) {
     73 		printf(ERROR_PREFIX "pthread_attr_init: %s", strerror(rc));
     74 		exit(PTS_UNRESOLVED);
     75 	}
     76 
     77 	/* Get the default stack_addr and stack_size value */
     78 	rc = pthread_attr_getstack(&attr, &stack_addr, &stack_size);
     79 	if (rc != 0) {
     80 		printf(ERROR_PREFIX "pthread_attr_getstack: %s", strerror(rc));
     81 		exit(PTS_UNRESOLVED);
     82 	}
     83 
     84 	/*
     85 	 * Use smallest usable stack size for us to be able to call
     86 	 * printf(3) / pthread_exit(3) without segfaulting.
     87 	 *
     88 	 * If for whatever reason PTHREAD_STACK_MIN is set to 0 (which it can
     89 	 * be according to POSIX), posix_memalign will fail with EINVAL.
     90 	 */
     91 	stack_size = PTHREAD_STACK_MIN * 4;
     92 
     93 	if ((rc = posix_memalign(&stack_addr, sysconf(_SC_PAGE_SIZE),
     94 				 stack_size)) != 0) {
     95 		printf(ERROR_PREFIX "posix_memalign: %s\n", strerror(rc));
     96 		exit(PTS_UNRESOLVED);
     97 	}
     98 
     99 	if ((rc = pthread_attr_setstack(&attr, stack_addr, stack_size)) != 0) {
    100 		printf(ERROR_PREFIX "pthread_attr_setstack: %s\n",
    101 		       strerror(rc));
    102 		exit(PTS_UNRESOLVED);
    103 	}
    104 
    105 	if ((rc = pthread_attr_getstack(&attr, &saddr, &ssize)) != 0) {
    106 		printf(ERROR_PREFIX "pthread_attr_getstack: %s\n",
    107 		       strerror(rc));
    108 		exit(PTS_UNRESOLVED);
    109 	}
    110 
    111 	if ((rc = pthread_create(&new_th, &attr, thread_func, NULL)) != 0) {
    112 		printf(ERROR_PREFIX "pthread_create: %s\n", strerror(rc));
    113 		exit(PTS_FAIL);
    114 	}
    115 
    116 	if ((rc = pthread_join(new_th, NULL)) != 0) {
    117 		printf(ERROR_PREFIX "pthread_join: %s\n", strerror(rc));
    118 		exit(PTS_UNRESOLVED);
    119 	}
    120 
    121 	if ((rc = pthread_attr_destroy(&attr)) != 0) {
    122 		printf(ERROR_PREFIX "pthread_attr_destroy: %s\n", strerror(rc));
    123 		exit(PTS_UNRESOLVED);
    124 	}
    125 
    126 	printf("Test PASSED\n");
    127 	return PTS_PASS;
    128 }
    129