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