diff --git a/mutex.cc b/mutex.cc index 639ce37a47f9bd383e6de205e75a1ba4a93230be..89f02c939b23720db440beff8f31be62e845c84b 100644 --- a/mutex.cc +++ b/mutex.cc @@ -2,16 +2,34 @@ void mutex::lock() { - // dummy - no threads yet + // FIXME: use atomics + if (!_locked) { + _locked = true; + return; + } else { + auto me = sched::thread::current(); + _waiters.push_back(me); + sched::thread::wait_until([=] { + return !_locked && _waiters.front() == me; + }); + _waiters.pop_front(); + } } bool mutex::try_lock() { - // dummy - no threads yet - return true; + if (_locked) { + return false; + } else { + _locked = true; + return true; + } } void mutex::unlock() { - // dummy - no threads yet + _locked = false; + if (!_waiters.empty()) { + _waiters.front()->wake(); + } } diff --git a/mutex.hh b/mutex.hh index 4b3a1ab9d08949956ba450382cb41433bef19763..e74eed244f53b14a6e8f1e10a093e2ff4d7b51e3 100644 --- a/mutex.hh +++ b/mutex.hh @@ -2,12 +2,17 @@ #define MUTEX_HH #include <mutex> +#include <list> +#include "sched.hh" class mutex { public: void lock(); bool try_lock(); void unlock(); +private: + bool _locked; + std::list<sched::thread*> _waiters; }; template <class Lock, class Func>