diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 20:10:10 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 20:10:10 +0000 |
| commit | a334319f6530564d22e775935d9c91663623a1b4 (patch) | |
| tree | b5877475619e4c938e98757d518bb1e9cbead751 /linuxthreads/Examples | |
| parent | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff) | |
| download | glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.xz glibc-a334319f6530564d22e775935d9c91663623a1b4.zip | |
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'linuxthreads/Examples')
| -rw-r--r-- | linuxthreads/Examples/Makefile | 15 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex1.c | 42 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex10.c | 108 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex11.c | 154 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex12.c | 47 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex13.c | 112 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex14.c | 133 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex15.c | 58 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex16.c | 26 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex17.c | 112 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex18.c | 113 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex2.c | 124 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex3.c | 152 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex4.c | 115 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex5.c | 114 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex6.c | 46 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex7.c | 45 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex8.c | 101 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex9.c | 98 | ||||
| -rw-r--r-- | linuxthreads/Examples/tststatic.c | 1 |
20 files changed, 1716 insertions, 0 deletions
diff --git a/linuxthreads/Examples/Makefile b/linuxthreads/Examples/Makefile new file mode 100644 index 0000000000..c68b3676a4 --- /dev/null +++ b/linuxthreads/Examples/Makefile @@ -0,0 +1,15 @@ +CC=gcc +CFLAGS=-g -O -Wall -I.. -D_REENTRANT +LIBPTHREAD=../libpthread.a + +PROGS=ex1 ex2 ex3 ex4 ex5 proxy + +all: $(PROGS) + +.c: + $(CC) $(CFLAGS) -o $* $*.c $(LIBPTHREAD) + +$(PROGS): + +clean: + rm -f $(PROGS) diff --git a/linuxthreads/Examples/ex1.c b/linuxthreads/Examples/ex1.c new file mode 100644 index 0000000000..29138cf761 --- /dev/null +++ b/linuxthreads/Examples/ex1.c @@ -0,0 +1,42 @@ +/* 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; + fprintf (stderr, "Starting process %s\n", (char *) arg); + for (i = 0; i < 10000; i++) + { + write (1, (char *) arg, 1); + } + return NULL; +} + +int +main (void) +{ + int retcode; + pthread_t th_a, th_b; + void *retval; + + retcode = pthread_create (&th_a, NULL, process, (void *) "a"); + if (retcode != 0) + fprintf (stderr, "create a failed %d\n", retcode); + retcode = pthread_create (&th_b, NULL, process, (void *) "b"); + if (retcode != 0) + fprintf (stderr, "create b failed %d\n", retcode); + retcode = pthread_join (th_a, &retval); + if (retcode != 0) + fprintf (stderr, "join a failed %d\n", retcode); + retcode = pthread_join (th_b, &retval); + if (retcode != 0) + fprintf (stderr, "join b failed %d\n", retcode); + return 0; +} diff --git a/linuxthreads/Examples/ex10.c b/linuxthreads/Examples/ex10.c new file mode 100644 index 0000000000..f3ad517283 --- /dev/null +++ b/linuxthreads/Examples/ex10.c @@ -0,0 +1,108 @@ +/* Tests for pthread_mutex_timedlock function. + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>, 2000. + + 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <error.h> +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <time.h> + +#define NUM_THREADS 10 +#define NUM_ITERS 50 +#define TIMEOUT_NS 100000000L + +static void *thread (void *) __attribute__ ((__noreturn__)); +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +int +main (void) +{ + pthread_t th; + int i; + + for (i = 0; i < NUM_THREADS; i++) + { + if (pthread_create (&th, NULL, thread, NULL) != 0) + error (EXIT_FAILURE, 0, "cannot create thread"); + } + + (void) thread (NULL); + /* notreached */ + return 0; +} + + +static void * +thread (void *arg) +{ + int i; + pthread_t self = pthread_self (); + static int linecount; /* protected by flockfile(stdout) */ + + for (i = 0; i < NUM_ITERS; i++) + { + struct timespec ts; + + for (;;) + { + int err; + + clock_gettime (CLOCK_REALTIME, &ts); + + ts.tv_nsec += TIMEOUT_NS; + + if (ts.tv_nsec >= 1000000000L) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } + + switch ((err = pthread_mutex_timedlock (&mutex, &ts))) + { + case 0: + flockfile (stdout); + printf ("%04d: thread %lu got mutex\n", ++linecount, + (unsigned long) self); + funlockfile (stdout); + break; + case ETIMEDOUT: + flockfile (stdout); + printf ("%04d: thread %lu timed out on mutex\n", ++linecount, + (unsigned long) self); + funlockfile (stdout); + continue; + default: + error (EXIT_FAILURE, err, "pthread_mutex_timedlock failure"); + } + break; + } + + ts.tv_sec = 0; + ts.tv_nsec = TIMEOUT_NS; + nanosleep (&ts, NULL); + + flockfile (stdout); + printf ("%04d: thread %lu releasing mutex\n", ++linecount, + (unsigned long) self); + funlockfile (stdout); + pthread_mutex_unlock (&mutex); + } + + pthread_exit (NULL); +} diff --git a/linuxthreads/Examples/ex11.c b/linuxthreads/Examples/ex11.c new file mode 100644 index 0000000000..abb5b5385a --- /dev/null +++ b/linuxthreads/Examples/ex11.c @@ -0,0 +1,154 @@ +/* Test program for timedout read/write lock functions. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. + + 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <error.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + + +#define NWRITERS 15 +#define WRITETRIES 10 +#define NREADERS 15 +#define READTRIES 15 + +#define TIMEOUT 1000000 +#define DELAY 1000000 + +static pthread_rwlock_t lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP; + + +static void * +writer_thread (void *nr) +{ + struct timespec ts; + struct timespec delay; + int n; + + ts.tv_sec = 0; + ts.tv_nsec = TIMEOUT; + + delay.tv_sec = 0; + delay.tv_nsec = DELAY; + + for (n = 0; n < WRITETRIES; ++n) + { + do + { + clock_gettime (CLOCK_REALTIME, &ts); + + ts.tv_nsec += 2 * TIMEOUT; + + printf ("writer thread %ld tries again\n", (long int) nr); + } + //while (pthread_rwlock_wrlock (&lock), 0); + while (pthread_rwlock_timedwrlock (&lock, &ts) == ETIMEDOUT); + + printf ("writer thread %ld succeeded\n", (long int) nr); + + nanosleep (&delay, NULL); + + pthread_rwlock_unlock (&lock); + + printf ("writer thread %ld released\n", (long int) nr); + } + + return NULL; +} + + +static void * +reader_thread (void *nr) +{ + struct timespec ts; + struct timespec delay; + int n; + + delay.tv_sec = 0; + delay.tv_nsec = DELAY; + + for (n = 0; n < READTRIES; ++n) + { + do + { + clock_gettime (CLOCK_REALTIME, &ts); + + ts.tv_nsec += TIMEOUT; + + printf ("reader thread %ld tries again\n", (long int) nr); + } + //while (pthread_rwlock_rdlock (&lock), 0); + while (pthread_rwlock_timedrdlock (&lock, &ts) == ETIMEDOUT); + + printf ("reader thread %ld succeeded\n", (long int) nr); + + nanosleep (&delay, NULL); + + pthread_rwlock_unlock (&lock); + + printf ("reader thread %ld released\n", (long int) nr); + } + + return NULL; +} + + +int +main (void) +{ + pthread_t thwr[NWRITERS]; + pthread_t thrd[NREADERS]; + int n; + void *res; + + /* Make standard error the same as standard output. */ + dup2 (1, 2); + + /* Make sure we see all message, even those on stdout. */ + setvbuf (stdout, NULL, _IONBF, 0); + + for (n = 0; n < NWRITERS; ++n) + { + int err = pthread_create (&thwr[n], NULL, writer_thread, + (void *) (long int) n); + + if (err != 0) + error (EXIT_FAILURE, err, "cannot create writer thread"); + } + + for (n = 0; n < NREADERS; ++n) + { + int err = pthread_create (&thrd[n], NULL, reader_thread, + (void *) (long int) n); + + if (err != 0) + error (EXIT_FAILURE, err, "cannot create reader thread"); + } + + /* Wait for all the threads. */ + for (n = 0; n < NWRITERS; ++n) + pthread_join (thwr[n], &res); + for (n = 0; n < NREADERS; ++n) + pthread_join (thrd[n], &res); + + return 0; +} diff --git a/linuxthreads/Examples/ex12.c b/linuxthreads/Examples/ex12.c new file mode 100644 index 0000000000..e986fec97f --- /dev/null +++ b/linuxthreads/Examples/ex12.c @@ -0,0 +1,47 @@ +/* Variant of ex6, but this time we use pthread_exit (). */ +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> +#include <unistd.h> + +static void * +__attribute__ ((noreturn)) +test_thread (void *v_param) +{ + pthread_exit (NULL); +} + +int +main (void) +{ + unsigned long count; + + 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); */ + if (pthread_join (thread, NULL) != 0) + { + printf ("join failed, count %lu\n", count); + return 2; + } + usleep (10); + } + return 0; +} diff --git a/linuxthreads/Examples/ex13.c b/linuxthreads/Examples/ex13.c new file mode 100644 index 0000000000..14add6c773 --- /dev/null +++ b/linuxthreads/Examples/ex13.c @@ -0,0 +1,112 @@ +/* Test for Pthreads/mutexes. + Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kurt Garloff <garloff@suse.de>, 2000. + + 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, + 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 <unistd.h> + +static void *thread_start (void *ptr) __attribute__ ((__noreturn__)); + + +struct thr_ctrl +{ + pthread_mutex_t mutex; + pthread_cond_t cond; + int retval; +}; + +static void +dump_mut (pthread_mutex_t * mut) +{ + size_t i; + for (i = 0; i < sizeof (*mut); i++) + printf (" %02x", *((unsigned char *) mut + i)); + printf ("\n"); +}; + +/* Helper, the opposite of pthread_cond_wait (cond, mut). */ +static void +pthr_cond_signal_mutex (pthread_cond_t * cond, pthread_mutex_t * mut) +{ + int err; + err = pthread_mutex_lock (mut); + if (err) + printf ("mutex_lock : %s\n", strerror (err)); + err = pthread_cond_signal (cond); + if (err) + printf ("cond_signal : %s\n", strerror (err)); + err = pthread_mutex_unlock (mut); + if (err) + printf ("mutex_unlock: %s\n", strerror (err)); +} + +static void * +thread_start (void *ptr) +{ + struct thr_ctrl *tc = ptr; + /* Do initialization. */ + /* ... */ + /* Signal that we are ready. */ + pthr_cond_signal_mutex (&tc->cond, &tc->mutex); + sleep (2); + pthr_cond_signal_mutex (&tc->cond, &tc->mutex); + tc->retval = 0; + pthread_exit (&tc->retval); +} + +int +main (void) +{ + struct thr_ctrl threadctrl; + pthread_t thread; + int err; + void *res = &threadctrl.retval; + pthread_mutexattr_t mutattr; + pthread_mutexattr_init (&mutattr); + pthread_mutex_init (&threadctrl.mutex, &mutattr); + pthread_cond_init (&threadctrl.cond, NULL); + err = pthread_mutex_lock (&threadctrl.mutex); + if (err) + printf ("mutex_lock : %s\n", strerror (err)); + dump_mut (&threadctrl.mutex); + pthread_create (&thread, NULL, thread_start, &threadctrl); + /* Wait until it's ready. */ + err = pthread_cond_wait (&threadctrl.cond, &threadctrl.mutex); + if (err) + printf ("cond_wait : %s\n", strerror (err)); + /* Now, we should have acquired the mutex again! */ + dump_mut (&threadctrl.mutex); + sleep (1); + dump_mut (&threadctrl.mutex); + err = pthread_cond_wait (&threadctrl.cond, &threadctrl.mutex); + if (err) + { + printf ("cond_wait : %s\n", strerror (err)); + printf ("ERROR\n"); + abort (); + }; + dump_mut (&threadctrl.mutex); + pthread_join (thread, &res); + printf ("OK\n"); + return 0; +} diff --git a/linuxthreads/Examples/ex14.c b/linuxthreads/Examples/ex14.c new file mode 100644 index 0000000000..406e03f346 --- /dev/null +++ b/linuxthreads/Examples/ex14.c @@ -0,0 +1,133 @@ +/* Test of POSIX barriers. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NTHREADS 20 + +#define ROUNDS 20 + +static pthread_barrier_t barriers[NTHREADS]; + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static int counters[NTHREADS]; +static int serial[NTHREADS]; + +static void * +worker (void *arg) +{ + void *result = NULL; + int nr = (long int) arg; + int i; + + for (i = 0; i < ROUNDS; ++i) + { + int j; + int retval; + + if (nr == 0) + { + memset (counters, '\0', sizeof (counters)); + memset (serial, '\0', sizeof (serial)); + } + + retval = pthread_barrier_wait (&barriers[NTHREADS - 1]); + if (retval != 0 && retval != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("thread %d failed to wait for all the others\n", nr); + result = (void *) 1; + } + + for (j = nr; j < NTHREADS; ++j) + { + /* Increment the counter for this round. */ + pthread_mutex_lock (&lock); + ++counters[j]; + pthread_mutex_unlock (&lock); + + /* Wait for the rest. */ + retval = pthread_barrier_wait (&barriers[j]); + + /* Test the result. */ + if (nr == 0 && counters[j] != j + 1) + { + printf ("barrier in round %d released but count is %d\n", + j, counters[j]); + result = (void *) 1; + } + + if (retval != 0) + { + if (retval != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("thread %d in round %d has nonzero return value != PTHREAD_BARRIER_SERIAL_THREAD\n", + nr, j); + result = (void *) 1; + } + else + { + pthread_mutex_lock (&lock); + ++serial[j]; + pthread_mutex_unlock (&lock); + } + } + + /* Wait for the rest again. */ + retval = pthread_barrier_wait (&barriers[j]); + + /* Now we can check whether exactly one thread was serializing. */ + if (nr == 0 && serial[j] != 1) + { + printf ("not exactly one serial thread in round %d\n", j); + result = (void *) 1; + } + } + } + + return result; +} + + +#define TEST_FUNCTION do_test () +#define TIMEOUT 60 +static int +do_test (void) +{ + pthread_t threads[NTHREADS]; + int i; + void *res; + int result = 0; + + /* Initialized the barrier variables. */ + for (i = 0; i < NTHREADS; ++i) + if (pthread_barrier_init (&barriers[i], NULL, i + 1) != 0) + { + printf ("Failed to initialize barrier %d\n", i); + exit (1); + } + + /* Start the threads. */ + for (i = 0; i < NTHREADS; ++i) + if (pthread_create (&threads[i], NULL, worker, (void *) (long int) i) != 0) + { + printf ("Failed to start thread %d\n", i); + exit (1); + |
