In computing, a programming language consists of a syntax plus an execution model.
[4] Operational Semantics is one method of specifying a language's execution model.
The C language actually has an additional level to its execution model, which is the order of precedence.
The order of precedence can be viewed as stating the constraints on performing the units of work that are within a single statement.
The implementation of an execution model can be via compiler, or interpreter, and often includes a runtime system.
This order may be chosen ahead of time, in some situations, or it can be dynamically determined as the execution proceeds.
The runtime system may be a library, which is called by instructions inserted by the compiler, or the runtime system may be embedded into the executable directly, such as by inserting branch instructions, which make dynamic choices about which work to perform next.
However, an interpreter may also be constructed for any language, in which case all decisions on order of execution are dynamic.
For example, both a 5 stage in-order pipeline and a large out of order CPU implement the same assembly language execution model.
Parallel execution models tend to be complex because they involve multiple timelines.
Parallel execution models necessarily include the behavior of synchronization constructs.
The timeline has a point at which it executes the "gain ownership of the lock" synchronization construct.
Specifically, A-post-give-up-lock and B-post-gain-lock have no relative ordering defined, which surprises many people.
That is one of the possibilities that must be thought about when designing locks, and illustrates why multi-threaded programming is difficult.