10dc076565f772bb1953209fb69ea150b494aaa40robbiew/*
20dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2004, Bull S.A..  All rights reserved.
30dc076565f772bb1953209fb69ea150b494aaa40robbiew * Created by: Sebastien Decugis
40dc076565f772bb1953209fb69ea150b494aaa40robbiew
50dc076565f772bb1953209fb69ea150b494aaa40robbiew * This program is free software; you can redistribute it and/or modify it
60dc076565f772bb1953209fb69ea150b494aaa40robbiew * under the terms of version 2 of the GNU General Public License as
70dc076565f772bb1953209fb69ea150b494aaa40robbiew * published by the Free Software Foundation.
80dc076565f772bb1953209fb69ea150b494aaa40robbiew *
90dc076565f772bb1953209fb69ea150b494aaa40robbiew * This program is distributed in the hope that it would be useful, but
100dc076565f772bb1953209fb69ea150b494aaa40robbiew * WITHOUT ANY WARRANTY; without even the implied warranty of
110dc076565f772bb1953209fb69ea150b494aaa40robbiew * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
120dc076565f772bb1953209fb69ea150b494aaa40robbiew *
130dc076565f772bb1953209fb69ea150b494aaa40robbiew * You should have received a copy of the GNU General Public License along
14fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao * with this program; if not, write the Free Software Foundation, Inc.,
15fed9641096e27f79a0f2d9adfe9839dd8d11dc0fWanlong Gao * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
160dc076565f772bb1953209fb69ea150b494aaa40robbiew
170dc076565f772bb1953209fb69ea150b494aaa40robbiew * This sample test aims to check the following assertion:
180dc076565f772bb1953209fb69ea150b494aaa40robbiew *
192c28215423293e443469a07ae7011135d058b671Garrett Cooper * If the current thread has an alternate stack, the new thread does not inherit
200dc076565f772bb1953209fb69ea150b494aaa40robbiew * this stack
212c28215423293e443469a07ae7011135d058b671Garrett Cooper
220dc076565f772bb1953209fb69ea150b494aaa40robbiew * The steps are:
230dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> Create a thread with an alternate stack.
240dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> From this thread, create another thread.
250dc076565f772bb1953209fb69ea150b494aaa40robbiew * -> Check that the new thread does not use the same stack.
260dc076565f772bb1953209fb69ea150b494aaa40robbiew
270dc076565f772bb1953209fb69ea150b494aaa40robbiew */
282c28215423293e443469a07ae7011135d058b671Garrett Cooper
290dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
30354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define _POSIX_C_SOURCE 200112L
312c28215423293e443469a07ae7011135d058b671Garrett Cooper
320dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Some routines are part of the XSI Extensions */
330dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifndef WITHOUT_XOPEN
34354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define _XOPEN_SOURCE	600
350dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif
360dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
370dc076565f772bb1953209fb69ea150b494aaa40robbiew/****************************** standard includes *****************************************/
380dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
39354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <pthread.h>
40354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdarg.h>
41354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdio.h>
42354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <stdlib.h>
43354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <string.h>
44354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <unistd.h>
45354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
46354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <sched.h>
47354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <semaphore.h>
48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <errno.h>
49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <assert.h>
50354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include <sys/wait.h>
512c28215423293e443469a07ae7011135d058b671Garrett Cooper
520dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
530dc076565f772bb1953209fb69ea150b494aaa40robbiew/******************************   Test framework   *****************************************/
540dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include "../testfrmw/testfrmw.h"
56354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#include "../testfrmw/testfrmw.c"
570dc076565f772bb1953209fb69ea150b494aaa40robbiew /* This header is responsible for defining the following macros:
582c28215423293e443469a07ae7011135d058b671Garrett Cooper  * UNRESOLVED(ret, descr);
590dc076565f772bb1953209fb69ea150b494aaa40robbiew  *    where descr is a description of the error and ret is an int (error code for example)
600dc076565f772bb1953209fb69ea150b494aaa40robbiew  * FAILED(descr);
610dc076565f772bb1953209fb69ea150b494aaa40robbiew  *    where descr is a short text saying why the test has failed.
620dc076565f772bb1953209fb69ea150b494aaa40robbiew  * PASSED();
630dc076565f772bb1953209fb69ea150b494aaa40robbiew  *    No parameter.
642c28215423293e443469a07ae7011135d058b671Garrett Cooper  *
650dc076565f772bb1953209fb69ea150b494aaa40robbiew  * Both three macros shall terminate the calling process.
660dc076565f772bb1953209fb69ea150b494aaa40robbiew  * The testcase shall not terminate in any other maneer.
672c28215423293e443469a07ae7011135d058b671Garrett Cooper  *
680dc076565f772bb1953209fb69ea150b494aaa40robbiew  * The other file defines the functions
690dc076565f772bb1953209fb69ea150b494aaa40robbiew  * void output_init()
700dc076565f772bb1953209fb69ea150b494aaa40robbiew  * void output(char * string, ...)
712c28215423293e443469a07ae7011135d058b671Garrett Cooper  *
720dc076565f772bb1953209fb69ea150b494aaa40robbiew  * Those may be used to output information.
730dc076565f772bb1953209fb69ea150b494aaa40robbiew  */
740dc076565f772bb1953209fb69ea150b494aaa40robbiew
750dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
760dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************** Configuration ******************************************/
770dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
780dc076565f772bb1953209fb69ea150b494aaa40robbiew#ifndef VERBOSE
790dc076565f772bb1953209fb69ea150b494aaa40robbiew#define VERBOSE 1
800dc076565f772bb1953209fb69ea150b494aaa40robbiew#endif
810dc076565f772bb1953209fb69ea150b494aaa40robbiew
820dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
830dc076565f772bb1953209fb69ea150b494aaa40robbiew/***********************************    Test cases  *****************************************/
840dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
850dc076565f772bb1953209fb69ea150b494aaa40robbiew
860dc076565f772bb1953209fb69ea150b494aaa40robbiew#define STD_MAIN
878d9c084e1770f2719ef99a79416584c945cc775fWanlong Gao#include "../testfrmw/threads_scenarii.c"
880dc076565f772bb1953209fb69ea150b494aaa40robbiew
890dc076565f772bb1953209fb69ea150b494aaa40robbiew/* This file will define the following objects:
900dc076565f772bb1953209fb69ea150b494aaa40robbiew * scenarii: array of struct __scenario type.
910dc076565f772bb1953209fb69ea150b494aaa40robbiew * NSCENAR : macro giving the total # of scenarii
920dc076565f772bb1953209fb69ea150b494aaa40robbiew * scenar_init(): function to call before use the scenarii array.
930dc076565f772bb1953209fb69ea150b494aaa40robbiew * scenar_fini(): function to call after end of use of the scenarii array.
940dc076565f772bb1953209fb69ea150b494aaa40robbiew */
950dc076565f772bb1953209fb69ea150b494aaa40robbiew
960dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
970dc076565f772bb1953209fb69ea150b494aaa40robbiew/***********************************    Real Test   *****************************************/
980dc076565f772bb1953209fb69ea150b494aaa40robbiew/********************************************************************************************/
990dc076565f772bb1953209fb69ea150b494aaa40robbiew
100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *teststack(void *arg)
1010dc076565f772bb1953209fb69ea150b494aaa40robbiew{
102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int ret = 0;
1030dc076565f772bb1953209fb69ea150b494aaa40robbiew	*(int **)arg = &ret;
1040dc076565f772bb1953209fb69ea150b494aaa40robbiew	return NULL;
1050dc076565f772bb1953209fb69ea150b494aaa40robbiew}
1060dc076565f772bb1953209fb69ea150b494aaa40robbiew
1070dc076565f772bb1953209fb69ea150b494aaa40robbiew/* Thread function */
108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid *threaded(void *arg)
1090dc076565f772bb1953209fb69ea150b494aaa40robbiew{
1100dc076565f772bb1953209fb69ea150b494aaa40robbiew	int ret;
111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int *child_stack;
1120dc076565f772bb1953209fb69ea150b494aaa40robbiew	pthread_t gchild;
1132c28215423293e443469a07ae7011135d058b671Garrett Cooper
1140dc076565f772bb1953209fb69ea150b494aaa40robbiew	int sz = sysconf(_SC_THREAD_STACK_MIN);
1152c28215423293e443469a07ae7011135d058b671Garrett Cooper
116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (scenarii[sc].bottom != NULL) {
117354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 1
1180dc076565f772bb1953209fb69ea150b494aaa40robbiew		output("Processing test\n");
119354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif
1202c28215423293e443469a07ae7011135d058b671Garrett Cooper
1210dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* Create a new thread and get a location inside its stack */
1220dc076565f772bb1953209fb69ea150b494aaa40robbiew		ret = pthread_create(&gchild, NULL, teststack, &child_stack);
123354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (ret != 0) {
124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			UNRESOLVED(ret,
125354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				   "Failed to create a thread with default attribute");
126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1272c28215423293e443469a07ae7011135d058b671Garrett Cooper
1280dc076565f772bb1953209fb69ea150b494aaa40robbiew		ret = pthread_join(gchild, NULL);
129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (ret != 0) {
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			UNRESOLVED(ret, "Failed to join the test thread");
131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
1322c28215423293e443469a07ae7011135d058b671Garrett Cooper
1330dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* Check the new thread stack location was outside of the current thread location */
1340dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* We convert all the @ to longs */
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#if VERBOSE > 4
136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		output("Current stack : %p -> %p\n", scenarii[sc].bottom,
137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       sz + (long)scenarii[sc].bottom);
1380dc076565f772bb1953209fb69ea150b494aaa40robbiew		output("Child location: %p\n", child_stack);
139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif
1402c28215423293e443469a07ae7011135d058b671Garrett Cooper
1412c28215423293e443469a07ae7011135d058b671Garrett Cooper		if ((((long)scenarii[sc].bottom) < ((long)child_stack))
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    && (((long)child_stack) <
143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			(((long)scenarii[sc].bottom) + sz))) {
144354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			FAILED
145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    ("The new thread inherited th alternate stack from its parent");
1460dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
1470dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1482c28215423293e443469a07ae7011135d058b671Garrett Cooper
1490dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Signal we're done (especially in case of a detached thread) */
150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	do {
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		ret = sem_post(&scenarii[sc].sem);
152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1530dc076565f772bb1953209fb69ea150b494aaa40robbiew	while ((ret == -1) && (errno == EINTR));
154354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (ret == -1) {
155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		UNRESOLVED(errno, "Failed to wait for the semaphore");
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1572c28215423293e443469a07ae7011135d058b671Garrett Cooper
1580dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* return */
1590dc076565f772bb1953209fb69ea150b494aaa40robbiew	return arg;
160ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
161