int main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; assert((t[0] = pthread_self()).p != NULL); assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); assert(pthread_mutex_lock(&cvthing.lock) == 0); assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); /* get current system time */ PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; while (! (cvthing.shared > 0)) assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); assert(cvthing.shared > 0); assert(pthread_mutex_unlock(&cvthing.lock) == 0); assert(pthread_join(t[1], NULL) == 0); assert(pthread_mutex_destroy(&cvthing.lock) == 0); assert(cvthing.lock == NULL); assert(pthread_cond_destroy(&cvthing.notbusy) == 0); assert(cvthing.notbusy == NULL); return 0; }
int main() { pthread_t t; struct timespec abstime = { 0, 0 }; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); assert(pthread_create(&t, NULL, func, NULL) == 0); Sleep(2000); assert(pthread_rwlock_unlock(&rwlock1) == 0); assert(washere == 1); return 0; }
/* * Returns abstime 'milliseconds' from 'now'. * * Works for: -INT_MAX <= millisecs <= INT_MAX */ struct timespec * millisecondsFromNow (struct timespec * time, int millisecs) { #if (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 struct __timeb64 currSysTime; #else struct _timeb currSysTime; #endif 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 */ PTW32_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; }
static void * rdfunc(void * arg) { int ba = -1; struct timespec abstime = { 0, 0 }; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; if ((int) (size_t)arg == 1) { abstime.tv_sec += 1; assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); ba = 0; } else if ((int) (size_t)arg == 2) { abstime.tv_sec += 3; assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); ba = bankAccount; assert(pthread_rwlock_unlock(&rwlock1) == 0); } return ((void *)(size_t)ba); }
/* * Returns abstime 'milliseconds' from 'now'. * * Works for: -INT_MAX <= millisecs <= INT_MAX */ struct timespec * millisecondsFromNow (struct timespec * time, int millisecs) { PTW32_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 */ PTW32_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; }
int _tmain(int argc, _TCHAR* argv[]) //int //main() { int i; pthread_t t[NUMTHREADS + 1]; void* result = (void*)0; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); assert(pthread_mutex_init(&mutex, NULL) == 0); /* get current system time */ PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; assert(pthread_mutex_lock(&mutex) == 0); for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0); } assert(pthread_mutex_unlock(&mutex) == 0); for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_join(t[i], &result) == 0); assert((int)(size_t)result == i); } { int result = pthread_cond_destroy(&cv); if (result != 0) { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); } assert(result == 0); } return 0; }
int main() { int rc; struct timespec abstime = { 0, 0 }; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cnd, 0) == 0); assert(pthread_mutex_init(&mtx, 0) == 0); /* get current system time */ PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; /* Here pthread_cond_timedwait should time out after one second. */ assert(pthread_mutex_lock(&mtx) == 0); assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); assert(pthread_mutex_unlock(&mtx) == 0); /* Here, the condition variable is signaled, but there are no threads waiting on it. The signal should be lost and the next pthread_cond_timedwait should time out too. */ // assert(pthread_mutex_lock(&mtx) == 0); assert((rc = pthread_cond_signal(&cnd)) == 0); // assert(pthread_mutex_unlock(&mtx) == 0); assert(pthread_mutex_lock(&mtx) == 0); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); assert(pthread_mutex_unlock(&mtx) == 0); return 0; }
void * locker(void * arg) { struct timespec abstime = { 0, 0 }; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); lockCount++; return 0; }
int test_condvar2(void) #endif { struct timespec abstime = { 0, 0 }; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); assert(pthread_mutex_init(&mutex, NULL) == 0); assert(pthread_mutex_lock(&mutex) == 0); /* get current system time */ PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); assert(pthread_mutex_unlock(&mutex) == 0); { int result = pthread_cond_destroy(&cv); if (result != 0) { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); } assert(result == 0); } return 0; }
int main() { pthread_t wrt1; pthread_t wrt2; pthread_t rdt; void* wr1Result = (void*)0; void* wr2Result = (void*)0; void* rdResult = (void*)0; #if (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 struct __timeb64 currSysTime; #else struct _timeb currSysTime; #endif const DWORD NANOSEC_PER_MILLISEC = 1000000; PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; bankAccount = 0; assert(pthread_create(&wrt1, NULL, wrfunc, (void *)(size_t)1) == 0); Sleep(100); assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); Sleep(100); assert(pthread_create(&wrt2, NULL, wrfunc, (void *)(size_t)2) == 0); assert(pthread_join(wrt1, &wr1Result) == 0); assert(pthread_join(rdt, &rdResult) == 0); assert(pthread_join(wrt2, &wr2Result) == 0); assert((int)(size_t)wr1Result == 10); assert((int)(size_t)rdResult == 0); assert((int)(size_t)wr2Result == 100); return 0; }
int main(int argc, char * argv[]) { pthread_t id; struct timespec abstime; void* result = (void*)-1; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_create(&id, NULL, func, (void *)(size_t)999) == 0); /* * Let thread start before we attempt to join it. */ Sleep(100); PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; /* Test for pthread_timedjoin_np timeout */ abstime.tv_sec += 1; assert(pthread_timedjoin_np(id, &result, &abstime) == ETIMEDOUT); assert((int)(size_t)result == -1); /* Test for pthread_tryjoin_np behaviour before thread has exited */ assert(pthread_tryjoin_np(id, &result) == EBUSY); assert((int)(size_t)result == -1); Sleep(500); /* Test for pthread_tryjoin_np behaviour after thread has exited */ assert(pthread_tryjoin_np(id, &result) == 0); assert((int)(size_t)result == 999); /* Success. */ return 0; }
int test_rwlock6_t2(void) #endif { pthread_t wrt1; pthread_t wrt2; pthread_t rdt; void* wr1Result = (void*)0; void* wr2Result = (void*)0; void* rdResult = (void*)0; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; bankAccount = 0; assert(pthread_create(&wrt1, NULL, wrfunc, (void *)(size_t)1) == 0); Sleep(100); assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); Sleep(100); assert(pthread_create(&wrt2, NULL, wrfunc, (void *)(size_t)2) == 0); assert(pthread_join(wrt1, &wr1Result) == 0); assert(pthread_join(rdt, &rdResult) == 0); assert(pthread_join(wrt2, &wr2Result) == 0); assert((int)(size_t)wr1Result == 10); assert((int)(size_t)rdResult == 0); assert((int)(size_t)wr2Result == 100); return 0; }
int main() { int failed = 0; int i; int first, last; pthread_t t[NUMTHREADS + 1]; #if (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 struct __timeb64 currSysTime; #else struct _timeb currSysTime; #endif const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()).p != NULL); assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 10; assert((t[0] = pthread_self()).p != NULL); awoken = 0; for (first = 1, last = NUMTHREADS / 2; first < NUMTHREADS; first = last + 1, last = NUMTHREADS) { assert(pthread_mutex_lock(&start_flag) == 0); for (i = first; i <= last; i++) { threadbag[i].started = 0; threadbag[i].threadnum = i; assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); } /* * Code to control or munipulate child threads should probably go here. */ cvthing.shared = 0; assert(pthread_mutex_unlock(&start_flag) == 0); /* * Give threads time to start. */ Sleep(100); assert(pthread_mutex_lock(&cvthing.lock) == 0); cvthing.shared++; assert(pthread_mutex_unlock(&cvthing.lock) == 0); assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); /* * Give threads time to complete. */ for (i = first; i <= last; i++) { assert(pthread_join(t[i], NULL) == 0); } assert(awoken == (i - 1)); } /* * Standard check that all threads started. */ for (i = 1; i <= NUMTHREADS; i++) { failed = !threadbag[i].started; if (failed) { fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); } } /* * Cleanup the CV. */ assert(pthread_mutex_destroy(&cvthing.lock) == 0); assert(cvthing.lock == NULL); assert(pthread_cond_destroy(&cvthing.notbusy) == 0); assert(cvthing.notbusy == NULL); assert(!failed); /* * Check any results here. */ assert(awoken == NUMTHREADS); /* * Success. */ return 0; }
int main() { int i; pthread_t t[NUMTHREADS + 1]; void* result = (void*)0; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); assert(pthread_cond_init(&cv1, NULL) == 0); assert(pthread_mutex_init(&mutex, NULL) == 0); assert(pthread_mutex_init(&mutex1, NULL) == 0); /* get current system time */ PTW32_FTIME(&currSysTime); abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; assert(pthread_mutex_lock(&mutex1) == 0); for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0); } do { assert(pthread_cond_wait(&cv1,&mutex1) == 0); } while ( NUMTHREADS > waiting ); assert(pthread_mutex_unlock(&mutex1) == 0); for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++) { // assert(pthread_mutex_lock(&mutex) == 0); assert(pthread_cond_signal(&cv) == 0); // assert(pthread_mutex_unlock(&mutex) == 0); signaled++; } for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_join(t[i], &result) == 0); assert((int)(size_t)result == i); } fprintf(stderr, "awk = %d\n", awoken); fprintf(stderr, "sig = %d\n", signaled); fprintf(stderr, "tot = %d\n", timedout); assert(signaled == awoken); assert(timedout == NUMTHREADS - signaled); assert(pthread_cond_destroy(&cv1) == 0); { int result = pthread_cond_destroy(&cv); if (result != 0) { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); } assert(result == 0); } assert(pthread_mutex_destroy(&mutex1) == 0); assert(pthread_mutex_destroy(&mutex) == 0); return 0; }
int main() { int failed = 0; int i; pthread_t t[NUMTHREADS + 1]; PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; assert((t[0] = pthread_self()).p != NULL); assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); assert(pthread_mutex_lock(&start_flag) == 0); PTW32_FTIME(&currSysTime); abstime.tv_sec = (time_t)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 10; assert((t[0] = pthread_self()).p != NULL); awoken = 0; for (i = 1; i <= NUMTHREADS; i++) { threadbag[i].started = 0; threadbag[i].threadnum = i; assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); } /* * Code to control or munipulate child threads should probably go here. */ assert(pthread_mutex_unlock(&start_flag) == 0); /* * Give threads time to start. */ Sleep(1000); /* * Cancel one of the threads. */ assert(pthread_cancel(t[1]) == 0); assert(pthread_join(t[1], NULL) == 0); assert(pthread_mutex_lock(&cvthing.lock) == 0); cvthing.shared++; assert(pthread_mutex_unlock(&cvthing.lock) == 0); /* * Signal all remaining waiting threads. */ assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); /* * Wait for all threads to complete. */ for (i = 2; i <= NUMTHREADS; i++) assert(pthread_join(t[i], NULL) == 0); /* * Cleanup the CV. */ assert(pthread_mutex_destroy(&cvthing.lock) == 0); assert(cvthing.lock == NULL); assert(pthread_cond_destroy(&cvthing.notbusy) == 0); assert(cvthing.notbusy == NULL); /* * Standard check that all threads started. */ for (i = 1; i <= NUMTHREADS; i++) { failed = !threadbag[i].started; if (failed) { fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); } } assert(!failed); /* * Check any results here. */ assert(awoken == (NUMTHREADS - 1)); /* * Success. */ return 0; }
int main (int argc, char *argv[]) { int count; int data_count; int thread_updates = 0; int data_updates = 0; int seed = 1; #if (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 struct __timeb64 currSysTime1; struct __timeb64 currSysTime2; #else struct _timeb currSysTime1; struct _timeb currSysTime2; #endif /* * 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); } PTW32_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].seed = 1 + rand_r (&seed) % 71; assert(pthread_create (&threads[count].thread_id, NULL, thread_routine, (void*)(size_t)&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); } putchar('\n'); fflush(stdout); for (count = 0; count < THREADS; count++) { if (threads[count].changed > 0) { printf ("Thread %d found changed elements %d times\n", count, threads[count].changed); } } putchar('\n'); fflush(stdout); for (count = 0; count < THREADS; count++) { thread_updates += threads[count].updates; printf ("%02d: seed %d, updates %d, reads %d\n", count, threads[count].seed, 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); PTW32_FTIME(&currSysTime2); printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", (long)currSysTime1.time,currSysTime1.millitm, (long)currSysTime2.time,currSysTime2.millitm, ((long)((currSysTime2.time*1000+currSysTime2.millitm) - (currSysTime1.time*1000+currSysTime1.millitm)))); return 0; }
int main() { int i; pthread_t t[NUMTHREADS + 1]; void* result = (void*)0; #if (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 struct __timeb64 currSysTime; #else struct _timeb currSysTime; #endif const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); assert(pthread_mutex_init(&mutex, NULL) == 0); /* get current system time */ PTW32_FTIME(&currSysTime); abstime.tv_sec = abstime2.tv_sec = (long)currSysTime.time + 5; abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; assert(pthread_mutex_lock(&mutex) == 0); for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0); } assert(pthread_mutex_unlock(&mutex) == 0); for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_join(t[i], &result) == 0); assert((int)(size_t)result == i); /* * Approximately 2/3rds of the threads are expected to time out. * Signal the remainder after some threads have woken up and exited * and while some are still waking up after timeout. * Also tests that redundant broadcasts don't return errors. */ // assert(pthread_mutex_lock(&mutex) == 0); if (InterlockedExchangeAdd((LPLONG)&awoken, 0L) > NUMTHREADS/3) { assert(pthread_cond_broadcast(&cv) == 0); } // assert(pthread_mutex_unlock(&mutex) == 0); } assert(awoken == NUMTHREADS - timedout); { int result = pthread_cond_destroy(&cv); if (result != 0) { fprintf(stderr, "Result = %s\n", error_string[result]); fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); fflush(stderr); } assert(result == 0); } assert(pthread_mutex_destroy(&mutex) == 0); return 0; }