From: Robert W. <ro...@us...> - 2004-07-06 15:59:02
|
Update of /cvsroot/ltp/ltp/testcases/open_posix_testsuite/conformance/interfaces/pthread_cancel In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2859/conformance/interfaces/pthread_cancel Added Files: 2-2.c 2-3.c 3-1.c Log Message: Updated to Posixtestsuite-1.4.3 --- NEW FILE: 2-2.c --- /* * Copyright (c) 2004, QUALCOMM Inc. All rights reserved. * Created by: abisain REMOVE-THIS AT qualcomm 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 pthread_cancel() * * Any destructors for thread_specific data will be called * * Steps: * 1. Create a new thread. * 2. Create a thread specific object in the thread with a destructor * 3. Call pthread_cancel on the thread. * 4. Make sure that the destructor was called * */ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "posixtest.h" #define TEST "2-2" #define FUNCTION "pthread_cancel" #define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": " int cleanup_flag = 0; int sem = 0; /* manual semaphore */ void destructor(void *tmp) { cleanup_flag = 1; } /* Thread's function. */ void *a_thread_func(void *tmp) { pthread_key_t key; int value = 1; int rc = 0; /* To enable thread immediate cancelation, since the default * is PTHREAD_CANCEL_DEFERRED. */ rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); if (rc != 0) { printf(ERROR_PREFIX "pthread_setcanceltype\n"); exit(PTS_UNRESOLVED); } rc = pthread_key_create(&key, destructor); if (rc != 0) { printf(ERROR_PREFIX "pthread_key_create\n"); exit(PTS_UNRESOLVED); } rc = pthread_setspecific(key, &value); if (rc != 0) { printf(ERROR_PREFIX "pthread_setspecific\n"); exit(PTS_UNRESOLVED); } /* Tell main that the key is created */ sem = 1; /* Sleep forever */ while(1) sleep(5); return NULL; } int main() { pthread_t new_th; int rc = 0; sem = 0; /* Create a new thread. */ rc = pthread_create(&new_th, NULL, a_thread_func, NULL); if(rc != 0) { printf(ERROR_PREFIX "pthread_create\n"); exit(PTS_UNRESOLVED); } /* Wait for the thread to be ready */ while(sem == 0) sleep(1); /* Cancel the thread. */ rc = pthread_cancel(new_th); if(rc != 0) { printf(ERROR_PREFIX "pthread_cancel\n"); exit(PTS_UNRESOLVED); } /* Delay enough so that the destructor must have been called */ sleep(5); if(cleanup_flag != 1) { printf(ERROR_PREFIX "Test FAIL: Destructor was not executed.\n"); exit(PTS_FAIL); } printf("Test PASS\n"); exit(PTS_PASS); } --- NEW FILE: 3-1.c --- /* * Copyright (c) 2004, QUALCOMM Inc. All rights reserved. * Created by: abisain REMOVE-THIS AT qualcomm 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 pthread_cancel * When the cancelation is acted on, the cancelation cleanup handlers for * 'thread' shall be called "asynchronously" * * STEPS: * 1. Change main thread to a real-time thread with a high priority * 1. Create a lower priority thread * 2. In the thread function, push a cleanup function onto the stack * 3. Cancel the thread from main and get timestamp, then block. * 4. The cleanup function should be automatically * executed, else the test will fail. */ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include "posixtest.h" #include <time.h> #define TEST "3-1" #define FUNCTION "pthread_cancel" #define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": " #define FIFOPOLICY SCHED_FIFO #define MAIN_PRIORITY 30 #define TIMEOUT_IN_SECS 10 /* Manual semaphore */ int sem; /* Made global so that the cleanup function * can manipulate the value as well. */ int cleanup_flag; struct timespec main_time, cleanup_time; /* A cleanup function that sets the cleanup_flag to 1, meaning that the * cleanup function was reached. */ void a_cleanup_func() { clock_gettime(CLOCK_REALTIME, &cleanup_time); cleanup_flag = 1; sem = 0; return; } /* A thread function called at the creation of the thread. It will push * the cleanup function onto it's stack, then go into a continuous 'while' * loop, never reaching the cleanup_pop function. So the only way the cleanup * function can be called is when the thread is canceled and all the cleanup * functions are supposed to be popped. */ void *a_thread_func() { int rc = 0; /* To enable thread immediate cancelation, since the default * is PTHREAD_CANCEL_DEFERRED. */ rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); if(rc != 0) { printf(ERROR_PREFIX "pthread_setcanceltype\n"); exit(PTS_UNRESOLVED); } pthread_cleanup_push(a_cleanup_func, NULL); sem=1; while(sem == 1) sleep(1); sleep(5); sem=0; /* Should never be reached, but is required to be in the code * since pthread_cleanup_push is in the code. Else a compile error * will result. */ pthread_cleanup_pop(0); pthread_exit(0); return NULL; } int main() { pthread_t new_th; int i; double diff ; struct sched_param param; int rc = 0; /* Initializing the cleanup flag. */ cleanup_flag = 0; sem = 0; param.sched_priority = MAIN_PRIORITY; /* Increase priority of main, so the new thread doesn't get to run */ rc = pthread_setschedparam(pthread_self(), FIFOPOLICY, ¶m); if(rc != 0) { printf(ERROR_PREFIX "pthread_setschedparam\n"); exit(PTS_UNRESOLVED); } /* Create a new thread. */ rc = pthread_create(&new_th, NULL, a_thread_func, NULL); if(rc != 0) { printf(ERROR_PREFIX "pthread_create\n"); return PTS_UNRESOLVED; } /* Make sure thread is created and executed before we cancel it. */ while(sem == 0) sleep(1); rc = pthread_cancel(new_th); if(rc != 0) { printf(ERROR_PREFIX "pthread_cancel\n"); exit(PTS_FAIL); } /* Get the time after canceling the thread */ clock_gettime(CLOCK_REALTIME, &main_time); i = 0; while(sem == 1) { sleep(1); if(i == TIMEOUT_IN_SECS) { printf(ERROR_PREFIX "Cleanup handler was not called\n"); exit(PTS_FAIL); } i++; } /* If the cleanup function was not reached by calling the * pthread_cancel function, then the test fails. */ if(cleanup_flag != 1) { printf(ERROR_PREFIX "Cleanup handler was not called\n"); exit(PTS_FAIL); } diff = cleanup_time.tv_sec - main_time.tv_sec; diff += (double)(cleanup_time.tv_nsec - main_time.tv_nsec)/1000000000.0; if(diff < 0) { printf(ERROR_PREFIX "Cleanup function was called before main continued\n"); exit(PTS_FAIL); } printf("Test PASS\n"); exit(PTS_PASS); } --- NEW FILE: 2-3.c --- /* * Copyright (c) 2004, QUALCOMM Inc. All rights reserved. * Created by: abisain REMOVE-THIS AT qualcomm 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 pthread_cancel() * * Any destructors for thread_specific data will be called after * all cleanup handlers return * * Steps: * 1. Create a new thread. * 2. Create a thread specific object in the thread with a destructor * 3. Add a cleanup function in the thread * 4. Call pthread_cancel on the thread. * 5. Make sure that the destructor was called after the cleanup handler * */ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "posixtest.h" #define TEST "2-3" #define FUNCTION "pthread_cancel" #define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": " int cleanup_flag = 0; int destructor_flag = 0; int sem = 0; /* manual semaphore */ struct timespec destructor_time, cleanup_time; /* Destructor for the Thread Specific Data */ void destructor(void *tmp) { clock_gettime(CLOCK_REALTIME, &destructor_time); destructor_flag = 1; } /* Cleanup Handler for the Thread */ void cleanup_function() { clock_gettime(CLOCK_REALTIME, &cleanup_time); cleanup_flag = 1; } /* Thread's function. */ void *a_thread_func(void *tmp) { pthread_key_t key; int value = 1; int rc = 0; /* To enable thread immediate cancelation, since the default * is PTHREAD_CANCEL_DEFERRED. */ rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); if (rc != 0) { printf(ERROR_PREFIX "pthread_setcanceltype\n"); exit(PTS_UNRESOLVED); } rc = pthread_key_create(&key, destructor); if (rc != 0) { printf(ERROR_PREFIX "pthread_key_create\n"); exit(PTS_UNRESOLVED); } rc = pthread_setspecific(key, &value); if (rc != 0) { printf(ERROR_PREFIX "pthread_setspecific\n"); exit(PTS_UNRESOLVED); } pthread_cleanup_push(cleanup_function, NULL); /* Tell main that the key is created */ sem = 1; /* Sleep forever */ while(1) sleep(5); pthread_cleanup_pop(0); return NULL; } int main() { pthread_t new_th; int rc = 0; double diff; sem = 0; /* Create a new thread. */ rc = pthread_create(&new_th, NULL, a_thread_func, NULL); if(rc != 0) { printf(ERROR_PREFIX "pthread_create\n"); exit(PTS_UNRESOLVED); } /* Wait for the thread to be ready */ while(sem == 0) sleep(1); /* Cancel the thread. */ rc = pthread_cancel(new_th); if(rc != 0) { printf(ERROR_PREFIX "pthread_cancel\n"); exit(PTS_UNRESOLVED); } /* Delay enough so that the destructor must have been called */ sleep(5); if(cleanup_flag != 1) { printf(ERROR_PREFIX "Test FAIL: Cleanup handler was not executed.\n"); exit(PTS_FAIL); } if(destructor_flag != 1) { printf(ERROR_PREFIX "Test FAIL: Destructor was not executed.\n"); exit(PTS_FAIL); } diff = destructor_time.tv_sec - cleanup_time.tv_sec; diff += (double)(destructor_time.tv_nsec - cleanup_time.tv_nsec)/1000000000.0; if(diff < 0) { printf(ERROR_PREFIX "Test FAIL: Destructor called before Cleanup Handler\n"); exit(PTS_FAIL); } printf("Test PASS\n"); exit(PTS_PASS); } |