From 7473e7fd4c30b24eb72440eb4db952bf31fcb431 Mon Sep 17 00:00:00 2001 From: Bowen Fu Date: Thu, 28 Jul 2022 21:22:17 +0800 Subject: [PATCH 1/6] Implement STM part 6 --- test/hspp/stm.cpp | 135 +++++++++++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 42 deletions(-) diff --git a/test/hspp/stm.cpp b/test/hspp/stm.cpp index 6c56d4f..616215d 100644 --- a/test/hspp/stm.cpp +++ b/test/hspp/stm.cpp @@ -458,6 +458,16 @@ struct TVar IORef>> waitQueue; }; +// constexpr auto newTVar = toGFunc<1> | [](auto a) +// { +// using A = decltype(a); +// return io([&] +// { +// auto const readStamp = readIORef(globalClock).run(); +// return TVar{myTId.run(), initIORef(readStamp), {}, {}}; +// }); +// }; + struct RSE { ID id; @@ -500,7 +510,8 @@ class Commiter template class CommitterRegister { - CommitterRegister() +public: + constexpr CommitterRegister() { anyCommiters.emplace(std::type_index(typeid(T)), Commiter{}); } @@ -509,7 +520,7 @@ class CommitterRegister template struct WSEData { - static const CommitterRegister dummy{}; + constexpr static CommitterRegister dummy{}; IORef content; A newValue; }; @@ -524,7 +535,7 @@ struct WSE constexpr auto toWSE = toGFunc<5> | [](Lock lock, IORef writeStamp, IORef>> waitQueue, auto content, auto newValue) { - return WSE{lock, writeStamp, waitQueue, WSEData{content, newValue}}; + return WSE{lock, writeStamp, waitQueue, WSEData{content, newValue}}; }; using ReadSet = IORef>; @@ -596,11 +607,10 @@ TEST(atomCAS, clock) template class Valid : public std::pair -{}; - -constexpr auto toValid = toGFunc<2> | [](TState ts, auto a) { - return Valid{ts, a}; +public: + using T = A; + using std::pair::pair; }; class Retry : public TState @@ -614,6 +624,12 @@ class TResult : public std::variant, Retry, Invalid> { public: using DataT = A; + using std::variant, Retry, Invalid>::variant; +}; + +constexpr auto toValid = toGFunc<2> | [](TState ts, auto a) +{ + return TResult{Valid{ts, a}}; }; template @@ -627,7 +643,7 @@ class STM constexpr STM(Func func) : mFunc{std::move(func)} {} - auto run(TState tState) const + auto run(TState tState) const -> RetT { return mFunc(tState); } @@ -649,11 +665,6 @@ constexpr auto toSTM = toGFunc<1> | [](auto func) return toSTMImpl(func); }; -constexpr auto castToPtr = toGFunc<1> | [](auto obj) -{ - return ioData(std::any{obj}); -}; - constexpr auto putWS = toFunc<> | [](WriteSet ws, ID id, WSE wse) { return io([=] @@ -691,9 +702,8 @@ constexpr auto writeTVarImpl(TVar const& tvar, A const& newValue) return toSTM | [=](auto tState) { auto [lock, id, wstamp, content, queue] = tvar; - Id wse; + WSE wse = (toWSE | lock | wstamp | queue | content | newValue); return do_( - wse <= (toWSE | lock | wstamp | queue | content | newValue), putWS | (getWriteSet | tState) | id | wse, return_ | (toValid | tState | _o_) ); @@ -718,28 +728,28 @@ constexpr auto readTVarImpl(TVar const tvar) { return toSTM | [=](TState tState) { - Id> mptr; - auto const handleMPtr = toFunc<> | [=](TState tState, std::optional mptr_) + Id> mwse; + auto const handleMWse = toFunc<> | [=](TState tState, std::optional mwse_) { return io([=]() -> TResult { - if (mptr_.has_value()) + if (mwse_.has_value()) { - auto const& wse = mptr_.value(); + auto const& wse = mwse_.value(); auto const& wseData = std::any_cast const&>(wse.wseData); - return toValid | tState | wseData.newData; + return toValid | tState | wseData.newValue; } else { auto [lock, id, wstamp, content, queue] = tvar; - auto const lockVal = lock.data.get(); + auto lockVal = (readLock | lock).run(); if (isLocked | lockVal) { return Invalid{tState}; } - auto const result = content.data.get(); - auto const lockVal2 = lock.data.get(); + auto const result = (readIORef | content).run(); + auto lockVal2 = (readLock | lock).run(); if ((lockVal != lockVal2) || (lockVal > (tState.readStamp))) { return Invalid{tState}; @@ -751,8 +761,8 @@ constexpr auto readTVarImpl(TVar const tvar) }); }; return do_( - mptr <= (lookUpWS | (getWriteSet | tState) | tvar.id), - handleMPtr | tState | mptr + mwse <= (lookUpWS | (getWriteSet | tState) | tvar.id), + handleMWse | tState | mwse ); }; } @@ -771,11 +781,11 @@ template <> class Applicative { public: - template - constexpr static auto pure(A x) + constexpr static auto pure = toGFunc<1> | [](auto x) { + using A = decltype(x); return toSTM | [=](auto tState) { return ioData>(toValid | tState | x); }; - } + }; }; @@ -784,7 +794,7 @@ class MonadBase { public: template - constexpr static auto bind(STM const& t1, Func const& f) + constexpr static auto bind(STM const& t1, Func const& func) { return toSTM || [=](TState tState) { @@ -793,26 +803,28 @@ class MonadBase { return io([=] { + using T = typename std::decay_t()).run(std::declval()).run())>::DataT; + using RetT = TResult; return std::visit(overload( - [=](Valid const& v_) -> TResult + [=](Valid const& v_) -> RetT { auto [nTState, v] = v_; auto t2 = func(v); - return t2(nTState).run(); + return t2.run(nTState).run(); }, - [=](Retry const&) + [=](Retry const& retry_) -> RetT { - return tResult; + return toValid | tState | T{}; }, - [=](Invalid const&) + [=](Invalid const& invalid_) -> RetT { - return tResult; + return toValid | tState | T{}; } ), tResult); }); }; return do_( - tRes <= t1(tState), + tRes <= t1.run(tState), dispatchResult | tRes ); }; @@ -1050,7 +1062,7 @@ constexpr auto addToWaitQueues = toFunc<> | [](MVar<_O_> mvar) template -auto atomicallyImpl(STM const& stmac) +auto atomicallyImpl(STM const& stmac) -> IO { Id ts; Id> r; @@ -1067,11 +1079,11 @@ auto atomicallyImpl(STM const& stmac) (void)ti; (void)a; auto wslist = (readIORef | nts.writeSet).run(); - auto [success, locks] = getLocks | nts.transId | wslist; + auto [success, locks] = (getLocks | nts.transId | wslist).run(); if (success) { auto wstamp = incrementGlobalClock.run(); - auto valid = validateReadSet | nts.readSet | nts.readStamp | nts.transId; + auto valid = (validateReadSet | nts.readSet | nts.readStamp | nts.transId).run(); if (valid) { (commitChangesToMemory | wstamp | wslist).run(); @@ -1118,11 +1130,50 @@ auto atomicallyImpl(STM const& stmac) ), tResult); }); }; - return do_( - ts <= newTState, - r <= stmac.run(ts), + return toTEIO | do_( + r <= stmac.run(newTState.run()), dispatchResult | r ); } +constexpr auto atomically = toGFunc<1> | [](auto const& stmac) +{ + return atomicallyImpl(stmac); +}; + } // namespace concurrent + +template