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 * NOTE: pthread_getattr_np is not a POSIX compliant API. It is
17 *       provided by nptl, which is developed by Ulrich Drepper.
18 */
19
20#ifndef _GNU_SOURCE
21#define _GNU_SOURCE
22#endif
23#include <pthread.h>
24#include <limits.h>
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <sys/param.h>
29#include <errno.h>
30#include <unistd.h>
31#include "posixtest.h"
32
33#define TEST "2-1"
34#define FUNCTION "pthread_attr_setstack"
35#define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": "
36
37static void *stack_addr;
38size_t stack_size;
39
40void *thread_func()
41{
42	pthread_attr_t attr;
43	void *saddr;
44	size_t ssize;
45	int rc;
46
47        /* pthread_getattr_np is not POSIX Compliant API*/
48	rc = pthread_getattr_np(pthread_self(), &attr);
49	if (rc != 0)
50    	{
51      		perror(ERROR_PREFIX "pthread_getattr_np");
52      		exit(PTS_UNRESOLVED);
53	}
54
55	pthread_attr_getstack(&attr, &saddr, &ssize);
56	if (ssize != stack_size || saddr != stack_addr)
57	{
58		perror(ERROR_PREFIX "got the wrong stacksize or stackaddr");
59		exit(PTS_FAIL);
60	}
61	/* printf("saddr = %p, ssize = %u\n", saddr, ssize); */
62
63	pthread_exit(0);
64	return NULL;
65}
66
67int main()
68{
69	pthread_t new_th;
70	pthread_attr_t attr;
71	size_t ssize;
72	void *saddr;
73	int rc;
74
75	/* Initialize attr */
76	rc = pthread_attr_init(&attr);
77	if( rc != 0) {
78		perror(ERROR_PREFIX "pthread_attr_init");
79		exit(PTS_UNRESOLVED);
80	}
81
82	/* Get the default stack_addr and stack_size value */
83	rc = pthread_attr_getstack(&attr, &stack_addr, &stack_size);
84	if( rc != 0) {
85		perror(ERROR_PREFIX "pthread_attr_getstack");
86		exit(PTS_UNRESOLVED);
87	}
88	/* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */
89
90	stack_size = PTHREAD_STACK_MIN;
91
92	if (posix_memalign (&stack_addr, sysconf(_SC_PAGE_SIZE),
93            stack_size) != 0)
94    	{
95      		perror (ERROR_PREFIX "out of memory while "
96                        "allocating the stack memory");
97      		exit(PTS_UNRESOLVED);
98    	}
99	/* printf("stack_addr = %p, stack_size = %u\n", stack_addr, stack_size); */
100
101	rc = pthread_attr_setstack(&attr, stack_addr, stack_size);
102        if (rc != 0 ) {
103                perror(ERROR_PREFIX "pthread_attr_setstack");
104                exit(PTS_UNRESOLVED);
105        }
106
107	rc = pthread_attr_getstack(&attr, &saddr, &ssize);
108        if (rc != 0 ) {
109                perror(ERROR_PREFIX "pthread_attr_getstack");
110                exit(PTS_UNRESOLVED);
111        }
112	/* printf("saddr = %p, ssize = %u\n", saddr, ssize); */
113
114	rc = pthread_create(&new_th, &attr, thread_func, NULL);
115	if (rc !=0 ) {
116		perror(ERROR_PREFIX "failed to create a thread");
117                exit(PTS_FAIL);
118        }
119
120	rc = pthread_join(new_th, NULL);
121	if(rc != 0)
122        {
123                perror(ERROR_PREFIX "pthread_join");
124		exit(PTS_UNRESOLVED);
125        }
126
127	rc = pthread_attr_destroy(&attr);
128	if(rc != 0)
129        {
130                perror(ERROR_PREFIX "pthread_attr_destroy");
131		exit(PTS_UNRESOLVED);
132        }
133
134	printf("Test PASSED\n");
135	return PTS_PASS;
136}
137
138
139