SlideShare une entreprise Scribd logo
1  sur  39
Télécharger pour lire hors ligne
Software Transactional Memory
Pure functional approach
Alexander Granin
graninas@gmail.com
C++ Russia 2018, Saint Petersburg
struct Presentation
{
Introduction1 Functional programming in C++
Introduction2 Parallel and concurrent programming in C++
Theory Software Transactional Memory
Practice Dining philosophers task
Implementation What’s inside?
Limitations What you should be aware of
};
Introduction 1. Functional programming in C++
● Lambdas, closures, functions (almost pure)
● std::function<>
● Combining of pure functions
● Immutability, POD-types
● Templates - pure functional language
● for_each(), recursion
● Type inference
● Pain
std::thread
std::future
std::promise
std::async
Introduction 2. Parallel and concurrent programming in C++
std::atomic
std::mutex
std::condition_variable
Theory. Software Transactional Memory
● Concurrent data model
● Independent parallel computations (“transactions”) over a different parts of the model
● Atomic commit of changed at the end of the computations:
○ Successful, if there are no conflicts of competing changes
○ Failed, if there are conflicts
■ Changes will be rollbacked, transaction will be restarted
● It’s also nice to have:
○ Absence of explicit synchronizations
○ Composable transactions
○ Capability to retry transactions
○ Adequate behavior and safety
● New blocks:
○ atomic_noexcept
○ atomic_cancel
○ atomic_commit
○ synchronized
● Transaction-safe functions
○ transaction_safe
● Pros:
○ Transaction-safe functions
● Cons:
○ Too chaotic
○ Too far from release
○ Bad way to do STM
● Requirements:
○ GCC 6.1
Technical Specification ISO/IEC TS 19841:2015
int f()
{
static int i = 0;
atomic_noexcept
{
++i;
return i;
}
}
Wyatt-STM
WSTM::Atomically ([&](WSTM::WAtomic& at)
{
++repeat1;
v1.Set (v1.Get (at) + v2.Get (at), at);
barrier.wait ();
});
● Pros:
○ Composable transactions
○ Retry operation
○ In production
● Cons:
○ Too imperative: easy to hack
○ Has some unwanted weakness
○ Boost
● Requirements:
○ Visual Studio 2015, GCC 4.9, Clang 3.4
○ Boost 1.57
● https://github.com/bretthall/Wyatt-STM
● CppCon 2015: Brett Hall “Transactional Memory in Practice"
My library: cpp_stm_free
STML<ForkPair>
readForks(const TForkPair& forks)
{
STML<Fork> lm = readTVar(forks.left);
STML<Fork> rm = readTVar(forks.right);
return both(lm, rm, mkForkPair);
};
● Pros:
○ Purely functional: hard to hack
○ Composable monadic transactions
○ Retry operation
○ Adequate behavior
○ Many ways to improve and optimize
● Cons:
○ Highly experimental, Proof of Concept
○ Mind blowing, probably
○ Performance - ??? (will measure later)
● Requirements:
○ GCC 7.2, C++17
● https://github.com/graninas/cpp_stm_free
TVar<int> tMyInt = newTVarIO(10);
TVar operations
TVar<int> tMyInt = newTVarIO(10);
auto someResult = readTVar(tMyInt);
TVar operations
TVar<int> tMyInt = newTVarIO(10);
auto someResult = readTVar(tMyInt);
writeTVar(tMyInt, 20);
TVar operations
TVar<int> tMyInt = newTVarIO(10);
auto someResult = readTVar(tMyInt);
writeTVar(tMyInt, 20);
// Why IO?
// someResult is int?
// Doesn’t return anything, right?
TVar operations
TVar<int> tMyInt = newTVarIO(10);
STML<int> someResult = readTVar(tMyInt);
STML<Unit> m = writeTVar(tMyInt, 20);
Transactions
STML<int> - transactional type, thus:
readTVar - transaction (returns stm::STML<T>)
writeTVar - transaction (returns stm::STML<Unit>)
newTVarIO - not a transaction (returns something else)
// Why IO?
// → Not a transaction.
// someResult is int?
// → Nope. It’s STML<int>.
// Doesn’t return anything, right?
// → Actually returns STML<Unit>.
template <typename A>
STML<TVar<A>> newTVar(const A& val);
template <typename A>
STML<A> readTVar(const TVar<A>& tvar);
template <typename A>
STML<Unit> writeTVar(const TVar<A>& tvar,
const A& val);
template <typename A>
STML<A> retry();
template <typename A>
STML<A> pure(const A& val);
Transactions
newTVar :: A → STML<TVar<A>>
readTVar :: TVar<A> → STML<A>
writeTVar :: TVar<A> → A → STML<Unit>
retry :: STML<A>
pure :: A → STML<A>
Composing transactions
bind ::
STML<A> → (A → STML<B>) → STML<B>
transaction :: STML<int>
transaction = do
tvar ← newTVar (10)
readTVar (tvar)
template <typename A, typename B>
STML<B> bind(const STML<A> ma,
const function<STML<B>(A)>& f);
STML<int> transaction()
{
STML<TVar<int>> t1 = newTVar(10);
STML<int> t2 = bind(t1, [](const TVar<int>& tvar) {
return readTVar(tvar);
});
return t2;
}
STML<TVar<int>> t1 = newTVar(10);
STML<int> t2 = bind(t1, readTVar); // short form without lambda
Context context; // All TVars live in the context
int result1 = atomically(context, t2); // result1 == 10
int result2 = atomically(context, t2); // result2 == 10, also*
// * but can be different on case of many competing threads trying to change this TVar.
Atomic evaluation
STML<TVar<int>> t1 = newTVar(10);
STML<int> t2 = bind(t1, readTVar); // short form without lambda
STML<int> t3 = bind(t2, [](int i) {
if (i == 10) return retry(); // retry if i == 10
return pure(i + 1); // return incremented i otherwise
});
Context context; // All TVars live in the context
int result1 = atomically(context, t2); // result1 == 10
int result2 = atomically(context, t2); // result2 == 10, also*
int result3 = atomically(context, t3); // tries hard to retry the transaction
// * but can be different on case of many competing threads trying to change this TVar.
Retrying
template <typename A, typename B, typename Ret>
STML<Ret> both(const STML<A>& ma,
const STML<B>& mb,
const function<Ret(A, B)>& f);
template <typename A, typename B>
STML<B> sequence(const STML<A>& ma,
const STML<B>& mb);
template <typename B>
STML<B> ifThenElse(const STML<bool>& m,
const STML<B>& mOnTrue,
const STML<B>& mOnFalse);
Useful combinators
// Do both computations separately,
// combine the results with function,
// return combined result
// Do the first computation,
// drop its result,
// do the second computation,
// return its result
// Do the conditional computation `m`,
// if true, do `mOnTrue`
// otherwise, do `mOnFalse`
Practice. Dining philosophers task
enum class ForkState
{
Free,
Taken
};
struct Fork
{
std::string name;
ForkState state;
};
enum class Activity
{
Thinking,
Eating
};
struct TForkPair
{
TVar<Fork> left;
TVar<Fork> right;
};
struct Philosopher
{
std::string name;
TVar<Activity> activity;
TForkPair forks;
};
// Fine grained
TVar<Fork> tFork1 = newTVarIO(someContext, Fork {"1", ForkState::Free});
TVar<Fork> tFork2 = newTVarIO(someContext, Fork {"2", ForkState::Free});
TVar<Fork> tFork3 = newTVarIO(someContext, Fork {"3", ForkState::Free});
// Coarse grained
std::vector<Fork> forks =
{ Fork {"1", ForkState::Free}
, Fork {"2", ForkState::Free}
, Fork {"3", ForkState::Free}
}
TVar<std::vector<Fork>> tForks = newTVarIO(someContext, forks);
Fine vs. Coarse Grained
Taking a fork
STML<bool> takeFork(const TVar<Fork>& tFork)
{
STML<bool> alreadyTaken = withTVar(tFork, isForkTaken);
STML<Unit> takenByUs = modifyTVar(tFork, setForkTaken);
STML<bool> success = sequence(takenByUs, pure(true));
STML<bool> fail = pure(false);
STML<bool> result = ifThenElse(alreadyTaken, fail, success);
return result;
};
const function<bool(Fork)> isForkTaken = [](const Fork& fork) {
return fork.state == ForkState::Taken;
};
const function<Fork(Fork)> setForkTaken = [](const Fork& fork) {
return Fork { fork.name, ForkState::Taken };
};
Taking both forks
STML<bool> takeForks(const TForkPair& forks)
{
STML<bool> leftTaken = takeFork(forks.left);
STML<bool> rightTaken = takeFork(forks.right);
STML<bool> bothTaken = both(leftTaken,
rightTaken,
[](bool l, bool r) { return l && r; });
return bothTaken;
};
Philosopher: changing activity
STML<Activity> changeActivity(const Philosopher& philosopher)
{
STML<Activity> mActivity = readTVar(philosopher.activity);
STML<Activity> mNewActivity = bind(mActivity, [=](Activity currentActivity)
{
if (currentActivity == Activity::Thinking)
{
STML<bool> taken = takeForks(philosopher.forks); // try take forks
STML<Unit> change = writeTVar(philosopher.activity, Activity::Eating);
STML<Unit> m = ifThenElse(taken, change, retry()); // retry if not taken
return sequence(m, pure(Activity::Eating));
}
// more code here
}
return mNewActivity;
}
Running the task
void philosopherWorker(stm::Context& context, const Philosopher& philosopher) {
while (true) {
stm::atomically(context, changeActivity(philosopher));
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
stm::Context context;
stm::TVar<Fork> tFork1 = stm::newTVarIO(context, Fork {"1", ForkState::Free }, " Fork 1");
stm::TVar<Fork> tFork2 = stm::newTVarIO(context, Fork {"2", ForkState::Free }, " Fork 2");
Philosopher philosopher1 = mkPhilosopher(context, "1", tFork1, tFork2); // default activity TVar
Philosopher philosopher2 = mkPhilosopher(context, "2", tFork2, tFork1); // will be created here
std::thread(philosopherWorker, context, philosopher1);
std::thread(philosopherWorker, context, philosopher2);
[1] (2) Eating, 1=Taken : 2=Taken
[2] (1) Thinking, 2=Taken : 3=Taken
[3] (2) Eating, 3=Taken : 4=Taken
[4] (1) Thinking, 4=Taken : 5=Free
[5] (1) Thinking, 5=Free : 1=Taken
Philosopher 3 changed activity to: Thinking for 3 seconds.
Philosopher 1 changed activity to: Thinking for 3 seconds.
Philosopher 2 changed activity to: Eating for 1 seconds.
Philosopher 4 changed activity to: Eating for 1 seconds.
[1] (3) Thinking, 1=Free : 2=Taken
[2] (2) Eating, 2=Taken : 3=Taken
[3] (3) Thinking, 3=Taken : 4=Taken
[4] (2) Eating, 4=Taken : 5=Taken
[5] (1) Thinking, 5=Taken : 1=Free
Sample console output
Implementation. What’s inside?
Embedded Domain-Specific Language for STM
template <typename A, typename Next>
struct NewTVar
{
A val;
std::function<Next(TVar<A>)> next;
};
template <typename A, typename Next>
struct ReadTVar
{
TVar<A> tvar;
std::function<Next(A)> next;
};
template <typename A, typename Next>
struct WriteTVar
{
TVar<A> tvar;
A val;
std::function<Next(fp::Unit)> next;
};
template <typename A, typename Next>
struct Retry
{
};
STM Algebraic Data Type
template <class Ret>
struct STMF
{
std::variant<NewTVar <std::any, Ret>,
ReadTVar <std::any, Ret>,
WriteTVar <std::any, Ret>,
Retry <std::any, Ret>
> stmf;
};
template <typename Ret>
struct PureF {
Ret ret;
};
template <typename Ret>
struct FreeF {
STMF<STML<Ret>> stmf;
};
template <typename Ret>
struct STML {
std::variant<PureF<Ret>,
FreeF<Ret>
> stml;
};
Free Monad Recursive Algebraic Data Type
template <class Ret>
struct STMF
{
std::variant<NewTVar <std::any, Ret>,
ReadTVar <std::any, Ret>,
WriteTVar <std::any, Ret>,
Retry <std::any, Ret>
> stmf;
};
Free Monad Recursive Algebraic Data Type
STML<A>→
STML<A>
→ FreeF<A>
→ STMF<STML<A>>
→ ReadTVar<std::any, A>
→ [](std::any any) {
return STML<A>
→ PureF<A>
→ std::any_cast<A>(any)
}
Free Monad Recursive Algebraic Data Type
STML<A>→
STML<A>
→ FreeF<A>
→ STMF<STML<A>>
→ ReadTVar<std::any, A>
→ [](std::any any) {
return STML<A>
→ PureF<A>
→ std::any_cast<A>(any)
}
Monadic binding
template <typename A, typename B>
struct BindStmlVisitor;
template <typename A, typename B>
struct BindStmfVisitor;
template <typename A, typename B>
STML<B> bind(const STML<A>& stml, const std::function<STML<B>(A)>& f)
{
BindStmlVisitor<A, B> visitor(f);
std::visit(visitor, stml.stml);
return visitor.result;
}
“Pattern-matching”
template <typename A, typename B>
struct BindStmfVisitor
{
void operator() (const NewTVar<std::any, STML<A>>& method);
void operator() (const ReadTVar<std::any, STML<A>>& method);
void operator() (const WriteTVar<std::any, STML<A>>& method);
void operator() (const Retry <std::any, STML<A>>&);
};
template <typename A, typename B>
struct BindStmlVisitor
{
void operator() (const PureF<A>& variant);
void operator() (const FreeF<A>& variant);
};
Typed / Untyped
template <typename A, typename Next>
struct ReadTVar { // ReadTVar<A, Next>
TVar<A> tvar; // TVar<A>
std::function<Next(A)> next;
ReadTVar<std::any, Next> toAny() const {
std::function<Next(A)> nextCopy = next;
ReadTVar<std::any, Next> m; // ReadTVar<std::any, Next>
m.tvar = TVar<std::any> { tvar.id }; // TVar<std::any>
m.next = [=](const std::any& val) { // A → std::any
A val2 = std::any_cast<A>(val); // std::any → A
return nextCopy(val2);
};
return m;
}
};
TVar Interface & Implementation
using TVarId = utils::GUID;
template <typename T>
struct TVar
{
std::string name;
TVarId id;
};
struct TVarHandle
{
GUID ustamp;
std::any data;
};
using TVars = std::map<TVarId, TVarHandle>;
class Context
{
std::map<TVarId, TVarHandle> _tvars;
std::mutex _lock;
public:
bool tryCommit(const GUID& ustamp, const TVars& stagedTvars);
};
Limitations. What you should be aware of
● Side effects in transactions are prohibited
● Proper binding of transactions
● Proper data model (fine grained vs coarse grained)
● Occasional infinite retry
● Dangerous closures (be careful passing things by reference)
● Starvation
● Deadlock / livelock
● Implementation isn’t optimal by performance (yet)
Thanks for watching!
Alexander Granin
graninas@gmail.com
C++ Russia 2018, Saint Petersburg

Contenu connexe

Tendances

C++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogrammingC++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogrammingcppfrug
 
Devirtualizing FinSpy
Devirtualizing FinSpyDevirtualizing FinSpy
Devirtualizing FinSpyjduart
 
LLVM Register Allocation (2nd Version)
LLVM Register Allocation (2nd Version)LLVM Register Allocation (2nd Version)
LLVM Register Allocation (2nd Version)Wang Hsiangkai
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196Mahmoud Samir Fayed
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)jeffz
 
JIT compilation for CPython
JIT compilation for CPythonJIT compilation for CPython
JIT compilation for CPythondelimitry
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2PVS-Studio
 
Algorithm and Programming (Looping Structure)
Algorithm and Programming (Looping Structure)Algorithm and Programming (Looping Structure)
Algorithm and Programming (Looping Structure)Adam Mukharil Bachtiar
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)jeffz
 
Renaming Tokens
Renaming TokensRenaming Tokens
Renaming Tokensyanamm
 
DWARF Data Representation
DWARF Data RepresentationDWARF Data Representation
DWARF Data RepresentationWang Hsiangkai
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskAlexander Granin
 
Algorithm and Programming (Procedure and Function)
Algorithm and Programming (Procedure and Function)Algorithm and Programming (Procedure and Function)
Algorithm and Programming (Procedure and Function)Adam Mukharil Bachtiar
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The LandingHaci Murat Yaman
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itSergey Platonov
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09Guy Korland
 
C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumlercorehard_by
 

Tendances (20)

C++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogrammingC++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogramming
 
Joel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMDJoel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMD
 
Devirtualizing FinSpy
Devirtualizing FinSpyDevirtualizing FinSpy
Devirtualizing FinSpy
 
C++11 talk
C++11 talkC++11 talk
C++11 talk
 
LLVM Register Allocation (2nd Version)
LLVM Register Allocation (2nd Version)LLVM Register Allocation (2nd Version)
LLVM Register Allocation (2nd Version)
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)
 
JIT compilation for CPython
JIT compilation for CPythonJIT compilation for CPython
JIT compilation for CPython
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
 
Algorithm and Programming (Looping Structure)
Algorithm and Programming (Looping Structure)Algorithm and Programming (Looping Structure)
Algorithm and Programming (Looping Structure)
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
 
Renaming Tokens
Renaming TokensRenaming Tokens
Renaming Tokens
 
DWARF Data Representation
DWARF Data RepresentationDWARF Data Representation
DWARF Data Representation
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
 
Algorithm and Programming (Procedure and Function)
Algorithm and Programming (Procedure and Function)Algorithm and Programming (Procedure and Function)
Algorithm and Programming (Procedure and Function)
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
 
C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumler
 
Java concurrency
Java concurrencyJava concurrency
Java concurrency
 

Similaire à Software transactional memory. pure functional approach

GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPMiller Lee
 
Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor ConcurrencyAlex Miller
 
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfProgramming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfssuser6254411
 
Cs1123 8 functions
Cs1123 8 functionsCs1123 8 functions
Cs1123 8 functionsTAlha MAlik
 
11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class웅식 전
 
Object oriented programming system with C++
Object oriented programming system with C++Object oriented programming system with C++
Object oriented programming system with C++msharshitha03s
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and BeyondComicSansMS
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Sheik Uduman Ali
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
Common mistakes in android development
Common mistakes in android developmentCommon mistakes in android development
Common mistakes in android developmentHoang Nguyen Huu
 
Robust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksRobust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksStoyan Nikolov
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel GeheugenDevnology
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 
Practical Meta Programming
Practical Meta ProgrammingPractical Meta Programming
Practical Meta ProgrammingReggie Meisler
 

Similaire à Software transactional memory. pure functional approach (20)

C#, What Is Next?
C#, What Is Next?C#, What Is Next?
C#, What Is Next?
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor Concurrency
 
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdfProgramming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
Programming For Big Data [ Submission DvcScheduleV2.cpp and StaticA.pdf
 
Cs1123 8 functions
Cs1123 8 functionsCs1123 8 functions
Cs1123 8 functions
 
Slides13.pdf
Slides13.pdfSlides13.pdf
Slides13.pdf
 
11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class
 
C++ L05-Functions
C++ L05-FunctionsC++ L05-Functions
C++ L05-Functions
 
Object oriented programming system with C++
Object oriented programming system with C++Object oriented programming system with C++
Object oriented programming system with C++
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
Common mistakes in android development
Common mistakes in android developmentCommon mistakes in android development
Common mistakes in android development
 
Robust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksRobust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time Checks
 
Microkernel Development
Microkernel DevelopmentMicrokernel Development
Microkernel Development
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
The STL
The STLThe STL
The STL
 
Practical Meta Programming
Practical Meta ProgrammingPractical Meta Programming
Practical Meta Programming
 

Plus de Alexander Granin

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stmAlexander Granin
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fpAlexander Granin
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monadAlexander Granin
 
The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++Alexander Granin
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentAlexander Granin
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Alexander Granin
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Alexander Granin
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's lawAlexander Granin
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FPAlexander Granin
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчикаAlexander Granin
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++Alexander Granin
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentialsAlexander Granin
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPAlexander Granin
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsAlexander Granin
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Alexander Granin
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФПAlexander Granin
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиAlexander Granin
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Alexander Granin
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный кодAlexander Granin
 

Plus de Alexander Granin (20)

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
 
The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный код
 

Dernier

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 

Dernier (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

Software transactional memory. pure functional approach

  • 1. Software Transactional Memory Pure functional approach Alexander Granin graninas@gmail.com C++ Russia 2018, Saint Petersburg
  • 2.
  • 3. struct Presentation { Introduction1 Functional programming in C++ Introduction2 Parallel and concurrent programming in C++ Theory Software Transactional Memory Practice Dining philosophers task Implementation What’s inside? Limitations What you should be aware of };
  • 4. Introduction 1. Functional programming in C++ ● Lambdas, closures, functions (almost pure) ● std::function<> ● Combining of pure functions ● Immutability, POD-types ● Templates - pure functional language ● for_each(), recursion ● Type inference ● Pain
  • 5. std::thread std::future std::promise std::async Introduction 2. Parallel and concurrent programming in C++ std::atomic std::mutex std::condition_variable
  • 6. Theory. Software Transactional Memory ● Concurrent data model ● Independent parallel computations (“transactions”) over a different parts of the model ● Atomic commit of changed at the end of the computations: ○ Successful, if there are no conflicts of competing changes ○ Failed, if there are conflicts ■ Changes will be rollbacked, transaction will be restarted ● It’s also nice to have: ○ Absence of explicit synchronizations ○ Composable transactions ○ Capability to retry transactions ○ Adequate behavior and safety
  • 7. ● New blocks: ○ atomic_noexcept ○ atomic_cancel ○ atomic_commit ○ synchronized ● Transaction-safe functions ○ transaction_safe ● Pros: ○ Transaction-safe functions ● Cons: ○ Too chaotic ○ Too far from release ○ Bad way to do STM ● Requirements: ○ GCC 6.1 Technical Specification ISO/IEC TS 19841:2015 int f() { static int i = 0; atomic_noexcept { ++i; return i; } }
  • 8. Wyatt-STM WSTM::Atomically ([&](WSTM::WAtomic& at) { ++repeat1; v1.Set (v1.Get (at) + v2.Get (at), at); barrier.wait (); }); ● Pros: ○ Composable transactions ○ Retry operation ○ In production ● Cons: ○ Too imperative: easy to hack ○ Has some unwanted weakness ○ Boost ● Requirements: ○ Visual Studio 2015, GCC 4.9, Clang 3.4 ○ Boost 1.57 ● https://github.com/bretthall/Wyatt-STM ● CppCon 2015: Brett Hall “Transactional Memory in Practice"
  • 9. My library: cpp_stm_free STML<ForkPair> readForks(const TForkPair& forks) { STML<Fork> lm = readTVar(forks.left); STML<Fork> rm = readTVar(forks.right); return both(lm, rm, mkForkPair); }; ● Pros: ○ Purely functional: hard to hack ○ Composable monadic transactions ○ Retry operation ○ Adequate behavior ○ Many ways to improve and optimize ● Cons: ○ Highly experimental, Proof of Concept ○ Mind blowing, probably ○ Performance - ??? (will measure later) ● Requirements: ○ GCC 7.2, C++17 ● https://github.com/graninas/cpp_stm_free
  • 10. TVar<int> tMyInt = newTVarIO(10); TVar operations
  • 11. TVar<int> tMyInt = newTVarIO(10); auto someResult = readTVar(tMyInt); TVar operations
  • 12. TVar<int> tMyInt = newTVarIO(10); auto someResult = readTVar(tMyInt); writeTVar(tMyInt, 20); TVar operations
  • 13. TVar<int> tMyInt = newTVarIO(10); auto someResult = readTVar(tMyInt); writeTVar(tMyInt, 20); // Why IO? // someResult is int? // Doesn’t return anything, right? TVar operations
  • 14. TVar<int> tMyInt = newTVarIO(10); STML<int> someResult = readTVar(tMyInt); STML<Unit> m = writeTVar(tMyInt, 20); Transactions STML<int> - transactional type, thus: readTVar - transaction (returns stm::STML<T>) writeTVar - transaction (returns stm::STML<Unit>) newTVarIO - not a transaction (returns something else) // Why IO? // → Not a transaction. // someResult is int? // → Nope. It’s STML<int>. // Doesn’t return anything, right? // → Actually returns STML<Unit>.
  • 15. template <typename A> STML<TVar<A>> newTVar(const A& val); template <typename A> STML<A> readTVar(const TVar<A>& tvar); template <typename A> STML<Unit> writeTVar(const TVar<A>& tvar, const A& val); template <typename A> STML<A> retry(); template <typename A> STML<A> pure(const A& val); Transactions newTVar :: A → STML<TVar<A>> readTVar :: TVar<A> → STML<A> writeTVar :: TVar<A> → A → STML<Unit> retry :: STML<A> pure :: A → STML<A>
  • 16. Composing transactions bind :: STML<A> → (A → STML<B>) → STML<B> transaction :: STML<int> transaction = do tvar ← newTVar (10) readTVar (tvar) template <typename A, typename B> STML<B> bind(const STML<A> ma, const function<STML<B>(A)>& f); STML<int> transaction() { STML<TVar<int>> t1 = newTVar(10); STML<int> t2 = bind(t1, [](const TVar<int>& tvar) { return readTVar(tvar); }); return t2; }
  • 17. STML<TVar<int>> t1 = newTVar(10); STML<int> t2 = bind(t1, readTVar); // short form without lambda Context context; // All TVars live in the context int result1 = atomically(context, t2); // result1 == 10 int result2 = atomically(context, t2); // result2 == 10, also* // * but can be different on case of many competing threads trying to change this TVar. Atomic evaluation
  • 18. STML<TVar<int>> t1 = newTVar(10); STML<int> t2 = bind(t1, readTVar); // short form without lambda STML<int> t3 = bind(t2, [](int i) { if (i == 10) return retry(); // retry if i == 10 return pure(i + 1); // return incremented i otherwise }); Context context; // All TVars live in the context int result1 = atomically(context, t2); // result1 == 10 int result2 = atomically(context, t2); // result2 == 10, also* int result3 = atomically(context, t3); // tries hard to retry the transaction // * but can be different on case of many competing threads trying to change this TVar. Retrying
  • 19. template <typename A, typename B, typename Ret> STML<Ret> both(const STML<A>& ma, const STML<B>& mb, const function<Ret(A, B)>& f); template <typename A, typename B> STML<B> sequence(const STML<A>& ma, const STML<B>& mb); template <typename B> STML<B> ifThenElse(const STML<bool>& m, const STML<B>& mOnTrue, const STML<B>& mOnFalse); Useful combinators // Do both computations separately, // combine the results with function, // return combined result // Do the first computation, // drop its result, // do the second computation, // return its result // Do the conditional computation `m`, // if true, do `mOnTrue` // otherwise, do `mOnFalse`
  • 21. enum class ForkState { Free, Taken }; struct Fork { std::string name; ForkState state; }; enum class Activity { Thinking, Eating }; struct TForkPair { TVar<Fork> left; TVar<Fork> right; }; struct Philosopher { std::string name; TVar<Activity> activity; TForkPair forks; };
  • 22. // Fine grained TVar<Fork> tFork1 = newTVarIO(someContext, Fork {"1", ForkState::Free}); TVar<Fork> tFork2 = newTVarIO(someContext, Fork {"2", ForkState::Free}); TVar<Fork> tFork3 = newTVarIO(someContext, Fork {"3", ForkState::Free}); // Coarse grained std::vector<Fork> forks = { Fork {"1", ForkState::Free} , Fork {"2", ForkState::Free} , Fork {"3", ForkState::Free} } TVar<std::vector<Fork>> tForks = newTVarIO(someContext, forks); Fine vs. Coarse Grained
  • 23. Taking a fork STML<bool> takeFork(const TVar<Fork>& tFork) { STML<bool> alreadyTaken = withTVar(tFork, isForkTaken); STML<Unit> takenByUs = modifyTVar(tFork, setForkTaken); STML<bool> success = sequence(takenByUs, pure(true)); STML<bool> fail = pure(false); STML<bool> result = ifThenElse(alreadyTaken, fail, success); return result; }; const function<bool(Fork)> isForkTaken = [](const Fork& fork) { return fork.state == ForkState::Taken; }; const function<Fork(Fork)> setForkTaken = [](const Fork& fork) { return Fork { fork.name, ForkState::Taken }; };
  • 24. Taking both forks STML<bool> takeForks(const TForkPair& forks) { STML<bool> leftTaken = takeFork(forks.left); STML<bool> rightTaken = takeFork(forks.right); STML<bool> bothTaken = both(leftTaken, rightTaken, [](bool l, bool r) { return l && r; }); return bothTaken; };
  • 25. Philosopher: changing activity STML<Activity> changeActivity(const Philosopher& philosopher) { STML<Activity> mActivity = readTVar(philosopher.activity); STML<Activity> mNewActivity = bind(mActivity, [=](Activity currentActivity) { if (currentActivity == Activity::Thinking) { STML<bool> taken = takeForks(philosopher.forks); // try take forks STML<Unit> change = writeTVar(philosopher.activity, Activity::Eating); STML<Unit> m = ifThenElse(taken, change, retry()); // retry if not taken return sequence(m, pure(Activity::Eating)); } // more code here } return mNewActivity; }
  • 26. Running the task void philosopherWorker(stm::Context& context, const Philosopher& philosopher) { while (true) { stm::atomically(context, changeActivity(philosopher)); std::this_thread::sleep_for(std::chrono::seconds(5)); } } stm::Context context; stm::TVar<Fork> tFork1 = stm::newTVarIO(context, Fork {"1", ForkState::Free }, " Fork 1"); stm::TVar<Fork> tFork2 = stm::newTVarIO(context, Fork {"2", ForkState::Free }, " Fork 2"); Philosopher philosopher1 = mkPhilosopher(context, "1", tFork1, tFork2); // default activity TVar Philosopher philosopher2 = mkPhilosopher(context, "2", tFork2, tFork1); // will be created here std::thread(philosopherWorker, context, philosopher1); std::thread(philosopherWorker, context, philosopher2);
  • 27. [1] (2) Eating, 1=Taken : 2=Taken [2] (1) Thinking, 2=Taken : 3=Taken [3] (2) Eating, 3=Taken : 4=Taken [4] (1) Thinking, 4=Taken : 5=Free [5] (1) Thinking, 5=Free : 1=Taken Philosopher 3 changed activity to: Thinking for 3 seconds. Philosopher 1 changed activity to: Thinking for 3 seconds. Philosopher 2 changed activity to: Eating for 1 seconds. Philosopher 4 changed activity to: Eating for 1 seconds. [1] (3) Thinking, 1=Free : 2=Taken [2] (2) Eating, 2=Taken : 3=Taken [3] (3) Thinking, 3=Taken : 4=Taken [4] (2) Eating, 4=Taken : 5=Taken [5] (1) Thinking, 5=Taken : 1=Free Sample console output
  • 29. Embedded Domain-Specific Language for STM template <typename A, typename Next> struct NewTVar { A val; std::function<Next(TVar<A>)> next; }; template <typename A, typename Next> struct ReadTVar { TVar<A> tvar; std::function<Next(A)> next; }; template <typename A, typename Next> struct WriteTVar { TVar<A> tvar; A val; std::function<Next(fp::Unit)> next; }; template <typename A, typename Next> struct Retry { };
  • 30. STM Algebraic Data Type template <class Ret> struct STMF { std::variant<NewTVar <std::any, Ret>, ReadTVar <std::any, Ret>, WriteTVar <std::any, Ret>, Retry <std::any, Ret> > stmf; };
  • 31. template <typename Ret> struct PureF { Ret ret; }; template <typename Ret> struct FreeF { STMF<STML<Ret>> stmf; }; template <typename Ret> struct STML { std::variant<PureF<Ret>, FreeF<Ret> > stml; }; Free Monad Recursive Algebraic Data Type template <class Ret> struct STMF { std::variant<NewTVar <std::any, Ret>, ReadTVar <std::any, Ret>, WriteTVar <std::any, Ret>, Retry <std::any, Ret> > stmf; };
  • 32. Free Monad Recursive Algebraic Data Type STML<A>→ STML<A> → FreeF<A> → STMF<STML<A>> → ReadTVar<std::any, A> → [](std::any any) { return STML<A> → PureF<A> → std::any_cast<A>(any) }
  • 33. Free Monad Recursive Algebraic Data Type STML<A>→ STML<A> → FreeF<A> → STMF<STML<A>> → ReadTVar<std::any, A> → [](std::any any) { return STML<A> → PureF<A> → std::any_cast<A>(any) }
  • 34. Monadic binding template <typename A, typename B> struct BindStmlVisitor; template <typename A, typename B> struct BindStmfVisitor; template <typename A, typename B> STML<B> bind(const STML<A>& stml, const std::function<STML<B>(A)>& f) { BindStmlVisitor<A, B> visitor(f); std::visit(visitor, stml.stml); return visitor.result; }
  • 35. “Pattern-matching” template <typename A, typename B> struct BindStmfVisitor { void operator() (const NewTVar<std::any, STML<A>>& method); void operator() (const ReadTVar<std::any, STML<A>>& method); void operator() (const WriteTVar<std::any, STML<A>>& method); void operator() (const Retry <std::any, STML<A>>&); }; template <typename A, typename B> struct BindStmlVisitor { void operator() (const PureF<A>& variant); void operator() (const FreeF<A>& variant); };
  • 36. Typed / Untyped template <typename A, typename Next> struct ReadTVar { // ReadTVar<A, Next> TVar<A> tvar; // TVar<A> std::function<Next(A)> next; ReadTVar<std::any, Next> toAny() const { std::function<Next(A)> nextCopy = next; ReadTVar<std::any, Next> m; // ReadTVar<std::any, Next> m.tvar = TVar<std::any> { tvar.id }; // TVar<std::any> m.next = [=](const std::any& val) { // A → std::any A val2 = std::any_cast<A>(val); // std::any → A return nextCopy(val2); }; return m; } };
  • 37. TVar Interface & Implementation using TVarId = utils::GUID; template <typename T> struct TVar { std::string name; TVarId id; }; struct TVarHandle { GUID ustamp; std::any data; }; using TVars = std::map<TVarId, TVarHandle>; class Context { std::map<TVarId, TVarHandle> _tvars; std::mutex _lock; public: bool tryCommit(const GUID& ustamp, const TVars& stagedTvars); };
  • 38. Limitations. What you should be aware of ● Side effects in transactions are prohibited ● Proper binding of transactions ● Proper data model (fine grained vs coarse grained) ● Occasional infinite retry ● Dangerous closures (be careful passing things by reference) ● Starvation ● Deadlock / livelock ● Implementation isn’t optimal by performance (yet)
  • 39. Thanks for watching! Alexander Granin graninas@gmail.com C++ Russia 2018, Saint Petersburg