Software transactional memory
1 / 24

Software Transactional Memory - PowerPoint PPT Presentation

  • Uploaded on

Software Transactional Memory. How D can make concurrent programming a piece of cake Bartosz Milewski D Programming Language. Obvious Things. Multi-Core is here to stay Programmers must use concurrency (Dead-) Lock Oriented Programming is BAD New paradigm badly needed. The Problem.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Software Transactional Memory' - victoria

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Software transactional memory l.jpg

Software Transactional Memory

How D can make concurrent programming a piece of cake

Bartosz Milewski

D Programming Language

Obvious things l.jpg
Obvious Things

  • Multi-Core is here to stay

  • Programmers must use concurrency

  • (Dead-) Lock Oriented Programming is BAD

  • New paradigm badly needed

The problem l.jpg
The Problem

void Toggle ()


if (x == 0)

x = 1;


x = 0;


  • Fetch value of x

  • Store it in a temporary

  • Compare with zero

  • Based on the result, write new value

What if, in the meanwhile, the original x was modified by another thread?

Write is based on incorrect assumption!

Logically speaking l.jpg
Logically Speaking

  • Theorem:

    • Hypothesis: x == 0 (read x, compare to 0)

    • Conclusion: x = 1 (write 1 into x)

  • Problem: Hypothesis invalidated before conclusion reached

  • Must re-check the hypothesis before writing!

Transaction l.jpg

  • Delay checking: Log read values for later

  • Must re-check before writing: Log the “intent to write” (speculative writes) for later execution

  • Verify hypothesis : Are read values unchanged?

  • Reach conclusion: Execute writes from log to memory

What does it buy us l.jpg
What Does It Buy Us?

  • Concurrency issues postponed to the commit phase (read-check and write)

  • Commit uses generic code, which can be optimized and tested once for all

  • User code simple, less error-prone—code as if there were a single global lock

  • Increased concurrency—executes as if every word were separately locked

  • No deadlocks!

Stm in a nutshell l.jpg
STM in a Nutshell

  • Start a transaction: create log

  • Speculative execution—reads and writes logged

  • Commit phase (atomic)

    • Read-check

    • Write to memory

  • If failure, restart transaction

Composability l.jpg

  • Combining atomic operations using locks—almost impossible!

  • Atomic (transacted) withdrawalatomic { acc.Withdraw (sum); }

  • Atomic deposit—similar

  • Atomic transferatomic {accOne.Withdraw (sum);accTwo.Deposit (sum);}

Blocking transactions l.jpg
Blocking Transactions

  • Example: Producer/Consumer



Item * item = pcQueue.Get ();


Item * Get () atomic // PCQueue method


if (_queue.Count () == 0)



return _queue.pop_front ();


Retry l.jpg

  • Restart transaction without destroying the log

  • Make the read-log globally available

  • Block until any of the logged read locations changes

  • Every commit checks the read-sets of blocked transactions and unblocks the ones that overlap with its write-set

The beauty of retry l.jpg
The Beauty of Retry

  • Consumer doesn’t have to specify what it’s waiting for

  • Producer doesn’t have to signal anybody

  • Composability: Wait for two items



item1 = pcQueue.Get ();

item2 = pcQueue.Get ();


Object based stm l.jpg
Object-Based STM

  • Transactable (atomic) objects

    • Visible as opaque handles

    • Can be opened only inside transaction

    • Open (for read) returns a const pointer to the actual object

    • Open for write clones the object and returns pointer to the clone

atomic struct Foo { int x; }

atomic Foo f (new Foo); // an opaque handle

atomic { // start transaction

Foo * foo = f.open_write ();



Cloning l.jpg

  • Deep copy of the object

  • Embedded atomic handles are copied but not the objects they refer to

  • Transactable data structures build from small atomic objects (tree from nodes)

  • Value-semantic objects (e.g. structs) cloned by copy construction

Type system support l.jpg
Type System Support

  • Struct or class marked as “atomic”—all methods (except constructor) “atomic”

  • Open and open_write can be called only inside a transaction—i.e. from inside:

    • Atomic block

    • Atomic function/method

  • Atomic function/method may only be called from inside a transaction

Singly linked list l.jpg
Singly-Linked List

struct Slist // not atomic


this () {

// Insert sentinels

SNode * last = new SNode (Infin, null);

_head = new SNode (MinusInfin, last);


// atomic methods

const (SNode) * Head () const atomic


retrun ();


void Insert (int i) atomic;

void Remove (int i) atomic;


atomic SNode _head; // atomic handle


Slide16 l.jpg

struct SNode atomic



this (int i, const (SNode) * next) {

_val = i; _next = next;


// atomic methods (by default)

int Value () const { return _val; }

const (SNode) * Next () const {

return ();


Snode * SetNext (const (SNode) * next) {

SNode * self = this.open_write ()

self._next = next;

return self;



int _val;

atomic Snode _next;


Insert l.jpg

atomic { myList.Insert (x); } // transactioned

void Insert (int i) atomic


const (SNode) * prev = Head (); // sentinel

const (SNode) * cur = prev.Next ();

while (cur._val < i)


prev = cur;

cur = prev.Next ();


assert (cur != 0); // at worst high sentinel

SNode * newNode = new SNode (i, cur);

(void) prev.SetNext (newNode);


Implementation l.jpg

  • Versioning and Locking

    • Global Version Clock (always even)

    • Version numbers always increase

    • (Hidden) version/lock word per atomic object (lock is the lowest bit)

  • Consistent Snapshot maintenance

    • Version checks when opening an object

    • Read-check during commit

Consistent snapshot l.jpg
Consistent Snapshot

  • Transaction starts by reading Version Clock into the transaction’s read-version variable

  • Open object

    • Check the object lock (bit). If taken, abort

    • Check object version number. If it’s greater than read-version abort

Logging l.jpg

  • Every open is recorded in read-log

    • Pointer to original object (from which its version lock can be retrieved)

  • Every open_write is recorded in read-log and write_log

    • Pointer to original object

    • Pointer to clone

  • Okay to call open_write after open (read)

Commit l.jpg

  • Lock all objects recorded in the write-log

    • Bounded spinlock on each version lock

  • Increment global Version Clock—store as transaction’s write-version

  • Sequence Point (if transaction commits, that’s when it “happened”)

  • Read-check

    • Re-check object version numbers against read-version

Commit writes l.jpg
Commit Writes

  • For each location in the write-log

    • Swap the clone in place of original

    • Stamp it with write-version

    • Unlock

D work l.jpg
D Work

  • We have C implementation (Brad Roberts’ port of GPL’d Dice, Shalev, and Shalit)

  • Write D implementation

  • Modify type system

Bibliography l.jpg

  • Dave Dice, Ori Shalev, and Nir Shavit. Transactional Locking II

  • Tim Harris, Simon Marlow, Simon Peyton Jones, and Maurice Herlihy. Composable Memory Transactions. ACM Conference on Principles and Practice of Parallel Programming 2005 (PPoPP'05). 2005.