/* Horrible task system */ #include #include #include #include #include #include using namespace std; using lock_t = unique_lock; class notification_queue { deque> _q; mutex _mutex; condition_variable _ready; bool _done{false}; public: void done() { { unique_lock lock{_mutex}; _done = true; } } bool pop(function& x) { lock_t lock{_mutex}; while (_q.empty() && !_done) _ready.wait(lock); if (_q.empty()) return false; x = move(_q.front()); _q.pop_front(); return true; } template void push(F&& f) { { lock_t lock{_mutex}; _q.emplace_back(forward(f)); } _ready.notify_one(); } }; class task_system { const unsigned _count{thread::hardware_concurrency()}; vector _threads; notification_queue _q; void run(unsigned i) { while (true) { function f; _q.pop(f); f(); } } public: task_system() { for (unsigned n = 0; n != _count; ++n) { _threads.emplace_back([&, n]{ run(n); }); } } ~task_system() { for (auto& e : _threads) e.join(); } template void async_(F&& f) { _q.push(forward(f)); } };