| #include <stdio.h> | |
| #include <assert.h> | |
| #include <sys/time.h> | |
| #ifdef PTEST_USE_THREAD | |
| # include <pthread.h> | |
| static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; | |
| static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER; | |
| static int remaining; | |
| #endif | |
| extern int add1(int, int); | |
| static double time_delta(struct timeval *stop, struct timeval *start) | |
| { | |
| return (stop->tv_sec - start->tv_sec) + | |
| 1e-6 * (stop->tv_usec - start->tv_usec); | |
| } | |
| static double measure(void) | |
| { | |
| long long i, iterations; | |
| int result; | |
| struct timeval start, stop; | |
| double elapsed; | |
| add1(0, 0); /* prepare off-line */ | |
| i = 0; | |
| iterations = 1000; | |
| result = gettimeofday(&start, NULL); | |
| assert(result == 0); | |
| while (1) { | |
| for (; i < iterations; i++) { | |
| add1(((int)i) & 0xaaaaaa, ((int)i) & 0x555555); | |
| } | |
| result = gettimeofday(&stop, NULL); | |
| assert(result == 0); | |
| elapsed = time_delta(&stop, &start); | |
| assert(elapsed >= 0.0); | |
| if (elapsed > 2.5) | |
| break; | |
| iterations = iterations * 3 / 2; | |
| } | |
| return elapsed / (double)iterations; | |
| } | |
| static void *start_routine(void *arg) | |
| { | |
| double t = measure(); | |
| printf("time per call: %.3g\n", t); | |
| #ifdef PTEST_USE_THREAD | |
| pthread_mutex_lock(&mutex1); | |
| remaining -= 1; | |
| if (!remaining) | |
| pthread_cond_signal(&cond1); | |
| pthread_mutex_unlock(&mutex1); | |
| #endif | |
| return arg; | |
| } | |
| int main(void) | |
| { | |
| #ifndef PTEST_USE_THREAD | |
| start_routine(0); | |
| #else | |
| pthread_t th; | |
| int i, status; | |
| add1(0, 0); /* this is the main thread */ | |
| remaining = PTEST_USE_THREAD; | |
| for (i = 0; i < PTEST_USE_THREAD; i++) { | |
| status = pthread_create(&th, NULL, start_routine, NULL); | |
| assert(status == 0); | |
| } | |
| pthread_mutex_lock(&mutex1); | |
| while (remaining) | |
| pthread_cond_wait(&cond1, &mutex1); | |
| pthread_mutex_unlock(&mutex1); | |
| #endif | |
| return 0; | |
| } |