|  | #include <stdio.h> | 
|  | #include <pthread.h> | 
|  | #include <stdlib.h> | 
|  | #include <parlib/parlib.h> | 
|  | #include <unistd.h> | 
|  | #include <sys/time.h> | 
|  |  | 
|  | pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; | 
|  | #define printf_safe(...) {} | 
|  | //#define printf_safe(...) \ | 
|  | pthread_mutex_lock(&lock); \ | 
|  | printf(__VA_ARGS__); \ | 
|  | pthread_mutex_unlock(&lock); | 
|  |  | 
|  | #define NUM_TEST_THREADS 500 | 
|  | #define NUM_TEST_LOOPS 1000 | 
|  |  | 
|  | pthread_t my_threads[NUM_TEST_THREADS]; | 
|  | void *my_retvals[NUM_TEST_THREADS]; | 
|  |  | 
|  | __thread int my_id; | 
|  | void *block_thread(void* arg) | 
|  | { | 
|  | assert(!in_vcore_context()); | 
|  | for (int i = 0; i < NUM_TEST_LOOPS; i++) { | 
|  | printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, | 
|  | vcore_id()); | 
|  | sys_block(5000 + pthread_self()->id); | 
|  | } | 
|  | return (void*)(long)pthread_self()->id; | 
|  | } | 
|  |  | 
|  | int main(int argc, char** argv) | 
|  | { | 
|  | struct timeval tv = {0}; | 
|  |  | 
|  | if (gettimeofday(&tv, 0)) | 
|  | perror("Time error..."); | 
|  | printf("Start time: %dsec %dusec\n", tv.tv_sec, tv.tv_usec); | 
|  | for (int i = 0; i < NUM_TEST_THREADS; i++) { | 
|  | printf_safe("[A] About to create thread %d\n", i); | 
|  | pthread_create(&my_threads[i], NULL, &block_thread, NULL); | 
|  | } | 
|  | for (int i = 0; i < NUM_TEST_THREADS; i++) { | 
|  | printf_safe("[A] About to join on thread %d\n", i); | 
|  | pthread_join(my_threads[i], &my_retvals[i]); | 
|  | printf_safe("[A] Successful join on thread %d (retval: %p)\n", | 
|  | i, my_retvals[i]); | 
|  | } | 
|  | if (gettimeofday(&tv, 0)) | 
|  | perror("Time error..."); | 
|  | printf("End time  : %dsec %dusec\n", tv.tv_sec, tv.tv_usec); | 
|  | printf("All done, exiting cleanishly\n"); | 
|  | } |