1139823Simp// Mini-benchmark for creating a lot of threads.
21541Srgrimes//
31541Srgrimes// Some facts:
41541Srgrimes// a) clang -O1 takes <15ms to start N=500 threads,
51541Srgrimes//    consuming ~4MB more RAM than N=1.
61541Srgrimes// b) clang -O1 -ftsan takes ~26s to start N=500 threads,
71541Srgrimes//    eats 5GB more RAM than N=1 (which is somewhat expected but still a lot)
81541Srgrimes//    but then it consumes ~4GB of extra memory when the threads shut down!
91541Srgrimes//        (definitely not in the barrier_wait interceptor)
101541Srgrimes//    Also, it takes 26s to run with N=500 vs just 1.1s to run with N=1.
111541Srgrimes#include <assert.h>
121541Srgrimes#include <pthread.h>
131541Srgrimes#include <stdio.h>
141541Srgrimes#include <stdlib.h>
151541Srgrimes#include <unistd.h>
161541Srgrimes
171541Srgrimespthread_barrier_t all_threads_ready;
181541Srgrimes
191541Srgrimesvoid* Thread(void *unused) {
201541Srgrimes  pthread_barrier_wait(&all_threads_ready);
211541Srgrimes  return 0;
221541Srgrimes}
231541Srgrimes
241541Srgrimesint main(int argc, char **argv) {
251541Srgrimes  int n_threads;
261541Srgrimes  if (argc == 1) {
271541Srgrimes    n_threads = 100;
281541Srgrimes  } else if (argc == 2) {
2985052Sru    n_threads = atoi(argv[1]);
3050477Speter  } else {
311541Srgrimes    printf("Usage: %s n_threads\n", argv[0]);
321541Srgrimes    return 1;
332168Spaul  }
342168Spaul  printf("%s: n_threads=%d\n", __FILE__, n_threads);
352168Spaul
361541Srgrimes  pthread_barrier_init(&all_threads_ready, NULL, n_threads + 1);
371541Srgrimes
388876Srgrimes  pthread_t *t = new pthread_t[n_threads];
391541Srgrimes  for (int i = 0; i < n_threads; i++) {
401541Srgrimes    int status = pthread_create(&t[i], 0, Thread, (void*)i);
411541Srgrimes    assert(status == 0);
421541Srgrimes  }
431541Srgrimes  // sleep(5);  // FIXME: simplify measuring the memory usage.
441541Srgrimes  pthread_barrier_wait(&all_threads_ready);
451541Srgrimes  for (int i = 0; i < n_threads; i++) {
461541Srgrimes    pthread_join(t[i], 0);
471541Srgrimes  }
481541Srgrimes  // sleep(5);  // FIXME: simplify measuring the memory usage.
491541Srgrimes  delete [] t;
501541Srgrimes
511541Srgrimes  return 0;
521541Srgrimes}
531541Srgrimes