Created
January 13, 2016 21:54
-
-
Save buchgr/aaef825e5db9668a789e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PARALLEL_ZEROER_HPP | |
#define PARALLEL_ZEROER_HPP | |
#include <atomic> | |
#include <iostream> | |
#include <boost/asio.hpp> | |
#include <boost/thread.hpp> | |
class ParallelZeroer { | |
private: | |
boost::asio::io_service service; | |
boost::asio::io_service::work work; | |
boost::thread_group threads; | |
public: | |
static ParallelZeroer& instance(size_t parallelism) { | |
static ParallelZeroer pz(parallelism); | |
return pz; | |
} | |
void zeroMemory(void *p, size_t size) { | |
// invariant: nthreads is one less than a power of two. | |
size_t nthreads = this->threads.size(); | |
size_t divisible_size = size & ~nthreads; | |
size_t remainder = size & nthreads; | |
size_t chunk_size = divisible_size / (nthreads + 1); | |
std::atomic<unsigned> counter(nthreads); | |
for (size_t i = 0; i < nthreads; i++) { | |
this->service.post(boost::bind(doZeroMem, ((uint8_t*)p) + i * chunk_size, chunk_size, std::ref(counter))); | |
} | |
memset(((uint8_t*)p) + divisible_size - chunk_size, 0, chunk_size + remainder); | |
while (counter.load()) { | |
asm volatile("pause"); | |
} | |
} | |
private: | |
ParallelZeroer(size_t parallelism) : work(service) { | |
checkPowerOfTwo(parallelism); | |
for (size_t i = 0; i < parallelism - 1; i++) { | |
this->threads.create_thread(boost::bind(&boost::asio::io_service::run, &(this->service))); | |
} | |
} | |
static void doZeroMem(void *p, size_t size, std::atomic<unsigned> &counter) { | |
memset(p, 0, size); | |
counter--; | |
} | |
static void checkPowerOfTwo(size_t val) { | |
if (val > 0 && (val & val-1) != 0) { | |
throw std::runtime_error("val must be a power of two"); | |
} | |
} | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment