From aaa4964a2277a1e265da4e7b91d5b1e3c3faa84e Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 17 Jan 2011 18:27:35 +0000 Subject: cvs update pthreads --- pthreads/tests/stress1.c | 556 +++++++++++++++++++++++------------------------ 1 file changed, 278 insertions(+), 278 deletions(-) (limited to 'pthreads/tests/stress1.c') diff --git a/pthreads/tests/stress1.c b/pthreads/tests/stress1.c index efaf44517..ac882503c 100644 --- a/pthreads/tests/stress1.c +++ b/pthreads/tests/stress1.c @@ -1,278 +1,278 @@ -/* - * stress1.c - * - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.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 - * - * -------------------------------------------------------------------------- - * - * Test Synopsis: - * - Stress test condition variables, mutexes, semaphores. - * - * Test Method (Validation or Falsification): - * - Validation - * - * Requirements Tested: - * - Correct accounting of semaphore and condition variable waiters. - * - * Features Tested: - * - - * - * Cases Tested: - * - - * - * Description: - * Attempting to expose race conditions in cond vars, semaphores etc. - * - Master attempts to signal slave close to when timeout is due. - * - Master and slave do battle continuously until main tells them to stop. - * - Afterwards, the CV must be successfully destroyed (will return an - * error if there are waiters (including any internal semaphore waiters, - * which, if there are, cannot not be real waiters). - * - * Environment: - * - - * - * Input: - * - None. - * - * Output: - * - File name, Line number, and failed expression on failure. - * - No output on success. - * - * Assumptions: - * - - * - * Pass Criteria: - * - CV is successfully destroyed. - * - * Fail Criteria: - * - CV destroy fails. - */ - -#include "test.h" -#include -#include - - -const unsigned int ITERATIONS = 1000; - -static pthread_t master, slave; -typedef struct { - int value; - pthread_cond_t cv; - pthread_mutex_t mx; -} mysig_t; - -static int allExit; -static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; -static pthread_barrier_t startBarrier, readyBarrier, holdBarrier; -static int timeoutCount = 0; -static int signalsTakenCount = 0; -static int signalsSent = 0; -static int bias = 0; -static int timeout = 10; // Must be > 0 - -enum { - CTL_STOP = -1 -}; - -/* - * Returns abstime 'milliseconds' from 'now'. - * - * Works for: -INT_MAX <= millisecs <= INT_MAX - */ -struct timespec * -millisecondsFromNow (struct timespec * time, int millisecs) -{ - struct _timeb currSysTime; - int64_t nanosecs, secs; - const int64_t NANOSEC_PER_MILLISEC = 1000000; - const int64_t NANOSEC_PER_SEC = 1000000000; - - /* get current system time and add millisecs */ - _ftime(&currSysTime); - - secs = (int64_t)(currSysTime.time) + (millisecs / 1000); - nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; - if (nanosecs >= NANOSEC_PER_SEC) - { - secs++; - nanosecs -= NANOSEC_PER_SEC; - } - else if (nanosecs < 0) - { - secs--; - nanosecs += NANOSEC_PER_SEC; - } - - time->tv_nsec = (long)nanosecs; - time->tv_sec = (long)secs; - - return time; -} - -void * -masterThread (void * arg) -{ - int dither = (int) arg; - - timeout = (int) arg; - - pthread_barrier_wait(&startBarrier); - - do - { - int sleepTime; - - assert(pthread_mutex_lock(&control.mx) == 0); - control.value = timeout; - assert(pthread_mutex_unlock(&control.mx) == 0); - - /* - * We are attempting to send the signal close to when the slave - * is due to timeout. We feel around by adding some [non-random] dither. - * - * dither is in the range 2*timeout peak-to-peak - * sleep time is the average of timeout plus dither. - * e.g. - * if timeout = 10 then dither = 20 and - * sleep millisecs is: 5 <= ms <= 15 - * - * The bias value attempts to apply some negative feedback to keep - * the ratio of timeouts to signals taken close to 1:1. - * bias changes more slowly than dither so as to average more. - * - * Finally, if abs(bias) exceeds timeout then timeout is incremented. - */ - if (signalsSent % timeout == 0) - { - if (timeoutCount > signalsTakenCount) - { - bias++; - } - else if (timeoutCount < signalsTakenCount) - { - bias--; - } - if (bias < -timeout || bias > timeout) - { - timeout++; - } - } - dither = (dither + 1 ) % (timeout * 2); - sleepTime = (timeout - bias + dither) / 2; - Sleep(sleepTime); - assert(pthread_cond_signal(&control.cv) == 0); - signalsSent++; - - pthread_barrier_wait(&holdBarrier); - pthread_barrier_wait(&readyBarrier); - } - while (!allExit); - - return NULL; -} - -void * -slaveThread (void * arg) -{ - struct timespec time; - - pthread_barrier_wait(&startBarrier); - - do - { - assert(pthread_mutex_lock(&control.mx) == 0); - if (pthread_cond_timedwait(&control.cv, - &control.mx, - millisecondsFromNow(&time, control.value)) == ETIMEDOUT) - { - timeoutCount++; - } - else - { - signalsTakenCount++; - } - assert(pthread_mutex_unlock(&control.mx) == 0); - - pthread_barrier_wait(&holdBarrier); - pthread_barrier_wait(&readyBarrier); - } - while (!allExit); - - return NULL; -} - -int -main () -{ - unsigned int i; - - assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0); - assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0); - assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0); - - assert(pthread_create(&master, NULL, masterThread, (void *) timeout) == 0); - assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0); - - allExit = FALSE; - - pthread_barrier_wait(&startBarrier); - - for (i = 1; !allExit; i++) - { - pthread_barrier_wait(&holdBarrier); - if (i >= ITERATIONS) - { - allExit = TRUE; - } - pthread_barrier_wait(&readyBarrier); - } - - assert(pthread_join(slave, NULL) == 0); - assert(pthread_join(master, NULL) == 0); - - printf("Signals sent = %d\nWait timeouts = %d\nSignals taken = %d\nBias = %d\nTimeout = %d\n", - signalsSent, - timeoutCount, - signalsTakenCount, - (int) bias, - timeout); - - /* Cleanup */ - assert(pthread_barrier_destroy(&holdBarrier) == 0); - assert(pthread_barrier_destroy(&readyBarrier) == 0); - assert(pthread_barrier_destroy(&startBarrier) == 0); - assert(pthread_cond_destroy(&control.cv) == 0); - assert(pthread_mutex_destroy(&control.mx) == 0); - - /* Success. */ - return 0; -} +/* + * stress1.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Stress test condition variables, mutexes, semaphores. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - Correct accounting of semaphore and condition variable waiters. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * Attempting to expose race conditions in cond vars, semaphores etc. + * - Master attempts to signal slave close to when timeout is due. + * - Master and slave do battle continuously until main tells them to stop. + * - Afterwards, the CV must be successfully destroyed (will return an + * error if there are waiters (including any internal semaphore waiters, + * which, if there are, cannot be real waiters). + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - CV is successfully destroyed. + * + * Fail Criteria: + * - CV destroy fails. + */ + +#include "test.h" +#include +#include + + +const unsigned int ITERATIONS = 1000; + +static pthread_t master, slave; +typedef struct { + int value; + pthread_cond_t cv; + pthread_mutex_t mx; +} mysig_t; + +static int allExit; +static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; +static pthread_barrier_t startBarrier, readyBarrier, holdBarrier; +static int timeoutCount = 0; +static int signalsTakenCount = 0; +static int signalsSent = 0; +static int bias = 0; +static int timeout = 10; // Must be > 0 + +enum { + CTL_STOP = -1 +}; + +/* + * Returns abstime 'milliseconds' from 'now'. + * + * Works for: -INT_MAX <= millisecs <= INT_MAX + */ +struct timespec * +millisecondsFromNow (struct timespec * time, int millisecs) +{ + struct _timeb currSysTime; + int64_t nanosecs, secs; + const int64_t NANOSEC_PER_MILLISEC = 1000000; + const int64_t NANOSEC_PER_SEC = 1000000000; + + /* get current system time and add millisecs */ + _ftime(&currSysTime); + + secs = (int64_t)(currSysTime.time) + (millisecs / 1000); + nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; + if (nanosecs >= NANOSEC_PER_SEC) + { + secs++; + nanosecs -= NANOSEC_PER_SEC; + } + else if (nanosecs < 0) + { + secs--; + nanosecs += NANOSEC_PER_SEC; + } + + time->tv_nsec = (long)nanosecs; + time->tv_sec = (long)secs; + + return time; +} + +void * +masterThread (void * arg) +{ + int dither = (int) arg; + + timeout = (int) arg; + + pthread_barrier_wait(&startBarrier); + + do + { + int sleepTime; + + assert(pthread_mutex_lock(&control.mx) == 0); + control.value = timeout; + assert(pthread_mutex_unlock(&control.mx) == 0); + + /* + * We are attempting to send the signal close to when the slave + * is due to timeout. We feel around by adding some [non-random] dither. + * + * dither is in the range 2*timeout peak-to-peak + * sleep time is the average of timeout plus dither. + * e.g. + * if timeout = 10 then dither = 20 and + * sleep millisecs is: 5 <= ms <= 15 + * + * The bias value attempts to apply some negative feedback to keep + * the ratio of timeouts to signals taken close to 1:1. + * bias changes more slowly than dither so as to average more. + * + * Finally, if abs(bias) exceeds timeout then timeout is incremented. + */ + if (signalsSent % timeout == 0) + { + if (timeoutCount > signalsTakenCount) + { + bias++; + } + else if (timeoutCount < signalsTakenCount) + { + bias--; + } + if (bias < -timeout || bias > timeout) + { + timeout++; + } + } + dither = (dither + 1 ) % (timeout * 2); + sleepTime = (timeout - bias + dither) / 2; + Sleep(sleepTime); + assert(pthread_cond_signal(&control.cv) == 0); + signalsSent++; + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +void * +slaveThread (void * arg) +{ + struct timespec time; + + pthread_barrier_wait(&startBarrier); + + do + { + assert(pthread_mutex_lock(&control.mx) == 0); + if (pthread_cond_timedwait(&control.cv, + &control.mx, + millisecondsFromNow(&time, control.value)) == ETIMEDOUT) + { + timeoutCount++; + } + else + { + signalsTakenCount++; + } + assert(pthread_mutex_unlock(&control.mx) == 0); + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +int +main () +{ + unsigned int i; + + assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0); + + assert(pthread_create(&master, NULL, masterThread, (void *) timeout) == 0); + assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0); + + allExit = FALSE; + + pthread_barrier_wait(&startBarrier); + + for (i = 1; !allExit; i++) + { + pthread_barrier_wait(&holdBarrier); + if (i >= ITERATIONS) + { + allExit = TRUE; + } + pthread_barrier_wait(&readyBarrier); + } + + assert(pthread_join(slave, NULL) == 0); + assert(pthread_join(master, NULL) == 0); + + printf("Signals sent = %d\nWait timeouts = %d\nSignals taken = %d\nBias = %d\nTimeout = %d\n", + signalsSent, + timeoutCount, + signalsTakenCount, + (int) bias, + timeout); + + /* Cleanup */ + assert(pthread_barrier_destroy(&holdBarrier) == 0); + assert(pthread_barrier_destroy(&readyBarrier) == 0); + assert(pthread_barrier_destroy(&startBarrier) == 0); + assert(pthread_cond_destroy(&control.cv) == 0); + assert(pthread_mutex_destroy(&control.mx) == 0); + + /* Success. */ + return 0; +} -- cgit v1.2.3