#include <stdlib.h>
#include <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 32
-pthread_t my_threads[NUM_TEST_THREADS];
-void *my_retvals[NUM_TEST_THREADS];
pthread_barrier_t barrier;
-void *thread(void* arg)
+#define MAX_NR_TEST_THREADS 100000
+int nr_threads = 100;
+int nr_loops = 10000;
+int nr_vcores = 0;
+
+pthread_t *my_threads;
+void **my_retvals;
+bool run_barriertest = FALSE;
+
+void *thread(void *arg)
{
- for(int i=0; i<NUM_TEST_THREADS; i++) {
- //printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, vcore_id());
+ while (!run_barriertest)
+ cpu_relax();
+ for(int i = 0; i < nr_loops; i++) {
pthread_barrier_wait(&barrier);
}
- return (void*)(pthread_self()->id);
+ return (void*)(long)pthread_self()->id;
}
int main(int argc, char** argv)
{
- pthread_barrier_init(&barrier, NULL, NUM_TEST_THREADS);
- #define NUM_ITERATIONS 5000
- for(int j=0; j<NUM_ITERATIONS; j++) {
-// while (1) {
- for (int i = 1; i <= NUM_TEST_THREADS; i++) {
- pthread_create(&my_threads[i-1], NULL, &thread, NULL);
- }
- for (int i = 1; i <= NUM_TEST_THREADS; i++) {
- pthread_join(my_threads[i-1], &my_retvals[i-1]);
+ struct timeval start_tv = {0};
+ struct timeval end_tv = {0};
+ long usec_diff;
+ if (argc > 1)
+ nr_threads = strtol(argv[1], 0, 10);
+ if (argc > 2)
+ nr_loops = strtol(argv[2], 0, 10);
+ if (argc > 3)
+ nr_vcores = strtol(argv[3], 0, 10);
+ printf("Running %d threads for %d iterations on %d vcores\n",
+ nr_threads, nr_loops, nr_vcores);
+ nr_threads = MIN(nr_threads, MAX_NR_TEST_THREADS);
+ my_threads = malloc(sizeof(pthread_t) * nr_threads);
+ my_retvals = malloc(sizeof(void*) * nr_threads);
+ if (!(my_retvals && my_threads))
+ perror("Init threads/malloc");
+ if (nr_vcores) {
+ /* Only do the vcore trickery if requested */
+ pthread_can_vcore_request(FALSE); /* 2LS won't manage vcores */
+ pthread_lib_init(); /* gives us one vcore */
+ vcore_request(nr_vcores - 1); /* ghetto incremental interface */
+ for (int i = 0; i < nr_vcores; i++) {
+ printd("Vcore %d mapped to pcore %d\n", i,
+ __procinfo.vcoremap[i].pcoreid);
}
- printf("Iteration %d of %d\n", j, NUM_ITERATIONS);
}
+ pthread_barrier_init(&barrier, NULL, nr_threads);
+ for (int i = 0; i < nr_threads; i++) {
+ pthread_create(&my_threads[i], NULL, &thread, NULL);
+ }
+ if (gettimeofday(&start_tv, 0))
+ perror("Start time error...");
+ run_barriertest = TRUE;
+ for (int i = 0; i < nr_threads; i++) {
+ pthread_join(my_threads[i], &my_retvals[i]);
+ }
+ if (gettimeofday(&end_tv, 0))
+ perror("End time error...");
+ pthread_barrier_destroy(&barrier);
+ usec_diff = (end_tv.tv_sec - start_tv.tv_sec) * 1000000 +
+ (end_tv.tv_usec - start_tv.tv_usec);
+ printf("Done: %d threads, %d loops, %d vcores\n",
+ nr_threads, nr_loops, nr_vcores);
+ printf("Time to run: %d usec, %f usec per barrier\n", usec_diff,
+ (float)usec_diff / nr_loops);
pthread_barrier_destroy(&barrier);
- sys_proc_destroy(getpid(), 0);
}