import RT-Thread@9217865c without bsp, libcpu and components/net

This commit is contained in:
Zihao Yu 2023-05-20 16:23:33 +08:00
commit e2376a3709
1414 changed files with 390370 additions and 0 deletions

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: julie.n.fleischer REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
*/
/*
* return codes
*/
#define PTS_PASS 0
#define PTS_FAIL 1
#define PTS_UNRESOLVED 2
#define PTS_UNSUPPORTED 4
#define PTS_UNTESTED 5
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#endif
#define PTS_ATTRIBUTE_NORETURN __attribute__((noreturn))
#define PTS_ATTRIBUTE_UNUSED __attribute__((unused))
#define PTS_ATTRIBUTE_UNUSED_RESULT __attribute__((warn_unused_result))

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: bing.wei.liu REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_cond_broadcast()
* When each thread unblocked as a result of pthread_cond_signal()
* returns from its call to pthread_cond_wait(), the thread shall
* own the mutex with which it called pthread_cond_wait().
*/
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "posixtest.h"
#define THREAD_NUM 3
static struct testdata {
pthread_mutex_t mutex;
pthread_cond_t cond;
} td;
static int start_num;
static int waken_num;
static void *thr_func(void *arg PTS_ATTRIBUTE_UNUSED)
{
int rc;
pthread_t self = pthread_self();
if (pthread_mutex_lock(&td.mutex) != 0) {
fprintf(stderr, "[Thread 0x%p] failed to acquire the mutex\n",
(void *)self);
exit(PTS_UNRESOLVED);
}
fprintf(stderr, "[Thread 0x%p] started and locked the mutex\n",
(void *)self);
start_num++;
fprintf(stderr, "[Thread 0x%p] is waiting for the cond\n",
(void *)self);
rc = pthread_cond_wait(&td.cond, &td.mutex);
if (rc != 0) {
fprintf(stderr, "pthread_cond_wait return %d\n", rc);
exit(PTS_UNRESOLVED);
}
if (pthread_mutex_trylock(&td.mutex) == 0) {
fprintf(stderr, "[Thread 0x%p] should not be able to lock the "
"mutex again\n", (void *)self);
printf("Test FAILED\n");
exit(PTS_FAIL);
}
fprintf(stderr, "[Thread 0x%p] was wakened and acquired the "
"mutex again\n", (void *)self);
waken_num++;
if (pthread_mutex_unlock(&td.mutex) != 0) {
fprintf(stderr, "[Thread 0x%p] failed to release the "
"mutex\n", (void *)self);
printf("Test FAILED\n");
exit(PTS_FAIL);
}
fprintf(stderr, "[Thread 0x%p] released the mutex\n", (void *)self);
return NULL;
}
static int posix_testcase(void)
{
struct timespec completion_wait_ts = {0, 100000};
int i, rc;
pthread_t thread[THREAD_NUM];
if (pthread_mutex_init(&td.mutex, NULL) != 0) {
fprintf(stderr, "Fail to initialize mutex\n");
return PTS_UNRESOLVED;
}
if (pthread_cond_init(&td.cond, NULL) != 0) {
fprintf(stderr, "Fail to initialize cond\n");
return PTS_UNRESOLVED;
}
for (i = 0; i < THREAD_NUM; i++) {
if (pthread_create(&thread[i], NULL, thr_func, NULL) != 0) {
fprintf(stderr, "Fail to create thread[%d]\n", i);
return PTS_UNRESOLVED;
}
}
while (start_num < THREAD_NUM)
nanosleep(&completion_wait_ts, NULL);
/* Acquire the mutex to make sure that all waiters are currently
blocked on pthread_cond_wait */
if (pthread_mutex_lock(&td.mutex) != 0) {
fprintf(stderr, "Main: Fail to acquire mutex\n");
return PTS_UNRESOLVED;
}
if (pthread_mutex_unlock(&td.mutex) != 0) {
fprintf(stderr, "Main: Fail to release mutex\n");
return PTS_UNRESOLVED;
}
/* broadcast the condition to wake up all waiters */
fprintf(stderr, "[Main thread] broadcast the condition\n");
rc = pthread_cond_broadcast(&td.cond);
if (rc != 0) {
fprintf(stderr, "[Main thread] failed to broadcast the "
"condition\n");
return PTS_UNRESOLVED;
}
sleep(1);
if (waken_num < THREAD_NUM) {
fprintf(stderr, "[Main thread] Not all waiters were wakened\n");
for (i = 0; i < THREAD_NUM; i++)
pthread_cancel(thread[i]);
return PTS_UNRESOLVED;
}
fprintf(stderr, "[Main thread] all waiters were wakened\n");
/* join all secondary threads */
for (i = 0; i < THREAD_NUM; i++) {
if (pthread_join(thread[i], NULL) != 0) {
fprintf(stderr, "Fail to join thread[%d]\n", i);
return PTS_UNRESOLVED;
}
}
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_cond_broadcast.2-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: bing.wei.liu REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_cond_destroy()
* shall destroy the condition variable referenced by 'cond';
* the condition variable object in effect becomes uninitialized.
*
*/
#include <pthread.h>
#include <stdio.h>
#include "posixtest.h"
static pthread_cond_t cond1, cond2;
static pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER;
static int posix_testcase(void)
{
pthread_condattr_t condattr;
int rc;
/* Initialize a condition variable attribute object */
if ((rc = pthread_condattr_init(&condattr)) != 0) {
fprintf(stderr, "Error at pthread_condattr_init(), rc=%d\n",
rc);
return PTS_UNRESOLVED;
}
printf("Line-%04d\n", __LINE__);
/* Initialize cond1 with the default condition variable attribute */
if ((rc = pthread_cond_init(&cond1, &condattr)) != 0) {
fprintf(stderr, "Fail to initialize cond1, rc=%d\n", rc);
return PTS_UNRESOLVED;
}
printf("Line-%04d\n", __LINE__);
/* Initialize cond2 with NULL attributes */
if ((rc = pthread_cond_init(&cond2, NULL)) != 0) {
fprintf(stderr, "Fail to initialize cond2, rc=%d\n", rc);
return PTS_UNRESOLVED;
}
printf("Line-%04d\n", __LINE__);
/* Destroy the condition variable attribute object */
if ((rc = pthread_condattr_destroy(&condattr)) != 0) {
fprintf(stderr, "Error at pthread_condattr_destroy(), rc=%d\n",
rc);
return PTS_UNRESOLVED;
}
printf("Line-%04d\n", __LINE__);
/* Destroy cond1 */
if ((rc = pthread_cond_destroy(&cond1)) != 0) {
fprintf(stderr, "Fail to destroy cond1, rc=%d\n", rc);
printf("Test FAILED\n");
return PTS_FAIL;
}
printf("Line-%04d\n", __LINE__);
/* Destroy cond2 */
if ((rc = pthread_cond_destroy(&cond2)) != 0) {
fprintf(stderr, "Fail to destroy cond2, rc=%d\n", rc);
printf("Test FAILED\n");
return PTS_FAIL;
}
printf("Line-%04d", __LINE__);
/* Destroy cond3 */
if ((rc = pthread_cond_destroy(&cond3)) != 0) {
fprintf(stderr, "Fail to destroy cond3, rc=%d\n", rc);
printf("Test FAILED\n");
return PTS_FAIL;
}
printf("Line-%04d", __LINE__);
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_cond_destroy.1-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: bing.wei.liu REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_cond_init()
* shall initialize the condition variable referenced by cond with attributes
* referenced by attr. If attr is NULL, the default condition variable
* attributes shall be used; the effect is the same as passing the address
* of a default condition variable attributes object.
* NOTE: There is no direct way to judge if two condition variables are equal,
* so this test does not cover the statement in the last sentence.
*
*
* Modified - LK coding style 30/05/2011
* Peter W. Morreale <pmorreale AT novell DOT com>
*/
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include "posixtest.h"
#define ERR_MSG(f, rc) printf("Failed: func: %s rc: %s (%u)\n", \
f, strerror(rc), rc);
static int posix_testcase(void)
{
pthread_condattr_t condattr;
pthread_cond_t cond1;
pthread_cond_t cond2;
int rc;
char *f;
int status = PTS_UNRESOLVED;
f = "pthread_condattr_init()";
rc = pthread_condattr_init(&condattr);
if (rc)
goto done;
status = PTS_FAIL;
f = "pthread_cond_init() - condattr";
rc = pthread_cond_init(&cond1, &condattr);
if (rc)
goto done;
f = "pthread_cond_init() - NULL";
rc = pthread_cond_init(&cond2, NULL);
if (rc)
goto done;
printf("Test PASSED\n");
return PTS_PASS;
done:
ERR_MSG(f, rc);
return status;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_cond_init.1-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: bing.wei.liu REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_cond_timedwait()
* shall be equivalent to pthread_cond_wait(), except that an error is returned
* if the absolute time specified by abstime passes before the condition cond is
* signaled or broadcasted, or if the absolute time specified by abstime has
* already been passed at the time of the call.
*
* Case 2-1
* Upon successful return, the mutex shall have been locked and shall
* be owned by the calling thread.
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include "posixtest.h"
#define INTERVAL 1
#define TIMEOUT 5
static struct testdata {
pthread_mutex_t mutex;
pthread_cond_t cond;
} td;
static int t1_start = 0;
static int signaled = 0;
static void *t1_func(void *arg)
{
int rc;
struct timespec timeout;
struct timeval curtime;
(void) arg;
if (pthread_mutex_lock(&td.mutex) != 0) {
fprintf(stderr, "Thread1 failed to acquire the mutex\n");
exit(PTS_UNRESOLVED);
}
fprintf(stderr, "Thread1 started\n");
t1_start = 1; /* let main thread continue */
if (gettimeofday(&curtime, NULL) != 0) {
fprintf(stderr, "Fail to get current time\n");
exit(PTS_UNRESOLVED);
}
timeout.tv_sec = curtime.tv_sec + TIMEOUT;
timeout.tv_nsec = curtime.tv_usec * 1000;
fprintf(stderr, "Thread1 is waiting for the cond\n");
rc = pthread_cond_timedwait(&td.cond, &td.mutex, &timeout);
if (rc != 0) {
if (rc == ETIMEDOUT) {
fprintf(stderr,
"Thread1 stops waiting when time is out\n");
exit(PTS_UNRESOLVED);
} else {
fprintf(stderr, "pthread_cond_timedwait return %d\n",
rc);
exit(PTS_UNRESOLVED);
}
}
fprintf(stderr, "Thread1 wakened\n");
if (signaled == 0) {
fprintf(stderr, "Thread1 did not block on the cond at all\n");
exit(PTS_UNRESOLVED);
}
if (pthread_mutex_trylock(&td.mutex) == 0) {
fprintf(stderr,
"Thread1 should not be able to lock the mutex again\n");
printf("Test FAILED\n");
exit(PTS_FAIL);
}
fprintf(stderr, "Thread1 failed to trylock the mutex (as expected)\n");
if (pthread_mutex_unlock(&td.mutex) != 0) {
fprintf(stderr, "Thread1 failed to release the mutex\n");
printf("Test FAILED\n");
exit(PTS_FAIL);
}
fprintf(stderr, "Thread1 released the mutex\n");
return NULL;
}
static int posix_testcase(void)
{
pthread_t thread1;
struct timespec thread_start_ts = {0, 100000};
if (pthread_mutex_init(&td.mutex, NULL) != 0) {
fprintf(stderr, "Fail to initialize mutex\n");
return PTS_UNRESOLVED;
}
if (pthread_cond_init(&td.cond, NULL) != 0) {
fprintf(stderr, "Fail to initialize cond\n");
return PTS_UNRESOLVED;
}
if (pthread_create(&thread1, NULL, t1_func, NULL) != 0) {
fprintf(stderr, "Fail to create thread 1\n");
return PTS_UNRESOLVED;
}
while (!t1_start) /* wait for thread1 started */
nanosleep(&thread_start_ts, NULL);
/* acquire the mutex released by pthread_cond_wait() within thread 1 */
if (pthread_mutex_lock(&td.mutex) != 0) {
fprintf(stderr, "Main failed to acquire mutex\n");
return PTS_UNRESOLVED;
}
if (pthread_mutex_unlock(&td.mutex) != 0) {
fprintf(stderr, "Main failed to release mutex\n");
return PTS_UNRESOLVED;
}
sleep(INTERVAL);
fprintf(stderr, "Time to wake up thread1 by signaling a condition\n");
signaled = 1;
if (pthread_cond_signal(&td.cond) != 0) {
fprintf(stderr, "Main failed to signal the condition\n");
return PTS_UNRESOLVED;
}
pthread_join(thread1, NULL);
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_cond_timedwait.2-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_create() creates a new thread with attributes specified
* by 'attr', within a process.
*
* Steps:
* 1. Create a thread using pthread_create()
* 2. Cancel that thread with pthread_cancel()
* 3. If that thread doesn't exist, then it pthread_cancel() will return
* an error code. This would mean that pthread_create() did not create
* a thread successfully.
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "posixtest.h"
static void *a_thread_func()
{
sleep(10);
/* Shouldn't reach here. If we do, then the pthread_cancel()
* function did not succeed. */
fprintf(stderr, "Could not send cancel request correctly\n");
return NULL;
}
static int posix_testcase(void)
{
pthread_t new_th;
int ret;
ret = pthread_create(&new_th, NULL, a_thread_func, NULL);
if (ret) {
fprintf(stderr, "pthread_create(): %s\n", strerror(ret));
return PTS_UNRESOLVED;
}
/* Try to cancel the newly created thread. If an error is returned,
* then the thread wasn't created successfully. */
ret = pthread_cancel(new_th);
if (ret) {
printf("Test FAILED: A new thread wasn't created: %s\n",
strerror(ret));
return PTS_FAIL;
}
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_create.1-2.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_detach()
*
* shall detach a thread. It shall indicate to the implementation that storage
* for 'thread' can be reclaimed when that thread terminates.
*
* STEPS:
* 1. Create a joinable thread
* 2. Detach that thread with pthread_detach()
* 3. Try and join the thread to main() using pthread_join()
* 4. An error should return from the pthread_join() function saying that the
* thread is detched. The test passes.
* 5. Else, if pthread_join is successful, the test fails.
*/
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include "posixtest.h"
static void *a_thread_func()
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
/* If the thread wasn't canceled in 10 seconds, time out */
sleep(10);
perror("Thread couldn't be canceled (at cleanup time), timing out\n");
pthread_exit(0);
return NULL;
}
static int posix_testcase(void)
{
pthread_attr_t new_attr;
pthread_t new_th;
int ret;
/* Initialize attribute */
if (pthread_attr_init(&new_attr) != 0) {
perror("Cannot initialize attribute object\n");
return PTS_UNRESOLVED;
}
/* Set the attribute object to be joinable */
if (pthread_attr_setdetachstate(&new_attr, PTHREAD_CREATE_JOINABLE) !=
0) {
perror("Error in pthread_attr_setdetachstate()\n");
return PTS_UNRESOLVED;
}
/* Create the thread */
if (pthread_create(&new_th, &new_attr, a_thread_func, NULL) != 0) {
perror("Error creating thread\n");
return PTS_UNRESOLVED;
}
/* Detach the thread. */
if (pthread_detach(new_th) != 0) {
printf("Error detaching thread\n");
return PTS_FAIL;
}
/* Now try and join it. This should fail. */
ret = pthread_join(new_th, NULL);
/* Cleanup: Cancel the thread */
pthread_cancel(new_th);
if (ret == 0) {
printf("Test FAILED\n");
return PTS_FAIL;
} else if (ret == EINVAL) {
printf("Test PASSED\n");
return PTS_PASS;
} else {
perror("Error in pthread_join\n");
return PTS_UNRESOLVED;
}
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_detach.1-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_detach()
*
* If 'thread' has not terminated, pthread_detach() shall not cause it to
* terminate. The effect of multiple pthread_detach() calls on the same
*
* STEPS:
* 1.Create a joinable thread
* 2.Detach that thread
* 3.Verify that the thread did not terminate because of this
*
*/
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include "posixtest.h"
static void *a_thread_func()
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
/* If the thread wasn't canceled in 10 seconds, time out */
sleep(10);
perror("Thread couldn't be canceled (at cleanup time), timing out\n");
pthread_exit(0);
return NULL;
}
static int posix_testcase(void)
{
pthread_attr_t new_attr;
pthread_t new_th;
int ret;
/* Initialize attribute */
if (pthread_attr_init(&new_attr) != 0) {
perror("Cannot initialize attribute object\n");
return PTS_UNRESOLVED;
}
/* Set the attribute object to be joinable */
if (pthread_attr_setdetachstate(&new_attr, PTHREAD_CREATE_JOINABLE) !=
0) {
perror("Error in pthread_attr_setdetachstate()\n");
return PTS_UNRESOLVED;
}
/* Create the thread */
if (pthread_create(&new_th, &new_attr, a_thread_func, NULL) != 0) {
perror("Error creating thread\n");
return PTS_UNRESOLVED;
}
/* Detach the thread. */
if (pthread_detach(new_th) != 0) {
printf("Error detaching thread\n");
return PTS_FAIL;
}
/* Verify that it hasn't terminated the thread */
ret = pthread_cancel(new_th);
if (ret != 0) {
if (ret == ESRCH) {
printf("Test FAILED\n");
return PTS_FAIL;
}
perror("Error canceling thread\n");
return PTS_UNRESOLVED;
}
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_detach.2-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_detach()
*
* Upon failure, it shall return an error number:
* -[EINVAL] The implemenation has detected that the value specified by
* 'thread' does not refer to a joinable thread.
* -[ESRCH] No thread could be found corresponding to that thread
* It shall not return an error code of [EINTR]
*
* STEPS:
* 1.Create a detached state thread
* 2.Detach that thread
* 3.Check the return value and make sure it is EINVAL
*
*/
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include "posixtest.h"
/* Thread function */
static void *a_thread_func()
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
/* If the thread wasn't canceled in 10 seconds, time out */
sleep(10);
perror("Thread couldn't be canceled (at cleanup time), timing out\n");
pthread_exit(0);
return NULL;
}
static int posix_testcase(void)
{
pthread_attr_t new_attr;
pthread_t new_th;
int ret;
/* Initialize attribute */
if (pthread_attr_init(&new_attr) != 0) {
perror("Cannot initialize attribute object\n");
return PTS_UNRESOLVED;
}
/* Set the attribute object to be detached */
if (pthread_attr_setdetachstate(&new_attr, PTHREAD_CREATE_DETACHED) !=
0) {
perror("Error in pthread_attr_setdetachstate()\n");
return PTS_UNRESOLVED;
}
/* Create the thread */
if (pthread_create(&new_th, &new_attr, a_thread_func, NULL) != 0) {
perror("Error creating thread\n");
return PTS_UNRESOLVED;
}
/* Detach the thread. */
ret = pthread_detach(new_th);
/* Cleanup and cancel the thread */
pthread_cancel(new_th);
/* Check return value of pthread_detach() */
if (ret != EINVAL) {
if (ret == ESRCH) {
perror("Error detaching thread\n");
return PTS_UNRESOLVED;
}
printf("Test FAILED: Incorrect return code\n");
return PTS_FAIL;
}
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_detach.4-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_exit()
*
* terminates the calling thread and makes the value 'value_ptr' available
* to any successful join with the terminating thread.
*
* Steps:
* 1. Create a new thread. Have it return a return code on pthread_exit();
* 2. Call pthread_join() in main(), and pass to it 'value_ptr'.
* 3. Check to see of the value_ptr and the value returned by pthread_exit() are the same;
*
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "posixtest.h"
#define RETURN_CODE 100 /* Set a random return code number. This shall be the return code of the
thread when using pthread_exit(). */
#define INTHREAD 0 /* Control going to or is already for Thread */
#define INMAIN 1 /* Control going to or is already for Main */
static int sem; /* Manual semaphore used to indicate when the thread has been created. */
/* Thread's function. */
static void *a_thread_func()
{
sem = INMAIN;
pthread_exit((void *)RETURN_CODE);
return NULL;
}
static int posix_testcase(void)
{
pthread_t new_th;
int *value_ptr;
/* Initializing variables. */
value_ptr = 0;
sem = INTHREAD;
/* Create a new thread. */
if (pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) {
perror("Error creating thread\n");
return PTS_UNRESOLVED;
}
/* Make sure the thread was created before we join it. */
while (sem == INTHREAD)
sleep(1);
/* Wait for thread to return */
if (pthread_join(new_th, (void *)&value_ptr) != 0) {
perror("Error in pthread_join()\n");
return PTS_UNRESOLVED;
}
/* Check to make sure that 'value_ptr' that was passed to pthread_join() and the
* pthread_exit() return code that was used in the thread function are the same. */
if ((long)value_ptr != RETURN_CODE) {
printf
("Test FAILED: pthread_exit() could not pass the return value of the thread in 'value_ptr' to pthread_join().\n");
return PTS_FAIL;
}
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_exit.1-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
*
* Test that pthread_join()
*
* shall suspend the execution of the calling thread until the target
* 'thread' terminates, unless 'thread' has already terminated.
*
* Steps:
* 1. Create a new thread. Have it sleep for 3 seconds.
* 2. The main() thread should wait for the new thread to finish
* execution before exiting out.
*
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "posixtest.h"
static int end_exec;
static void *a_thread_func()
{
int i;
printf("Wait for 3 seconds for thread to finish execution:\n");
for (i = 1; i < 4; i++) {
printf("Waited (%d) second\n", i);
sleep(1);
}
/* Indicate that the thread has ended execution. */
end_exec = 1;
pthread_exit(0);
return NULL;
}
static int posix_testcase(void)
{
pthread_t new_th;
/* Initialize flag */
end_exec = 0;
/* Create a new thread. */
if (pthread_create(&new_th, NULL, a_thread_func, NULL) != 0) {
perror("Error creating thread\n");
return PTS_UNRESOLVED;
}
/* Wait for thread to return */
if (pthread_join(new_th, NULL) != 0) {
perror("Error in pthread_join()\n");
return PTS_UNRESOLVED;
}
if (end_exec == 0) {
printf("Test FAILED: When using pthread_join(), "
"main() did not wait for thread to finish "
"execution before continuing.\n");
return PTS_FAIL;
}
printf("Test PASSED\n");
return PTS_PASS;
}
#include <rtt_utest_internal.h>
UTEST_TC_EXPORT(testcase, "posix.pthread_join.1-1.c", RT_NULL, RT_NULL, 10);

View file

@ -0,0 +1,24 @@
#include <utest.h>
#include <pthread.h>
static void posix_unit_test(void)
{
pthread_t new_th; /* Create a new thread. */
int err_val;
if (pthread_create(&new_th, NULL, (void *(*)(void *))posix_testcase, NULL) != 0) {
perror("Error creating thread\n");
}
/* Wait for thread to return */
if (pthread_join(new_th, (void*)&err_val) != 0) {
perror("Error in pthread_join()\n");
}
rt_thread_mdelay(1000);
uassert_true(err_val == 0);
}
static void testcase(void)
{
UTEST_UNIT_RUN(posix_unit_test);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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