import RT-Thread@9217865c without bsp, libcpu and components/net
This commit is contained in:
commit
e2376a3709
1414 changed files with 390370 additions and 0 deletions
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Bull S.A.. All rights reserved.
|
||||
* Created by: Sebastien Decugis
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
|
||||
* This file is a wrapper to use the tests from the NPTL Test & Trace Project
|
||||
* with either the Linux Test Project or the Open POSIX Test Suite.
|
||||
|
||||
* The following function are defined:
|
||||
* void output_init()
|
||||
* void output_fini()
|
||||
* void output(char * string, ...)
|
||||
*
|
||||
* The are used to output informative text (as a printf).
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* We use a mutex to avoid conflicts in traces */
|
||||
static pthread_mutex_t m_trace = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void output_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void output(char *string, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct tm *now;
|
||||
time_t nw;
|
||||
int oldstate;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||||
pthread_mutex_lock(&m_trace);
|
||||
nw = time(NULL);
|
||||
now = localtime(&nw);
|
||||
if (now == NULL)
|
||||
printf("[??:??:??]\n");
|
||||
else
|
||||
printf("[%2.2d:%2.2d:%2.2d]\n",
|
||||
now->tm_hour, now->tm_min, now->tm_sec);
|
||||
va_start(ap, string);
|
||||
vprintf(string, ap);
|
||||
va_end(ap);
|
||||
pthread_mutex_unlock(&m_trace);
|
||||
pthread_setcancelstate(oldstate, NULL);
|
||||
}
|
||||
|
||||
static void output_fini(void)
|
||||
{
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Bull S.A.. All rights reserved.
|
||||
* Created by: Sebastien Decugis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is a wrapper to use the tests from the NPTL Test & Trace Project
|
||||
* with either the Linux Test Project or the Open POSIX Test Suite.
|
||||
*
|
||||
* The following macros are defined here:
|
||||
* UNRESOLVED(ret, descr);
|
||||
* where descr is a description of the error and ret is
|
||||
* an int (error code for example)
|
||||
* FAILED(descr);
|
||||
* where descr is a short text saying why the test has failed.
|
||||
* PASSED();
|
||||
* No parameter.
|
||||
*
|
||||
* Both three macros shall terminate the calling process.
|
||||
* The testcase shall not terminate without calling one of those macros.
|
||||
*/
|
||||
|
||||
#include "posixtest.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#define UNRESOLVED(x, s) \
|
||||
{ \
|
||||
output("Test %s unresolved: got %i (%s) on line %i (%s)\n", \
|
||||
__FILE__, x, strerror(x), __LINE__, s); \
|
||||
output_fini(); \
|
||||
exit(PTS_UNRESOLVED); \
|
||||
}
|
||||
|
||||
#define FAILED(s) \
|
||||
{ \
|
||||
output("Test %s FAILED: %s\n", __FILE__, s); \
|
||||
output_fini(); \
|
||||
exit(PTS_FAIL); \
|
||||
}
|
||||
|
||||
#define PASSED \
|
||||
{ \
|
||||
output_fini(); \
|
||||
exit(PTS_PASS); \
|
||||
}
|
||||
|
||||
#define UNTESTED(s) \
|
||||
{ \
|
||||
output("File %s cannot test: %s\n", __FILE__, s); \
|
||||
output_fini(); \
|
||||
exit(PTS_UNTESTED); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define UNRESOLVED(x, s) \
|
||||
{ \
|
||||
output("Test unresolved: got %i (%s) on line %i (%s)\n", \
|
||||
x, strerror(x), __LINE__, s); \
|
||||
output_fini(); \
|
||||
exit(PTS_UNRESOLVED); \
|
||||
}
|
||||
|
||||
#define FAILED(s) \
|
||||
{ \
|
||||
output("Test FAILED: %s\n", s); \
|
||||
output_fini(); \
|
||||
exit(PTS_FAIL); \
|
||||
}
|
||||
|
||||
#define PASSED \
|
||||
{ \
|
||||
output_fini(); \
|
||||
exit(PTS_PASS); \
|
||||
}
|
||||
|
||||
#define UNTESTED(s) \
|
||||
{ \
|
||||
output("Unable to test: %s\n", s); \
|
||||
output_fini(); \
|
||||
exit(PTS_UNTESTED); \
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,555 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Bull S.A.. All rights reserved.
|
||||
* Created by: Sebastien Decugis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is a helper file for the pthread_create tests
|
||||
* It defines the following objects:
|
||||
* scenarii: array of struct __scenario type.
|
||||
* NSCENAR : macro giving the total # of scenarii
|
||||
* scenar_init(): function to call before use the scenarii array.
|
||||
* scenar_fini(): function to call after end of use of the scenarii array.
|
||||
*/
|
||||
|
||||
static struct __scenario {
|
||||
/*
|
||||
* Object to hold the given configuration,
|
||||
* and which will be used to create the threads
|
||||
*/
|
||||
pthread_attr_t ta;
|
||||
|
||||
/* General parameters */
|
||||
/* 0 => joinable; 1 => detached */
|
||||
int detached;
|
||||
|
||||
/* Scheduling parameters */
|
||||
/*
|
||||
* 0 => sched policy is inherited;
|
||||
* 1 => sched policy from the attr param
|
||||
*/
|
||||
int explicitsched;
|
||||
/* 0 => default; 1=> SCHED_FIFO; 2=> SCHED_RR */
|
||||
int schedpolicy;
|
||||
/*
|
||||
* 0 => default sched param;
|
||||
* 1 => max value for sched param;
|
||||
* -1 => min value for sched param
|
||||
*/
|
||||
int schedparam;
|
||||
/*
|
||||
* 0 => default contension scope;
|
||||
* 1 => alternative contension scope
|
||||
*/
|
||||
int altscope;
|
||||
|
||||
/* Stack parameters */
|
||||
/* 0 => system manages the stack; 1 => stack is provided */
|
||||
int altstack;
|
||||
/*
|
||||
* 0 => default guardsize;
|
||||
* 1=> guardsize is 0;
|
||||
* 2=> guard is 1 page
|
||||
* -- this setting only affect system stacks (not user's).
|
||||
*/
|
||||
int guard;
|
||||
/*
|
||||
* 0 => default stack size;
|
||||
* 1 => stack size specified (min value)
|
||||
* -- ignored when stack is provided
|
||||
*/
|
||||
int altsize;
|
||||
|
||||
/* Additionnal information */
|
||||
/* object description */
|
||||
char *descr;
|
||||
/* Stores the stack start when an alternate stack is required */
|
||||
void *bottom;
|
||||
/*
|
||||
* This thread creation is expected to:
|
||||
* 0 => succeed; 1 => fail; 2 => unknown
|
||||
*/
|
||||
int result;
|
||||
/*
|
||||
* This semaphore is used to signal the end of
|
||||
* the detached threads execution
|
||||
*/
|
||||
sem_t sem;
|
||||
} scenarii[] =
|
||||
#define CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, res) \
|
||||
{ \
|
||||
.detached = det, \
|
||||
.explicitsched = expl, \
|
||||
.schedpolicy = scp, \
|
||||
.schedparam = spa, \
|
||||
.altscope = sco, \
|
||||
.altstack = sta, \
|
||||
.guard = gua, \
|
||||
.altsize = ssi, \
|
||||
.descr = desc, \
|
||||
.bottom = NULL, \
|
||||
.result = res \
|
||||
}
|
||||
#define CASE_POS(det, expl, scp, spa, sco, sta, gua, ssi, desc) \
|
||||
CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 0)
|
||||
#define CASE_NEG(det, expl, scp, spa, sco, sta, gua, ssi, desc) \
|
||||
CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 1)
|
||||
#define CASE_UNK(det, expl, scp, spa, sco, sta, gua, ssi, desc) \
|
||||
CASE(det, expl, scp, spa, sco, sta, gua, ssi, desc, 2)
|
||||
/*
|
||||
* This array gives the different combinations of threads
|
||||
* attributes for the testcases.
|
||||
*
|
||||
* Some combinations must be avoided.
|
||||
* -> Do not have a detached thread use an alternative stack;
|
||||
* as we don't know when the thread terminates to free the stack memory
|
||||
* -> ... (to be completed)
|
||||
*/
|
||||
{
|
||||
/* Unary tests */
|
||||
CASE_POS(0, 0, 0, 0, 0, 0, 0, 0, "default"),
|
||||
CASE_POS(1, 0, 0, 0, 0, 0, 0, 0, "detached"),
|
||||
CASE_POS(0, 1, 0, 0, 0, 0, 0, 0, "Explicit sched"),
|
||||
CASE_UNK(0, 0, 1, 0, 0, 0, 0, 0, "FIFO Policy"),
|
||||
CASE_UNK(0, 0, 2, 0, 0, 0, 0, 0, "RR Policy"),
|
||||
CASE_UNK(0, 0, 0, 1, 0, 0, 0, 0, "Max sched param"),
|
||||
CASE_UNK(0, 0, 0, -1, 0, 0, 0, 0, "Min sched param"),
|
||||
CASE_POS(0, 0, 0, 0, 1, 0, 0, 0, "Alternative contension scope"),
|
||||
CASE_POS(0, 0, 0, 0, 0, 1, 0, 0, "Alternative stack"),
|
||||
CASE_POS(0, 0, 0, 0, 0, 0, 1, 0, "No guard size"),
|
||||
CASE_UNK(0, 0, 0, 0, 0, 0, 2, 0, "1p guard size"),
|
||||
CASE_POS(0, 0, 0, 0, 0, 0, 0, 1, "Min stack size"),
|
||||
/* Stack play */
|
||||
CASE_POS(0, 0, 0, 0, 0, 0, 1, 1, "Min stack size, no guard"),
|
||||
CASE_UNK(0, 0, 0, 0, 0, 0, 2, 1, "Min stack size, 1p guard"),
|
||||
CASE_POS(1, 0, 0, 0, 0, 1, 0, 0, "Detached, Alternative stack"),
|
||||
CASE_POS(1, 0, 0, 0, 0, 0, 1, 1,
|
||||
"Detached, Min stack size, no guard"), CASE_UNK(1, 0, 0, 0,
|
||||
0, 0, 2, 1,
|
||||
"Detached, Min stack size, 1p guard"),
|
||||
/*
|
||||
* Scheduling play
|
||||
* -- all results are unknown since it might depend on
|
||||
* the user priviledges
|
||||
*/
|
||||
CASE_UNK(0, 1, 1, 1, 0, 0, 0, 0, "Explicit FIFO max param"),
|
||||
CASE_UNK(0, 1, 2, 1, 0, 0, 0, 0,
|
||||
"Explicit RR max param"),
|
||||
CASE_UNK(0, 1, 1, -1, 0, 0, 0, 0,
|
||||
"Explicit FIFO min param"),
|
||||
CASE_UNK(0, 1, 2, -1, 0, 0, 0, 0,
|
||||
"Explicit RR min param"),
|
||||
CASE_UNK(0, 1, 1, 1, 1, 0, 0, 0,
|
||||
"Explicit FIFO max param, alt scope"),
|
||||
CASE_UNK(0, 1, 2, 1, 1, 0, 0, 0,
|
||||
"Explicit RR max param, alt scope"),
|
||||
CASE_UNK(0, 1, 1, -1, 1, 0, 0, 0,
|
||||
"Explicit FIFO min param, alt scope"),
|
||||
CASE_UNK(0, 1, 2, -1, 1, 0, 0, 0,
|
||||
"Explicit RR min param, alt scope"),
|
||||
CASE_UNK(1, 1, 1, 1, 0, 0, 0, 0,
|
||||
"Detached, explicit FIFO max param"),
|
||||
CASE_UNK(1, 1, 2, 1, 0, 0, 0, 0,
|
||||
"Detached, explicit RR max param"),
|
||||
CASE_UNK(1, 1, 1, -1, 0, 0, 0, 0,
|
||||
"Detached, explicit FIFO min param"),
|
||||
CASE_UNK(1, 1, 2, -1, 0, 0, 0, 0,
|
||||
"Detached, explicit RR min param"),
|
||||
CASE_UNK(1, 1, 1, 1, 1, 0, 0, 0,
|
||||
"Detached, explicit FIFO max param,"
|
||||
" alt scope"), CASE_UNK(1, 1, 2, 1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"Detached, explicit RR max param,"
|
||||
" alt scope"),
|
||||
CASE_UNK(1, 1, 1, -1, 1, 0, 0, 0,
|
||||
"Detached, explicit FIFO min param,"
|
||||
" alt scope"), CASE_UNK(1, 1, 2,
|
||||
-1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"Detached, explicit RR min param,"
|
||||
" alt scope"),};
|
||||
|
||||
#define NSCENAR (sizeof(scenarii) / sizeof(scenarii[0]))
|
||||
|
||||
/*
|
||||
* This function will initialize every pthread_attr_t object
|
||||
* in the scenarii array
|
||||
*/
|
||||
static void scenar_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int old;
|
||||
long pagesize, minstacksize;
|
||||
long tsa, tss, tps;
|
||||
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
minstacksize = sysconf(_SC_THREAD_STACK_MIN);
|
||||
tsa = sysconf(_SC_THREAD_ATTR_STACKADDR);
|
||||
tss = sysconf(_SC_THREAD_ATTR_STACKSIZE);
|
||||
tps = sysconf(_SC_THREAD_PRIORITY_SCHEDULING);
|
||||
|
||||
#if VERBOSE > 0
|
||||
output("System abilities:\n");
|
||||
output(" TSA: %li\n", tsa);
|
||||
output(" TSS: %li\n", tss);
|
||||
output(" TPS: %li\n", tps);
|
||||
output(" pagesize: %li\n", pagesize);
|
||||
output(" min stack size: %li\n", minstacksize);
|
||||
#endif
|
||||
|
||||
if (minstacksize % pagesize)
|
||||
UNTESTED("The min stack size is not a multiple"
|
||||
" of the page size");
|
||||
|
||||
for (i = 0; i < NSCENAR; i++) {
|
||||
#if VERBOSE > 2
|
||||
output("Initializing attribute for scenario %i: %s\n",
|
||||
i, scenarii[i].descr);
|
||||
#endif
|
||||
|
||||
ret = pthread_attr_init(&scenarii[i].ta);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Failed to initialize a"
|
||||
" thread attribute object");
|
||||
|
||||
/* Set the attributes according to the scenario */
|
||||
if (scenarii[i].detached == 1) {
|
||||
ret = pthread_attr_setdetachstate(&scenarii[i].ta,
|
||||
PTHREAD_CREATE_DETACHED);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to set detachstate");
|
||||
} else {
|
||||
ret =
|
||||
pthread_attr_getdetachstate(&scenarii[i].ta, &old);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to get detachstate"
|
||||
" from initialized attribute");
|
||||
if (old != PTHREAD_CREATE_JOINABLE)
|
||||
FAILED("The default attribute is not"
|
||||
" PTHREAD_CREATE_JOINABLE");
|
||||
}
|
||||
#if VERBOSE > 4
|
||||
output("Detach state was set successfully\n");
|
||||
#endif
|
||||
|
||||
/* Sched related attributes */
|
||||
/*
|
||||
* This routine is dependent on the Thread Execution
|
||||
* Scheduling option
|
||||
*/
|
||||
if (tps > 0) {
|
||||
if (scenarii[i].explicitsched == 1)
|
||||
ret =
|
||||
pthread_attr_setinheritsched(&scenarii
|
||||
[i].ta,
|
||||
PTHREAD_EXPLICIT_SCHED);
|
||||
else
|
||||
ret =
|
||||
pthread_attr_setinheritsched(&scenarii
|
||||
[i].ta,
|
||||
PTHREAD_INHERIT_SCHED);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to set inheritsched"
|
||||
" attribute");
|
||||
#if VERBOSE > 4
|
||||
output("inheritsched state was set successfully\n");
|
||||
#endif
|
||||
}
|
||||
#if VERBOSE > 4
|
||||
else
|
||||
output("TPS unsupported => inheritsched parameter"
|
||||
" untouched\n");
|
||||
#endif
|
||||
|
||||
if (tps > 0) {
|
||||
if (scenarii[i].schedpolicy == 1)
|
||||
ret =
|
||||
pthread_attr_setschedpolicy(&scenarii[i].ta,
|
||||
SCHED_FIFO);
|
||||
if (scenarii[i].schedpolicy == 2)
|
||||
ret =
|
||||
pthread_attr_setschedpolicy(&scenarii[i].ta,
|
||||
SCHED_RR);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to set the"
|
||||
" sched policy");
|
||||
#if VERBOSE > 4
|
||||
if (scenarii[i].schedpolicy)
|
||||
output("Sched policy was set successfully\n");
|
||||
else
|
||||
output("Sched policy untouched\n");
|
||||
#endif
|
||||
}
|
||||
#if VERBOSE > 4
|
||||
else
|
||||
output("TPS unsupported => sched policy parameter"
|
||||
" untouched\n");
|
||||
#endif
|
||||
|
||||
if (scenarii[i].schedparam != 0) {
|
||||
struct sched_param sp;
|
||||
|
||||
ret =
|
||||
pthread_attr_getschedpolicy(&scenarii[i].ta, &old);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to get sched policy"
|
||||
" from attribute");
|
||||
|
||||
if (scenarii[i].schedparam == 1)
|
||||
sp.sched_priority = sched_get_priority_max(old);
|
||||
if (scenarii[i].schedparam == -1)
|
||||
sp.sched_priority = sched_get_priority_min(old);
|
||||
|
||||
ret = pthread_attr_setschedparam(&scenarii[i].ta, &sp);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret,
|
||||
"Failed to set the sched param");
|
||||
|
||||
#if VERBOSE > 4
|
||||
output("Sched param was set successfully to %i\n",
|
||||
sp.sched_priority);
|
||||
} else {
|
||||
output("Sched param untouched\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (tps > 0) {
|
||||
ret = pthread_attr_getscope(&scenarii[i].ta, &old);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Failed to get contension"
|
||||
" scope from thread attribute");
|
||||
|
||||
if (scenarii[i].altscope != 0) {
|
||||
if (old == PTHREAD_SCOPE_PROCESS)
|
||||
old = PTHREAD_SCOPE_SYSTEM;
|
||||
else
|
||||
old = PTHREAD_SCOPE_PROCESS;
|
||||
|
||||
ret =
|
||||
pthread_attr_setscope(&scenarii[i].ta, old);
|
||||
|
||||
#if VERBOSE > 0
|
||||
if (ret != 0)
|
||||
output("WARNING: The TPS option is"
|
||||
" claimed to be supported but"
|
||||
" setscope fails\n");
|
||||
#endif
|
||||
|
||||
#if VERBOSE > 4
|
||||
output("Contension scope set to %s\n",
|
||||
old == PTHREAD_SCOPE_PROCESS ?
|
||||
"PTHREAD_SCOPE_PROCESS" :
|
||||
"PTHREAD_SCOPE_SYSTEM");
|
||||
} else {
|
||||
output("Contension scope untouched (%s)\n",
|
||||
old == PTHREAD_SCOPE_PROCESS ?
|
||||
"PTHREAD_SCOPE_PROCESS" :
|
||||
"PTHREAD_SCOPE_SYSTEM");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if VERBOSE > 4
|
||||
else
|
||||
output("TPS unsupported => sched contension scope"
|
||||
" parameter untouched\n");
|
||||
#endif
|
||||
|
||||
/* Stack related attributes */
|
||||
/*
|
||||
* This routine is dependent on the Thread Stack Address
|
||||
* Attribute and Thread Stack Size Attribute options
|
||||
*/
|
||||
if ((tss > 0) && (tsa > 0)) {
|
||||
if (scenarii[i].altstack != 0) {
|
||||
/*
|
||||
* This is slightly more complicated.
|
||||
* We need to alloc a new stackand free
|
||||
* it upon test termination.
|
||||
* We will alloc with a simulated guardsize
|
||||
* of 1 pagesize */
|
||||
scenarii[i].bottom = malloc(minstacksize + pagesize);
|
||||
if (scenarii[i].bottom == NULL)
|
||||
UNRESOLVED(errno, "Unable to alloc"
|
||||
" enough memory for"
|
||||
" alternative stack");
|
||||
|
||||
ret = pthread_attr_setstack(&scenarii[i].ta,
|
||||
scenarii[i].bottom,
|
||||
minstacksize);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Failed to specify"
|
||||
" alternate stack");
|
||||
|
||||
#if VERBOSE > 1
|
||||
output("Alternate stack created successfully."
|
||||
" Bottom=%p, Size=%i\n",
|
||||
scenarii[i].bottom, minstacksize);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if VERBOSE > 4
|
||||
else
|
||||
output("TSA or TSS unsupported => "
|
||||
"No alternative stack\n");
|
||||
#endif
|
||||
|
||||
#ifndef WITHOUT_XOPEN
|
||||
if (scenarii[i].guard != 0) {
|
||||
if (scenarii[i].guard == 1)
|
||||
ret =
|
||||
pthread_attr_setguardsize(&scenarii[i].ta,
|
||||
0);
|
||||
if (scenarii[i].guard == 2)
|
||||
ret =
|
||||
pthread_attr_setguardsize(&scenarii[i].ta,
|
||||
pagesize);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to set guard area"
|
||||
" size in thread stack");
|
||||
#if VERBOSE > 4
|
||||
output("Guard size set to %i\n",
|
||||
scenarii[i].guard == 1 ? 1 : pagesize);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tss > 0) {
|
||||
if (scenarii[i].altsize != 0) {
|
||||
ret = pthread_attr_setstacksize(&scenarii[i].ta,
|
||||
minstacksize);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to change"
|
||||
" stack size");
|
||||
#if VERBOSE > 4
|
||||
output("Stack size set to %i (this is the "
|
||||
"min)\n", minstacksize);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if VERBOSE > 4
|
||||
else
|
||||
output("TSS unsupported => stack size unchanged\n");
|
||||
#endif
|
||||
|
||||
ret = sem_init(&scenarii[i].sem, 0, 0);
|
||||
if (ret == -1)
|
||||
UNRESOLVED(errno, "Unable to init a semaphore");
|
||||
|
||||
}
|
||||
#if VERBOSE > 0
|
||||
output("All %i thread attribute objects were initialized\n\n", NSCENAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will free all resources consumed
|
||||
* in the scenar_init() routine
|
||||
*/
|
||||
static void scenar_fini(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NSCENAR; i++) {
|
||||
if (scenarii[i].bottom != NULL)
|
||||
free(scenarii[i].bottom);
|
||||
|
||||
ret = sem_destroy(&scenarii[i].sem);
|
||||
if (ret == -1)
|
||||
UNRESOLVED(errno, "Unable to destroy a semaphore");
|
||||
|
||||
ret = pthread_attr_destroy(&scenarii[i].ta);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Failed to destroy a thread"
|
||||
" attribute object");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int sc;
|
||||
|
||||
#ifdef STD_MAIN
|
||||
|
||||
static void *threaded(void *arg);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ret = 0;
|
||||
pthread_t child;
|
||||
|
||||
output_init();
|
||||
scenar_init();
|
||||
|
||||
for (sc = 0; sc < NSCENAR; sc++) {
|
||||
#if VERBOSE > 0
|
||||
output("-----\n");
|
||||
output("Starting test with scenario (%i): %s\n",
|
||||
sc, scenarii[sc].descr);
|
||||
#endif
|
||||
|
||||
ret = pthread_create(&child, &scenarii[sc].ta, threaded, NULL);
|
||||
switch (scenarii[sc].result) {
|
||||
case 0: /* Operation was expected to succeed */
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Failed to create this thread");
|
||||
break;
|
||||
case 1: /* Operation was expected to fail */
|
||||
if (ret == 0)
|
||||
UNRESOLVED(-1, "An error was expected but the"
|
||||
" thread creation succeeded");
|
||||
break;
|
||||
case 2: /* We did not know the expected result */
|
||||
default:
|
||||
#if VERBOSE > 0
|
||||
if (ret == 0)
|
||||
output("Thread has been created successfully"
|
||||
" for this scenario\n");
|
||||
else
|
||||
output("Thread creation failed with the error:"
|
||||
" %s\n", strerror(ret));
|
||||
#endif
|
||||
}
|
||||
if (ret == 0) {
|
||||
if (scenarii[sc].detached == 0) {
|
||||
ret = pthread_join(child, NULL);
|
||||
if (ret != 0)
|
||||
UNRESOLVED(ret, "Unable to join a"
|
||||
" thread");
|
||||
} else {
|
||||
/* Just wait for the thread to terminate */
|
||||
do {
|
||||
ret = sem_wait(&scenarii[sc].sem);
|
||||
} while ((ret == -1) && (errno == EINTR));
|
||||
if (ret == -1)
|
||||
UNRESOLVED(errno, "Failed to wait for"
|
||||
" the semaphore");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scenar_fini();
|
||||
#if VERBOSE > 0
|
||||
output("-----\n");
|
||||
output("All test data destroyed\n");
|
||||
output("Test PASSED\n");
|
||||
#endif
|
||||
|
||||
PASSED;
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue