inline void ParallelFor()

in java/thread_pool.h [64:110]


inline void ParallelFor(size_t start, size_t end, size_t numThreads,
                        Function fn) {
  if (numThreads <= 0) {
    numThreads = std::thread::hardware_concurrency();
  }

  std::vector<std::thread> threads;
  std::atomic<size_t> current(start);

  // keep track of exceptions in threads
  // https://stackoverflow.com/a/32428427/1713196
  std::exception_ptr lastException = nullptr;
  std::mutex lastExceptMutex;

  for (size_t i = 0; i < numThreads; ++i) {
    threads.push_back(std::thread([&] {
      while (true) {
        size_t id = current.fetch_add(1);

        if ((id >= end)) {
          break;
        }

        try {
          fn(id);
        } catch (...) {
          std::unique_lock<std::mutex> lastExcepLock(lastExceptMutex);
          lastException = std::current_exception();
          /*
           * This will work even when current is the largest value that
           * size_t can fit, because fetch_add returns the previous value
           * before the increment (what will result in overflow
           * and produce 0 instead of current + 1).
           */
          current = end;
          break;
        }
      }
    }));
  }
  for (auto &thread : threads) {
    thread.join();
  }
  if (lastException) {
    std::rethrow_exception(lastException);
  }
}