#include using namespace std; #define WIN32_LEAN_AND_MEAN #include #include #include #include using namespace boost::interprocess; HANDLE runself(string const& _arg) { STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(STARTUPINFO); PROCESS_INFORMATION pi1; ZeroMemory(&pi1, sizeof(pi1)); CreateProcessA(0, (char*)("ProfileCache " + _arg).c_str(), 0, 0, FALSE, 0, 0, 0, &si, &pi1); Sleep(100); // 100ms to get its head together. return pi1.hProcess; } void term(HANDLE _h) { TerminateProcess(_h, 0); } void semaphore(int _work) { shared_memory_object::remove("ProfileCache-Semaphore1"); shared_memory_object::remove("ProfileCache-Semaphore2"); boost::interprocess::named_semaphore s1(boost::interprocess::create_only, "ProfileCache-Semaphore1", 1); boost::interprocess::named_semaphore s2(boost::interprocess::create_only, "ProfileCache-Semaphore2", 0); int x = 0; boost::timer t; for (int ti = 0; ti < 1000; ++ti) for (int i = 0; i < _work; ++i) x += rand(); cerr << t.elapsed(); // measure how long it takes to do the job normally. auto h = runself(("-s " + stringOf(_work)).c_str()); // start the worker. t.restart(); // 500 iterations = 1000 job computations; 500 for us, 500 for them. for (int i = 0; i < 500; ++i) { s1.wait(); for (int i = 0; i < _work; ++i) x += rand(); s2.post(); } cerr << " " << t.elapsed() << endl; // dummy test to guarantee optimiser doesn't discard the rands. if (x == 69 && _work == 0) throw false; term(h); } int main(int argc, char* argv[]) { if (argc == 1) { for (int i = 10; i < 17; ++i) semaphore(1 << i); } else if (argc >= 2 && argv[1] == string("-s")) { int w = (argc == 3) ? atoi(argv[2]) : 0; boost::interprocess::named_semaphore s1(boost::interprocess::open_only, "ProfileCache-Semaphore1"); boost::interprocess::named_semaphore s2(boost::interprocess::open_only, "ProfileCache-Semaphore2"); int x = 0; while (x != 69 || argc != 999) { s2.wait(); for (int i = 0; i < w; ++i) x += rand(); s1.post(); } } return 0; }