diff options
Diffstat (limited to 'test/pthread')
-rw-r--r-- | test/pthread/Makefile | 8 | ||||
-rw-r--r-- | test/pthread/Makefile.in | 10 | ||||
-rw-r--r-- | test/pthread/cancellation-points.c | 286 | ||||
-rw-r--r-- | test/pthread/ex1.c | 35 | ||||
-rw-r--r-- | test/pthread/ex2.c | 113 | ||||
-rw-r--r-- | test/pthread/ex3.c | 152 | ||||
-rw-r--r-- | test/pthread/ex4.c | 107 | ||||
-rw-r--r-- | test/pthread/ex5.c | 102 | ||||
-rw-r--r-- | test/pthread/ex6.c | 44 | ||||
-rw-r--r-- | test/pthread/ex7.c | 106 | ||||
-rw-r--r-- | test/pthread/ex8-mtx-odd.c | 56 | ||||
-rw-r--r-- | test/pthread/tst-c99.c | 2 | ||||
-rw-r--r-- | test/pthread/tst-join2.c | 103 | ||||
-rw-r--r-- | test/pthread/tst-join3.c | 122 | ||||
-rw-r--r-- | test/pthread/tst-too-many-cleanups.c | 104 |
15 files changed, 0 insertions, 1350 deletions
diff --git a/test/pthread/Makefile b/test/pthread/Makefile deleted file mode 100644 index 97ebee894..000000000 --- a/test/pthread/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# uClibc pthread tests -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - -top_builddir=../../ -top_srcdir=../../ -include ../Rules.mak --include Makefile.in -include ../Test.mak diff --git a/test/pthread/Makefile.in b/test/pthread/Makefile.in deleted file mode 100644 index bd6b29b0c..000000000 --- a/test/pthread/Makefile.in +++ /dev/null @@ -1,10 +0,0 @@ -# uClibc pthread tests -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - -TESTS_DISABLED += cancellation-points - -EXTRA_LDFLAGS := -lpthread - -LDFLAGS_cancellation-points := -lrt - -CFLAGS_tst-c99 := -std=c99 diff --git a/test/pthread/cancellation-points.c b/test/pthread/cancellation-points.c deleted file mode 100644 index 5453060f7..000000000 --- a/test/pthread/cancellation-points.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Make sure functions marked as cancellation points actually are. - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html#tag_02_09_05 - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <features.h> -#include <sys/ipc.h> -#include <sys/mman.h> -#include <sys/msg.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <mqueue.h> -#include <poll.h> -#include <pthread.h> -#include <semaphore.h> -#include <signal.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <termios.h> -#include <time.h> -#include <unistd.h> - -/* take care of optional things ... */ -#define STUB(func, args) static void func args { sleep(0); } -#if defined(__UCLIBC_AIO__) -# include <aio.h> -#else -STUB(aio_suspend, (void *p, int n, const void *p2)) -#endif -#if defined(__UCLIBC_STROPTS__) -# include <stropts.h> -#else -STUB(getmsg, (int f, void *p, void *p2, void *p3)) -STUB(getpmsg, (int f, void *p, void *p2, void *p3, void *p4)) -STUB(putmsg, (int f, void *p, void *p2, void *p3)) -STUB(putpmsg, (int f, void *p, void *p2, void *p3, void *p4)) -#endif -#if defined(__UCLIBC__) -STUB(clock_nanosleep, (int i, int f, const void *p, void *p2)) -#endif - -int cnt; -bool ready; - -void cancel_timeout(int sig) -{ - ready = false; -} -void cancel_thread_cleanup(void *arg) -{ - ready = false; -} - -/* some funcs need some help as they wont take NULL args ... */ -const struct timespec zero_sec = { .tv_sec = 0, .tv_nsec = 0 }; - -sem_t sem; -void help_sem_setup(void) -{ - if (sem_init(&sem, 0, 1) == -1) { - perror("sem_init() failed"); - exit(-1); - } -} - -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -pthread_mutex_t mutex; -void help_pthread_setup(void) -{ - pthread_mutex_init(&mutex, NULL); - pthread_mutex_lock(&mutex); -} - -/* the pthread function that will call the cancellable function over and over */ -#define _MAKE_CANCEL_THREAD_FUNC_EX(func, sysfunc, args, setup) \ -void *cancel_thread_##func(void *arg) \ -{ \ - if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)) { \ - perror("unable to set cancel type to deferred; something is seriously broken"); \ - exit(-1); \ - } \ - pthread_cleanup_push(cancel_thread_cleanup, NULL); \ - setup; \ - ready = true; \ - while (ready) \ - sysfunc args; \ - pthread_cleanup_pop(1); \ - return NULL; \ -} -#define MAKE_CANCEL_THREAD_FUNC_RE(func, sysfunc, args) _MAKE_CANCEL_THREAD_FUNC_EX(func, sysfunc, args, (void)0) -#define MAKE_CANCEL_THREAD_FUNC_EX(func, args, setup) _MAKE_CANCEL_THREAD_FUNC_EX(func, func, args, setup) -#define MAKE_CANCEL_THREAD_FUNC(func, args) _MAKE_CANCEL_THREAD_FUNC_EX(func, func, args, (void)0) - -MAKE_CANCEL_THREAD_FUNC(accept, (-1, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(aio_suspend, (NULL, 0, &zero_sec)) -MAKE_CANCEL_THREAD_FUNC(clock_nanosleep, (0, 0, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(close, (-1)) -MAKE_CANCEL_THREAD_FUNC(connect, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(creat, ("", 0)) -MAKE_CANCEL_THREAD_FUNC(fcntl, (0, F_SETLKW, NULL)) -MAKE_CANCEL_THREAD_FUNC(fdatasync, (-1)) -MAKE_CANCEL_THREAD_FUNC(fsync, (0)) -MAKE_CANCEL_THREAD_FUNC(getmsg, (-1, NULL, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(getpmsg, (-1, NULL, NULL, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(lockf, (-1, F_TEST, 0)) -MAKE_CANCEL_THREAD_FUNC(mq_receive, (0, NULL, 0, NULL)) -MAKE_CANCEL_THREAD_FUNC(mq_send, (0, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(mq_timedreceive, (0, NULL, 0, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(mq_timedsend, (0, NULL, 0, 0, NULL)) -MAKE_CANCEL_THREAD_FUNC(msgrcv, (-1, NULL, 0, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(msgsnd, (-1, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(msync, (NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(nanosleep, (NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(open, ("", 0)) -MAKE_CANCEL_THREAD_FUNC(pause, ()) -MAKE_CANCEL_THREAD_FUNC(poll, (NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(pread, (-1, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(pselect, (0, NULL, NULL, NULL, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC_EX(pthread_cond_timedwait, (&cond, &mutex, &zero_sec), help_pthread_setup()) -MAKE_CANCEL_THREAD_FUNC_EX(pthread_cond_wait, (&cond, &mutex), help_pthread_setup()) -/*MAKE_CANCEL_THREAD_FUNC_EX(pthread_join, (0, NULL))*/ -MAKE_CANCEL_THREAD_FUNC(pthread_testcancel, ()) -MAKE_CANCEL_THREAD_FUNC(putmsg, (-1, NULL, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(putpmsg, (-1, NULL, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(pwrite, (-1, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(read, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(readv, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(recv, (-1, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(recvfrom, (-1, NULL, 0, 0, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(recvmsg, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(select, (0, NULL, NULL, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC_EX(sem_timedwait, (&sem, &zero_sec), help_sem_setup()) -MAKE_CANCEL_THREAD_FUNC_EX(sem_wait, (&sem), help_sem_setup()) -MAKE_CANCEL_THREAD_FUNC(send, (-1, NULL, 0, 0)) -MAKE_CANCEL_THREAD_FUNC(sendmsg, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(sendto, (-1, NULL, 0, 0, NULL, 0)) -#ifdef __UCLIBC_SUSV4_LEGACY__ -MAKE_CANCEL_THREAD_FUNC(sigpause, (0)) -#endif -MAKE_CANCEL_THREAD_FUNC(sigsuspend, (NULL)) -MAKE_CANCEL_THREAD_FUNC(sigtimedwait, (NULL, NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(sigwait, (NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(sigwaitinfo, (NULL, NULL)) -MAKE_CANCEL_THREAD_FUNC(sleep, (0)) -MAKE_CANCEL_THREAD_FUNC(system, ("")) -MAKE_CANCEL_THREAD_FUNC(tcdrain, (-1)) -#ifdef __UCLIBC_SUSV3_LEGACY__ -MAKE_CANCEL_THREAD_FUNC(usleep, (0)) -#endif -MAKE_CANCEL_THREAD_FUNC(wait, (NULL)) -MAKE_CANCEL_THREAD_FUNC(waitid, (0, 0, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(waitpid, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(write, (-1, NULL, 0)) -MAKE_CANCEL_THREAD_FUNC(writev, (-1, NULL, 0)) - -/* test a few variations that should not cancel ... */ -MAKE_CANCEL_THREAD_FUNC_RE(fcntl_another, fcntl, (0, F_GETFD)) - -/* main test that creates thread, cancels it, etc... */ -int _test_func(const char *func_name, void *(*func)(void*), const int should_cancel) -{ - int ret; - pthread_t cancel_thread_id; - - ++cnt; - - printf("testing %-30s ", func_name); - - printf("."); - if (signal(SIGALRM, cancel_timeout) == SIG_ERR) { - perror("unable to bind SIGALRM"); - exit(-1); - } - - printf("."); - ready = false; - pthread_create(&cancel_thread_id, NULL, func, NULL); - - printf("."); - while (!ready) - sched_yield(); - - printf("."); - if (pthread_cancel(cancel_thread_id)) { - perror("unable to cancel thread"); - exit(-1); - } - - printf("."); - alarm(5); - while (ready) - sched_yield(); - - printf("."); - ret = (!!!alarm(0) == should_cancel); - - if (ret) - printf(" failed ;(\n"); - else - printf(" OK!\n"); - - return ret; -} -#define TEST_FUNC(f) _test_func(#f, cancel_thread_##f, 1) -#define TEST_FUNC_RE(f) _test_func(#f, cancel_thread_##f, 0) - -int main(int argc, char *argv[]) -{ - int ret = 0; - setbuf(stdout, NULL); - cnt = 0; - - ret += TEST_FUNC(accept); - ret += TEST_FUNC(aio_suspend); - ret += TEST_FUNC(clock_nanosleep); - ret += TEST_FUNC(close); - ret += TEST_FUNC(connect); - ret += TEST_FUNC(creat); - ret += TEST_FUNC(fcntl); - ret += TEST_FUNC(fdatasync); - ret += TEST_FUNC(fsync); - ret += TEST_FUNC(getmsg); - ret += TEST_FUNC(getpmsg); - ret += TEST_FUNC(lockf); - ret += TEST_FUNC(mq_receive); - ret += TEST_FUNC(mq_send); - ret += TEST_FUNC(mq_timedreceive); - ret += TEST_FUNC(mq_timedsend); - ret += TEST_FUNC(msgrcv); - ret += TEST_FUNC(msgsnd); - ret += TEST_FUNC(msync); - ret += TEST_FUNC(nanosleep); - ret += TEST_FUNC(open); - ret += TEST_FUNC(pause); - ret += TEST_FUNC(poll); - ret += TEST_FUNC(pread); - ret += TEST_FUNC(pselect); - ret += TEST_FUNC(pthread_cond_timedwait); - ret += TEST_FUNC(pthread_cond_wait); - /*ret += TEST_FUNC(pthread_join);*/ - ret += TEST_FUNC(pthread_testcancel); - ret += TEST_FUNC(putmsg); - ret += TEST_FUNC(putpmsg); - ret += TEST_FUNC(pwrite); - ret += TEST_FUNC(read); - ret += TEST_FUNC(readv); - ret += TEST_FUNC(recv); - ret += TEST_FUNC(recvfrom); - ret += TEST_FUNC(recvmsg); - ret += TEST_FUNC(select); - ret += TEST_FUNC(sem_timedwait); - ret += TEST_FUNC(sem_wait); - ret += TEST_FUNC(send); - ret += TEST_FUNC(sendmsg); - ret += TEST_FUNC(sendto); - ret += TEST_FUNC(sigpause); - ret += TEST_FUNC(sigsuspend); - ret += TEST_FUNC(sigtimedwait); - ret += TEST_FUNC(sigwait); - ret += TEST_FUNC(sigwaitinfo); - ret += TEST_FUNC(sleep); - ret += TEST_FUNC(system); - ret += TEST_FUNC(tcdrain); -#ifdef __UCLIBC_SUSV3_LEGACY__ - ret += TEST_FUNC(usleep); -#endif - ret += TEST_FUNC(wait); - ret += TEST_FUNC(waitid); - ret += TEST_FUNC(waitpid); - ret += TEST_FUNC(write); - ret += TEST_FUNC(writev); - - ret += TEST_FUNC_RE(fcntl_another); - - if (ret) - printf("!!! %i / %i tests failed\n", ret, cnt); - - return ret; -} diff --git a/test/pthread/ex1.c b/test/pthread/ex1.c deleted file mode 100644 index 4d9de03d8..000000000 --- a/test/pthread/ex1.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Creates two threads, one printing 10000 "a"s, the other printing - 10000 "b"s. - Illustrates: thread creation, thread joining. */ - -#include <stddef.h> -#include <stdio.h> -#include <unistd.h> -#include "pthread.h" - -static void *process(void * arg) -{ - int i; - printf("Starting process %s\n", (char *)arg); - for (i = 0; i < 10000; i++) - write(1, (char *) arg, 1); - return NULL; -} - -#define sucfail(r) (r != 0 ? "failed" : "succeeded") -int main(void) -{ - int pret, ret = 0; - pthread_t th_a, th_b; - void *retval; - - ret += (pret = pthread_create(&th_a, NULL, process, (void *)"a")); - printf("create a %s %d\n", sucfail(pret), pret); - ret += (pret = pthread_create(&th_b, NULL, process, (void *)"b")); - printf("create b %s %d\n", sucfail(pret), pret); - ret += (pret = pthread_join(th_a, &retval)); - printf("join a %s %d\n", sucfail(pret), pret); - ret += (pret = pthread_join(th_b, &retval)); - printf("join b %s %d\n", sucfail(pret), pret); - return ret; -} diff --git a/test/pthread/ex2.c b/test/pthread/ex2.c deleted file mode 100644 index 98bd4b347..000000000 --- a/test/pthread/ex2.c +++ /dev/null @@ -1,113 +0,0 @@ -/* The classic producer-consumer example. - Illustrates mutexes and conditions. - All integers between 0 and 9999 should be printed exactly twice, - once to the right of the arrow and once to the left. */ - -#include <stdio.h> -#include "pthread.h" - -#define BUFFER_SIZE 16 - -/* Circular buffer of integers. */ - -struct prodcons { - int buffer[BUFFER_SIZE]; /* the actual data */ - pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */ - int readpos, writepos; /* positions for reading and writing */ - pthread_cond_t notempty; /* signaled when buffer is not empty */ - pthread_cond_t notfull; /* signaled when buffer is not full */ -}; - -/* Initialize a buffer */ - -static void init(struct prodcons * b) -{ - pthread_mutex_init(&b->lock, NULL); - pthread_cond_init(&b->notempty, NULL); - pthread_cond_init(&b->notfull, NULL); - b->readpos = 0; - b->writepos = 0; -} - -/* Store an integer in the buffer */ - -static void put(struct prodcons * b, int data) -{ - pthread_mutex_lock(&b->lock); - /* Wait until buffer is not full */ - while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) { - pthread_cond_wait(&b->notfull, &b->lock); - /* pthread_cond_wait reacquired b->lock before returning */ - } - /* Write the data and advance write pointer */ - b->buffer[b->writepos] = data; - b->writepos++; - if (b->writepos >= BUFFER_SIZE) b->writepos = 0; - /* Signal that the buffer is now not empty */ - pthread_cond_signal(&b->notempty); - pthread_mutex_unlock(&b->lock); -} - -/* Read and remove an integer from the buffer */ - -static int get(struct prodcons * b) -{ - int data; - pthread_mutex_lock(&b->lock); - /* Wait until buffer is not empty */ - while (b->writepos == b->readpos) { - pthread_cond_wait(&b->notempty, &b->lock); - } - /* Read the data and advance read pointer */ - data = b->buffer[b->readpos]; - b->readpos++; - if (b->readpos >= BUFFER_SIZE) b->readpos = 0; - /* Signal that the buffer is now not full */ - pthread_cond_signal(&b->notfull); - pthread_mutex_unlock(&b->lock); - return data; -} - -/* A test program: one thread inserts integers from 1 to 10000, - the other reads them and prints them. */ - -#define OVER (-1) - -struct prodcons buffer; - -static void * producer(void * data) -{ - int n; - for (n = 0; n < 10000; n++) { - printf("%d --->\n", n); - put(&buffer, n); - } - put(&buffer, OVER); - return NULL; -} - -static void * consumer(void * data) -{ - int d; - while (1) { - d = get(&buffer); - if (d == OVER) break; - printf("---> %d\n", d); - } - return NULL; -} - -int main(void) -{ - pthread_t th_a, th_b; - void * retval; - - init(&buffer); - /* Create the threads */ - pthread_create(&th_a, NULL, producer, 0); - pthread_create(&th_b, NULL, consumer, 0); - /* Wait until producer and consumer finish. */ - pthread_join(th_a, &retval); - pthread_join(th_b, &retval); - return 0; -} diff --git a/test/pthread/ex3.c b/test/pthread/ex3.c deleted file mode 100644 index 8ef779789..000000000 --- a/test/pthread/ex3.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Multi-thread searching. - Illustrates: thread cancellation, cleanup handlers. */ - -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/types.h> -#include <pthread.h> - -/* Defines the number of searching threads */ -#define NUM_THREADS 5 - -/* Function prototypes */ -void *search(void *); -void print_it(void *); - -/* Global variables */ -pthread_t threads[NUM_THREADS]; -pthread_mutex_t lock; -int tries; -volatile int started; - -int main(int argc, char ** argv) -{ - unsigned long i; - unsigned long pid; - - /* create a number to search for */ - pid = getpid(); - printf("Searching for the number = %ld...\n", pid); - - /* Initialize the mutex lock */ - pthread_mutex_init(&lock, NULL); - - /* Create the searching threads */ - for (started=0; started<NUM_THREADS; started++) - pthread_create(&threads[started], NULL, search, (void *)pid); - - /* Wait for (join) all the searching threads */ - for (i=0; i<NUM_THREADS; i++) - pthread_join(threads[i], NULL); - - printf("It took %d tries to find the number.\n", tries); - - /* Exit the program */ - return 0; -} - -/* This is the cleanup function that is called - when the threads are cancelled */ - -void print_it(void *arg) -{ - int *try = (int *) arg; - pthread_t tid; - - /* Get the calling thread's ID */ - tid = pthread_self(); - - /* Print where the thread was in its search when it was cancelled */ - printf("Thread %lx was canceled on its %d try.\n", tid, *try); -} - -/* This is the search routine that is executed in each thread */ - -void *search(void *arg) -{ - unsigned long num = (unsigned long) arg; - unsigned long i, j, ntries; - pthread_t tid; - - /* get the calling thread ID */ - tid = pthread_self(); - - /* use the thread ID to set the seed for the random number generator */ - /* Since srand and rand are not thread-safe, serialize with lock */ - - /* Try to lock the mutex lock -- - if locked, check to see if the thread has been cancelled - if not locked then continue */ - while (pthread_mutex_trylock(&lock) == EBUSY) - pthread_testcancel(); - - srand((int)tid); - i = rand() & 0xFFFFFF; - pthread_mutex_unlock(&lock); - ntries = 0; - - /* Set the cancellation parameters -- - - Enable thread cancellation - - Defer the action of the cancellation */ - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); - - while (started < NUM_THREADS) - sched_yield (); - - /* Push the cleanup routine (print_it) onto the thread - cleanup stack. This routine will be called when the - thread is cancelled. Also note that the pthread_cleanup_push - call must have a matching pthread_cleanup_pop call. The - push and pop calls MUST be at the same lexical level - within the code */ - - /* Pass address of `ntries' since the current value of `ntries' is not - the one we want to use in the cleanup function */ - - pthread_cleanup_push(print_it, (void *)&ntries); - - /* Loop forever */ - while (1) { - i = (i + 1) & 0xFFFFFF; - ntries++; - - /* Does the random number match the target number? */ - if (num == i) { - /* Try to lock the mutex lock -- - if locked, check to see if the thread has been cancelled - if not locked then continue */ - while (pthread_mutex_trylock(&lock) == EBUSY) - pthread_testcancel(); - - /* Set the global variable for the number of tries */ - tries = ntries; - printf("Thread %lx found the number!\n", tid); - - /* Cancel all the other threads */ - for (j=0; j<NUM_THREADS; j++) - if (threads[j] != tid) pthread_cancel(threads[j]); - - /* Break out of the while loop */ - break; - } - - /* Every 100 tries check to see if the thread has been cancelled. */ - if (ntries % 100 == 0) { - pthread_testcancel(); - } - } - - /* The only way we can get here is when the thread breaks out - of the while loop. In this case the thread that makes it here - has found the number we are looking for and does not need to run - the thread cleanup function. This is why the pthread_cleanup_pop - function is called with a 0 argument; this will pop the cleanup - function off the stack without executing it */ - - pthread_cleanup_pop(0); - return((void *)0); -} diff --git a/test/pthread/ex4.c b/test/pthread/ex4.c deleted file mode 100644 index cf4cf1d69..000000000 --- a/test/pthread/ex4.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Making a library function that uses static variables thread-safe. - Illustrates: thread-specific data, pthread_once(). */ - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> - -/* This is a typical example of a library function that uses - static variables to accumulate results between calls. - Here, it just returns the concatenation of all string arguments - that were given to it. */ - -#if 0 - -static char * str_accumulate(char * s) -{ - static char accu[1024] = { 0 }; - strcat(accu, s); - return accu; -} - -#endif - -/* Of course, this cannot be used in a multi-threaded program - because all threads store "accu" at the same location. - So, we'll use thread-specific data to have a different "accu" - for each thread. */ - -/* Key identifying the thread-specific data */ -static pthread_key_t str_key; -/* "Once" variable ensuring that the key for str_alloc will be allocated - exactly once. */ -static pthread_once_t str_alloc_key_once = PTHREAD_ONCE_INIT; - -/* Forward functions */ -static void str_alloc_key(void); -static void str_alloc_destroy_accu(void * accu); - -/* Thread-safe version of str_accumulate */ - -static char * str_accumulate(const char * s) -{ - char * accu; - - /* Make sure the key is allocated */ - pthread_once(&str_alloc_key_once, str_alloc_key); - /* Get the thread-specific data associated with the key */ - accu = (char *) pthread_getspecific(str_key); - /* It's initially NULL, meaning that we must allocate the buffer first. */ - if (accu == NULL) { - accu = malloc(1024); - if (accu == NULL) return NULL; - accu[0] = 0; - /* Store the buffer pointer in the thread-specific data. */ - pthread_setspecific(str_key, (void *) accu); - printf("Thread %lx: allocating buffer at %p\n", pthread_self(), accu); - } - /* Now we can use accu just as in the non thread-safe code. */ - strcat(accu, s); - return accu; -} - -/* Function to allocate the key for str_alloc thread-specific data. */ - -static void str_alloc_key(void) -{ - pthread_key_create(&str_key, str_alloc_destroy_accu); - printf("Thread %lx: allocated key %d\n", pthread_self(), str_key); -} - -/* Function to free the buffer when the thread exits. */ -/* Called only when the thread-specific data is not NULL. */ - -static void str_alloc_destroy_accu(void * accu) -{ - printf("Thread %lx: freeing buffer at %p\n", pthread_self(), accu); - free(accu); -} - -/* Test program */ - -static void * process(void * arg) -{ - char * res; - res = str_accumulate("Result of "); - res = str_accumulate((char *) arg); - res = str_accumulate(" thread"); - printf("Thread %lx: \"%s\"\n", pthread_self(), res); - return NULL; -} - -int main(int argc, char ** argv) -{ - char * res; - pthread_t th1, th2; - - res = str_accumulate("Result of "); - pthread_create(&th1, NULL, process, (void *) "first"); - pthread_create(&th2, NULL, process, (void *) "second"); - res = str_accumulate("initial thread"); - printf("Thread %lx: \"%s\"\n", pthread_self(), res); - pthread_join(th1, NULL); - pthread_join(th2, NULL); - exit(0); -} diff --git a/test/pthread/ex5.c b/test/pthread/ex5.c deleted file mode 100644 index 7a293eb01..000000000 --- a/test/pthread/ex5.c +++ /dev/null @@ -1,102 +0,0 @@ -/* The classic producer-consumer example, implemented with semaphores. - All integers between 0 and 9999 should be printed exactly twice, - once to the right of the arrow and once to the left. */ - -#include <stdio.h> -#include "pthread.h" -#include "semaphore.h" - -#define BUFFER_SIZE 16 - -/* Circular buffer of integers. */ - -struct prodcons { - int buffer[BUFFER_SIZE]; /* the actual data */ - int readpos, writepos; /* positions for reading and writing */ - sem_t sem_read; /* number of elements available for reading */ - sem_t sem_write; /* number of locations available for writing */ -}; - -/* Initialize a buffer */ - -static void init(struct prodcons * b) -{ - sem_init(&b->sem_write, 0, BUFFER_SIZE - 1); - sem_init(&b->sem_read, 0, 0); - b->readpos = 0; - b->writepos = 0; -} - -/* Store an integer in the buffer */ - -static void put(struct prodcons * b, int data) -{ - /* Wait until buffer is not full */ - sem_wait(&b->sem_write); - /* Write the data and advance write pointer */ - b->buffer[b->writepos] = data; - b->writepos++; - if (b->writepos >= BUFFER_SIZE) b->writepos = 0; - /* Signal that the buffer contains one more element for reading */ - sem_post(&b->sem_read); -} - -/* Read and remove an integer from the buffer */ - -static int get(struct prodcons * b) -{ - int data; - /* Wait until buffer is not empty */ - sem_wait(&b->sem_read); - /* Read the data and advance read pointer */ - data = b->buffer[b->readpos]; - b->readpos++; - if (b->readpos >= BUFFER_SIZE) b->readpos = 0; - /* Signal that the buffer has now one more location for writing */ - sem_post(&b->sem_write); - return data; -} - -/* A test program: one thread inserts integers from 1 to 10000, - the other reads them and prints them. */ - -#define OVER (-1) - -struct prodcons buffer; - -static void * producer(void * data) -{ - int n; - for (n = 0; n < 10000; n++) { - printf("%d --->\n", n); - put(&buffer, n); - } - put(&buffer, OVER); - return NULL; -} - -static void * consumer(void * data) -{ - int d; - while (1) { - d = get(&buffer); - if (d == OVER) break; - printf("---> %d\n", d); - } - return NULL; -} - -int main(void) -{ - pthread_t th_a, th_b; - void * retval; - - init(&buffer); - /* Create the threads */ - pthread_create(&th_a, NULL, producer, 0); - pthread_create(&th_b, NULL, consumer, 0); - /* Wait until producer and consumer finish. */ - pthread_join(th_a, &retval); - pthread_join(th_b, &retval); - return 0; -} diff --git a/test/pthread/ex6.c b/test/pthread/ex6.c deleted file mode 100644 index ffb628771..000000000 --- a/test/pthread/ex6.c +++ /dev/null @@ -1,44 +0,0 @@ -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <pthread.h> -#include <time.h> - -static void * -test_thread (void *v_param) -{ - return NULL; -} - -int -main (void) -{ - unsigned long count; - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 10 * 1000; - - setvbuf (stdout, NULL, _IONBF, 0); - - for (count = 0; count < 2000; ++count) - { - pthread_t thread; - int status; - - status = pthread_create (&thread, NULL, test_thread, NULL); - if (status != 0) - { - printf ("status = %d, count = %lu: %s\n", status, count, - strerror (errno)); - return 1; - } - else - { - printf ("count = %lu\n", count); - } - /* pthread_detach (thread); */ - pthread_join (thread, NULL); - nanosleep (&ts, NULL); - } - return 0; -} diff --git a/test/pthread/ex7.c b/test/pthread/ex7.c deleted file mode 100644 index 8eeb9a2e5..000000000 --- a/test/pthread/ex7.c +++ /dev/null @@ -1,106 +0,0 @@ -/* ex7 - * - * Test case that illustrates a timed wait on a condition variable. - */ - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <pthread.h> -#include <sys/time.h> -#include <time.h> - -/* Our event variable using a condition variable contruct. */ -typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - int flag; -} event_t; - - -/* Global event to signal main thread the timeout of the child thread. */ -event_t main_event; - - -static void * -test_thread (void *ms_param) -{ - unsigned long status = 0; - event_t foo; - struct timespec timeout; - struct timeval now; - long ms = (long) ms_param; - - /* initialize cond var */ - pthread_cond_init(&foo.cond, NULL); - pthread_mutex_init(&foo.mutex, NULL); - foo.flag = 0; - - /* set the time out value */ - printf("waiting %ld ms ...\n", ms); - gettimeofday(&now, NULL); - timeout.tv_sec = now.tv_sec + ms/1000 + (now.tv_usec + (ms%1000)*1000)/1000000; - timeout.tv_nsec = ((now.tv_usec + (ms%1000)*1000) % 1000000) * 1000; - - /* Just use this to test the time out. The cond var is never signaled. */ - pthread_mutex_lock(&foo.mutex); - while (foo.flag == 0 && status != ETIMEDOUT) { - status = pthread_cond_timedwait(&foo.cond, &foo.mutex, &timeout); - } - pthread_mutex_unlock(&foo.mutex); - - /* post the main event */ - pthread_mutex_lock(&main_event.mutex); - main_event.flag = 1; - pthread_cond_signal(&main_event.cond); - pthread_mutex_unlock(&main_event.mutex); - - /* that's it, bye */ - return (void*) status; -} - -int -main (void) -{ - unsigned long count; - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 10 * 1000; - - setvbuf (stdout, NULL, _IONBF, 0); - - /* initialize main event cond var */ - pthread_cond_init(&main_event.cond, NULL); - pthread_mutex_init(&main_event.mutex, NULL); - main_event.flag = 0; - - for (count = 0; count < 20; ++count) - { - pthread_t thread; - int status; - - /* pass down the milli-second timeout in the void* param */ - status = pthread_create (&thread, NULL, test_thread, (void*) (count*100)); - if (status != 0) { - printf ("status = %d, count = %lu: %s\n", status, count, - strerror (errno)); - return 1; - } - else { - - /* wait for the event posted by the child thread */ - pthread_mutex_lock(&main_event.mutex); - while (main_event.flag == 0) { - pthread_cond_wait(&main_event.cond, &main_event.mutex); - } - main_event.flag = 0; - pthread_mutex_unlock(&main_event.mutex); - - printf ("count = %lu\n", count); - } - - nanosleep (&ts, NULL); - } - - return 0; -} diff --git a/test/pthread/ex8-mtx-odd.c b/test/pthread/ex8-mtx-odd.c deleted file mode 100644 index 791b2c2ac..000000000 --- a/test/pthread/ex8-mtx-odd.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - - -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - -static int -do_test (void) -{ - - if (pthread_mutex_lock (&lock) != 0) - { - puts ("mutex_lock failed"); - exit (1); - } - - if (pthread_mutex_unlock (&lock) != 0) - { - puts ("1st mutex_unlock failed"); - exit (1); - } - - if (pthread_mutex_unlock (&lock) != 0) - { - puts ("2nd mutex_unlock failed"); - exit (1); - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/test/pthread/tst-c99.c b/test/pthread/tst-c99.c deleted file mode 100644 index 3cc91b1b7..000000000 --- a/test/pthread/tst-c99.c +++ /dev/null @@ -1,2 +0,0 @@ -#include <pthread.h> -int main(void) { return 0; } diff --git a/test/pthread/tst-join2.c b/test/pthread/tst-join2.c deleted file mode 100644 index 6d994f39e..000000000 --- a/test/pthread/tst-join2.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see <http://www.gnu.org/licenses/>. */ - -#include <errno.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - - -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - - -static void * -tf (void *arg) -{ - if (pthread_mutex_lock (&lock) != 0) - { - puts ("child: mutex_lock failed"); - return NULL; - } - - return (void *) 42l; -} - - -static int -do_test (void) -{ - pthread_t th; - - if (pthread_mutex_lock (&lock) != 0) - { - puts ("mutex_lock failed"); - exit (1); - } - - if (pthread_create (&th, NULL, tf, NULL) != 0) - { - puts ("mutex_create failed"); - exit (1); - } - - void *status; - int val = pthread_tryjoin_np (th, &status); - if (val == 0) - { - puts ("1st tryjoin succeeded"); - exit (1); - } - else if (val != EBUSY) - { - puts ("1st tryjoin didn't return EBUSY"); - exit (1); - } - - if (pthread_mutex_unlock (&lock) != 0) - { - puts ("mutex_unlock failed"); - exit (1); - } - - while ((val = pthread_tryjoin_np (th, &status)) != 0) - { - if (val != EBUSY) - { - printf ("tryjoin returned %s (%d), expected only 0 or EBUSY\n", - strerror (val), val); - exit (1); - } - - /* Delay minimally. */ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; - nanosleep (&ts, NULL); - } - - if (status != (void *) 42l) - { - printf ("return value %p, expected %p\n", status, (void *) 42l); - exit (1); - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/test/pthread/tst-join3.c b/test/pthread/tst-join3.c deleted file mode 100644 index 7816f4d22..000000000 --- a/test/pthread/tst-join3.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see <http://www.gnu.org/licenses/>. */ - -#include <errno.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> - - -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - - -static void * -tf (void *arg) -{ - if (pthread_mutex_lock (&lock) != 0) - { - puts ("child: mutex_lock failed"); - return NULL; - } - - return (void *) 42l; -} - - -static int -do_test (void) -{ - pthread_t th; - - if (pthread_mutex_lock (&lock) != 0) - { - puts ("mutex_lock failed"); - exit (1); - } - - if (pthread_create (&th, NULL, tf, NULL) != 0) - { - puts ("mutex_create failed"); - exit (1); - } - - void *status; - struct timespec ts; - struct timeval tv; - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_nsec += 200000000; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } - int val = pthread_timedjoin_np (th, &status, &ts); - if (val == 0) - { - puts ("1st timedjoin succeeded"); - exit (1); - } - else if (val != ETIMEDOUT) - { - puts ("1st timedjoin didn't return ETIMEDOUT"); - exit (1); - } - - if (pthread_mutex_unlock (&lock) != 0) - { - puts ("mutex_unlock failed"); - exit (1); - } - - while (1) - { - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_nsec += 200000000; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } - - val = pthread_timedjoin_np (th, &status, &ts); - if (val == 0) - break; - - if (val != ETIMEDOUT) - { - printf ("timedjoin returned %s (%d), expected only 0 or ETIMEDOUT\n", - strerror (val), val); - exit (1); - } - } - - if (status != (void *) 42l) - { - printf ("return value %p, expected %p\n", status, (void *) 42l); - exit (1); - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/test/pthread/tst-too-many-cleanups.c b/test/pthread/tst-too-many-cleanups.c deleted file mode 100644 index 7828c5036..000000000 --- a/test/pthread/tst-too-many-cleanups.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This illustrates the bug where the cleanup function - * of a thread may be called too many times. - * - * main thread: - * - grab mutex - * - spawn thread1 - * - go to sleep - * thread1: - * - register cleanup handler via pthread_cleanup_push() - * - try to grab mutex and sleep - * main: - * - kill thread1 - * - go to sleep - * thread1 cleanup handler: - * - try to grab mutex and sleep - * main: - * - kill thread1 - * - go to sleep - * thread1 cleanup handler: - * - wrongly called again - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <pthread.h> -#include <assert.h> -#include <unistd.h> - -#define warn(fmt, args...) fprintf(stderr, "[%p] " fmt, (void*)pthread_self(), ## args) -#define warnf(fmt, args...) warn("%s:%i: " fmt, __FUNCTION__, __LINE__, ## args) - -int ok_to_kill_thread; - -static void thread_killed(void *arg); - -static void *KillMeThread(void *thread_par) -{ - pthread_t pthread_id; - - warnf("Starting child thread\n"); - - pthread_id = pthread_self(); - pthread_cleanup_push(thread_killed, (void *)pthread_id); - - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - - /* main code */ - warnf("please kill me now\n"); - while (1) { - ok_to_kill_thread = 1; - sleep(1); - } - - pthread_cleanup_pop(0); - - return 0; -} - -static void thread_killed(void *arg) -{ - static int num_times_called = 0; - - warnf("killing %p [cnt=%i]\n", arg, ++num_times_called); - assert(num_times_called == 1); - - /* pick any cancellation endpoint, sleep() will do just fine */ - while (1) { - warnf("sleeping in cancellation endpoint ...\n"); - sleep(1); - } - - warnf("done cleaning up\n"); -} - -int main(int argc, char *argv[]) -{ - int count = 3; - pthread_t app_pthread_id; - - /* need to tweak this test a bit to play nice with signals and LT */ - return 0; - - ok_to_kill_thread = 0; - - pthread_create(&app_pthread_id, NULL, KillMeThread, NULL); - - warnf("waiting for thread to prepare itself\n"); - while (!ok_to_kill_thread) - sleep(1); - - while (count--) { - warnf("killing thread\n"); - pthread_cancel(app_pthread_id); - sleep(3); - } - - return 0; -} |