From 4fd9bca85e390cbb98fe232a8405df7db6eafb51 Mon Sep 17 00:00:00 2001 From: Thomas Pfaff Date: Tue, 18 Mar 2003 20:04:24 +0000 Subject: * winsup.api/pthread/rwlock1.c: New test. * winsup.api/pthread/rwlock2.c: Ditto. * winsup.api/pthread/rwlock3.c: Ditto. * winsup.api/pthread/rwlock4.c: Ditto. * winsup.api/pthread/rwlock5.c: Ditto. * winsup.api/pthread/rwlock6.c: Ditto. * winsup.api/pthread/rwlock7.c: Ditto. --- winsup/testsuite/ChangeLog | 10 ++ winsup/testsuite/winsup.api/pthread/rwlock1.c | 63 +++++++++ winsup/testsuite/winsup.api/pthread/rwlock2.c | 68 +++++++++ winsup/testsuite/winsup.api/pthread/rwlock3.c | 78 +++++++++++ winsup/testsuite/winsup.api/pthread/rwlock4.c | 78 +++++++++++ winsup/testsuite/winsup.api/pthread/rwlock5.c | 80 +++++++++++ winsup/testsuite/winsup.api/pthread/rwlock6.c | 103 ++++++++++++++ winsup/testsuite/winsup.api/pthread/rwlock7.c | 189 ++++++++++++++++++++++++++ 8 files changed, 669 insertions(+) create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock1.c create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock2.c create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock3.c create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock4.c create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock5.c create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock6.c create mode 100644 winsup/testsuite/winsup.api/pthread/rwlock7.c diff --git a/winsup/testsuite/ChangeLog b/winsup/testsuite/ChangeLog index be94fb2..cdec40f 100644 --- a/winsup/testsuite/ChangeLog +++ b/winsup/testsuite/ChangeLog @@ -1,5 +1,15 @@ 2003-03-18 Thomas Pfaff + * winsup.api/pthread/rwlock1.c: New test. + * winsup.api/pthread/rwlock2.c: Ditto. + * winsup.api/pthread/rwlock3.c: Ditto. + * winsup.api/pthread/rwlock4.c: Ditto. + * winsup.api/pthread/rwlock5.c: Ditto. + * winsup.api/pthread/rwlock6.c: Ditto. + * winsup.api/pthread/rwlock7.c: Ditto. + +2003-03-18 Thomas Pfaff + * winsup.api/pthread/condvar7.c: New test. * winsup.api/pthread/condvar9.c: Ditto. diff --git a/winsup/testsuite/winsup.api/pthread/rwlock1.c b/winsup/testsuite/winsup.api/pthread/rwlock1.c new file mode 100644 index 0000000..cebb485 --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock1.c @@ -0,0 +1,63 @@ +/* + * rwlock1.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create a simple rwlock object and then destroy it. + * + * Depends on API functions: + * pthread_rwlock_init() + * pthread_rwlock_destroy() + */ + +#include "test.h" + +pthread_rwlock_t rwlock = NULL; + +int +main() +{ + assert(rwlock == NULL); + + assert(pthread_rwlock_init(&rwlock, NULL) == 0); + + assert(rwlock != NULL); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/pthread/rwlock2.c b/winsup/testsuite/winsup.api/pthread/rwlock2.c new file mode 100644 index 0000000..67b5286 --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock2.c @@ -0,0 +1,68 @@ +/* + * rwlock2.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; + +int +main() +{ + assert(rwlock == PTHREAD_RWLOCK_INITIALIZER); + + assert(pthread_rwlock_rdlock(&rwlock) == 0); + + assert(rwlock != PTHREAD_RWLOCK_INITIALIZER); + + assert(rwlock != NULL); + + assert(pthread_rwlock_unlock(&rwlock) == 0); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/pthread/rwlock3.c b/winsup/testsuite/winsup.api/pthread/rwlock3.c new file mode 100644 index 0000000..65aa379 --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock3.c @@ -0,0 +1,78 @@ +/* + * rwlock3.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, wrlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_wrlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/pthread/rwlock4.c b/winsup/testsuite/winsup.api/pthread/rwlock4.c new file mode 100644 index 0000000..6605bf6 --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock4.c @@ -0,0 +1,78 @@ +/* + * rwlock4.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, rdlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/pthread/rwlock5.c b/winsup/testsuite/winsup.api/pthread/rwlock5.c new file mode 100644 index 0000000..43e2c6a --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock5.c @@ -0,0 +1,80 @@ +/* + * rwlock5.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, rdlock it, tryrdlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_tryrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_tryrdlock(&rwlock1) == 0); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/pthread/rwlock6.c b/winsup/testsuite/winsup.api/pthread/rwlock6.c new file mode 100644 index 0000000..9a4832e --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock6.c @@ -0,0 +1,103 @@ +/* + * rwlock6.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Check writer and reader locking + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_wrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; + +void * wrfunc(void * arg) +{ + int ba; + + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + Sleep(2000); + bankAccount += 10; + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) ba); +} + +void * rdfunc(void * arg) +{ + int ba; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) ba); +} + +int +main() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt; + int wr1Result = 0; + int wr2Result = 0; + int rdResult = 0; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); + Sleep(500); + assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); + Sleep(500); + assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt, (void **) &rdResult) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + + assert(wr1Result == 10); + assert(rdResult == 20); + assert(wr2Result == 20); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/pthread/rwlock7.c b/winsup/testsuite/winsup.api/pthread/rwlock7.c new file mode 100644 index 0000000..d8af507 --- /dev/null +++ b/winsup/testsuite/winsup.api/pthread/rwlock7.c @@ -0,0 +1,189 @@ +/* + * rwlock7.c + * + * Hammer on a bunch of rwlocks to test robustness and fairness. + * Printed stats should be roughly even for each thread. + */ + +#include "test.h" +#include +#include + +#ifdef __GNUC__ +#include +#endif + +#define THREADS 5 +#define DATASIZE 15 +#define ITERATIONS 1000000 + +#define rand_r( _seed ) \ + ( _seed == _seed? rand() : rand() ) + +/* + * Keep statistics for each thread. + */ +typedef struct thread_tag { + int thread_num; + pthread_t thread_id; + int updates; + int reads; + int interval; +} thread_t; + +/* + * Read-write lock and shared data + */ +typedef struct data_tag { + pthread_rwlock_t lock; + int data; + int updates; +} data_t; + +static thread_t threads[THREADS]; +static data_t data[DATASIZE]; + +/* + * Thread start routine that uses read-write locks + */ +void *thread_routine (void *arg) +{ + thread_t *self = (thread_t*)arg; + int repeats = 0; + int iteration; + int element = 0; + + for (iteration = 0; iteration < ITERATIONS; iteration++) + { + if (iteration % (ITERATIONS / 10) == 0) + { + putchar('.'); + fflush(stdout); + } + /* + * Each "self->interval" iterations, perform an + * update operation (write lock instead of read + * lock). + */ + if ((iteration % self->interval) == 0) + { + assert(pthread_rwlock_wrlock (&data[element].lock) == 0); + data[element].data = self->thread_num; + data[element].updates++; + self->updates++; + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } else { + /* + * Look at the current data element to see whether + * the current thread last updated it. Count the + * times, to report later. + */ + assert(pthread_rwlock_rdlock (&data[element].lock) == 0); + + self->reads++; + + if (data[element].data == self->thread_num) + { + repeats++; + } + + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + + element++; + + if (element >= DATASIZE) + { + element = 0; + } + } + + if (repeats > 0) + { + printf ("\nThread %d found unchanged elements %d times", + self->thread_num, repeats); + fflush(stdout); + } + + return NULL; +} + +int +main (int argc, char *argv[]) +{ + int count; + int data_count; + int thread_updates = 0; + int data_updates = 0; + int seed = 1; + + struct timeb currSysTime1; + struct timeb currSysTime2; + + /* + * Initialize the shared data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data[data_count].data = 0; + data[data_count].updates = 0; + + assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); + } + + _ftime(&currSysTime1); + + /* + * Create THREADS threads to access shared data. + */ + for (count = 0; count < THREADS; count++) + { + threads[count].thread_num = count; + threads[count].updates = 0; + threads[count].reads = 0; + threads[count].interval = rand_r (&seed) % 71; + + assert(pthread_create (&threads[count].thread_id, + NULL, thread_routine, (void*)&threads[count]) == 0); + } + + /* + * Wait for all threads to complete, and collect + * statistics. + */ + for (count = 0; count < THREADS; count++) + { + assert(pthread_join (threads[count].thread_id, NULL) == 0); + thread_updates += threads[count].updates; + printf ("%02d: interval %d, updates %d, reads %d\n", + count, threads[count].interval, + threads[count].updates, threads[count].reads); + } + + putchar('\n'); + fflush(stdout); + + /* + * Collect statistics for the data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data_updates += data[data_count].updates; + printf ("data %02d: value %d, %d updates\n", + data_count, data[data_count].data, data[data_count].updates); + assert(pthread_rwlock_destroy (&data[data_count].lock) == 0); + } + + printf ("%d thread updates, %d data updates\n", + thread_updates, data_updates); + + _ftime(&currSysTime2); + + printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", + currSysTime1.time,currSysTime1.millitm, + currSysTime2.time,currSysTime2.millitm, + (currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)); + + return 0; +} -- cgit v1.1