[For complete, up-to-date TBB information visit: http://www.ThreadingBuildingBlocks.org]

TbbRef (Ver. 20): 6.1 Mutexes

6.1 Mutexes

Mutexes provide MUTual EXclusion of threads from sections of code.

In general, strive for designs that minimize the use of explicit locking, because it can lead to serial bottlenecks. If explicitly locking is necessary, try to spread it out so that multiple threads usually do not contend to lock the same mutex.

6.1.1 Mutex Concept

The mutexes and locks here have relatively spartan interfaces that are designed for high performance. The interfaces enforce the scoped locking pattern, which is widely used in C++ libraries because:

1. Does not require the programmer to remember to release the lock

2. Releases the lock if an exception is thrown out of the mutual exclusion region protected by the lock

There are two parts to the pattern: a mutex object, for which construction of a lock object acquires a lock on the mutex and destruction of the lock object releases the lock. Here’s an example:

{

// Construction of myLock acquires lock on myMutex

M::scoped_lock myLock( myMutex );

... actions to be performed while holding the lock ...

// Destruction of myLock releases lock on myMutex

}

If the actions throw an exception, the lock is automatically released as the block is exited.

Table 19 shows the requirements for the Mutex concept for a mutex type M

Header

#include "tbb/queuing_mutex.h"

Description

A queuing_mutex models the Mutex Concept ( 6.1.1). A queuing_mutex is scalable, in the sense that if a thread has to wait to acquire the mutex, it spins on its own local cache line. A queuing_mutex is fair. Threads acquire a lock on a mutex in the order that they request it. A queuing_mutex is not reentrant.

The current implementation does busy-waiting, so using a queuing_mutex may degrade system performance if the wait is long.

Members

See Mutex Concept ( 6.1.1).

6.1.5 ReaderWriterMutex Concept

The ReaderWriterMutex concept extends the Mutex concept to include the notion of reader-writer locks. It introduces a boolean parameter write that specifies whether a writer lock (write =true) or reader lock (write =false) is being requested. Multiple reader locks can be held simultaneously on a ReaderWriterMutex if it does not have a writer lock on it. A writer lock on a ReaderWriterMutex excludes all other threads from holding a lock on the mutex at the same time.

Table 21 shows the requirements for ReaderWriterMutex RW.

Table 21: ReaderWriterMutex Concept

Pseudo-Signature

Semantics

RW()

Construct unlocked mutex

~RW()

Destroy unlocked mutex

typename RW::scoped_lock

Corresponding scoped-lock type

RW::scoped_lock()

Construct lock without acquiring mutex

RW::scoped_lock(RW&, bool write=true)

Construct lock and acquire lock on mutex

RW::~scoped_lock()

Release lock (if acquired)

RW::scoped_lock::acquire(RW&, bool write=true)

Acquire lock on mutex

bool RW::scoped_lock::try_acquire(RW&, bool write=true)

Try to acquire lock on mutex. Return true if lock acquired, false otherwise.

RW::scoped_lock::release()

Release lock

bool RW::scoped_lock::upgrade_to_writer()

Change reader lock to writer lock

bool RW::scoped_lock::downgrade_to_reader()

Change writer lock to reader lock

The following subsections explain the semantics of the ReaderWriterMutex concept in detail.

Model Types

spin_rw_mutex ( 6.1.6) and queuing_rw_mutex ( 6.1.7) model the ReaderWriterMutex concept.

6.1.5.1 ReaderWriterMutex()

Effect

Construct unlocked ReaderWriterMutex.

6.1.5.2 ~ReaderWriterMutex()

Effect

Destroy unlocked ReaderWriterMutex. The effect of destroying a locked ReaderWriterMutex is undefined.

6.1.5.3 ReaderWriterMutex::scoped_lock()

Effect

Construct a scoped_lock object that does not hold a lock on any mutex.

6.1.5.4 ReaderWriterMutex::scoped_lock( ReaderWriterMutex& rw, bool write =true)

Effect

Construct a scoped_lock object that acquires a lock on mutex rw. The lock is a writer lock if write is true; a reader lock otherwise.

6.1.5.5 ReaderWriterMutex::~scoped_lock()

Effect

If the object holds a lock on a ReaderWriterMutex, release the lock.

6.1.5.6 void ReaderWriterMutex:: scoped_lock:: acquire( ReaderWriterMutex& rw, bool write=true )

Effect

Acquires a lock on mutex rw. The lock is a writer lock if write is true; a reader lock otherwise.

6.1.5.7 bool ReaderWriterMutex:: scoped_lock::try_acquire( ReaderWriterMutex& rw, bool write=true )

Effect

Attempts to acquire a lock on mutex rw. The lock is a writer lock if write is true; a reader lock otherwise.

Returns

true if the lock is acquired, false otherwise.

6.1.5.8 void ReaderWriterMutex:: scoped_lock::release()

Effect

Release lock. The effect is undefined if no lock is held.

6.1.5.9 bool ReaderWriterMutex:: scoped_lock::upgrade_to_writer()

Effect

Change reader lock to a writer lock. The effect is undefined if the object does not already hold a reader lock.

Returns

false if lock was released and reacquired; true otherwise.

6.1.5.10 bool ReaderWriterMutex:: scoped_lock::downgrade_to_reader()

Effect

Change writer lock to a reader lock. The effect is undefined if the object does not already hold a writer lock.

Returns

false if lock was released and reacquired; true otherwise.

NOTE: Intel's current implementations for spin_rw_mutex and queuing_rw_mutex always return true. Different implementations might sometimes return false.

6.1.6 spin_rw_mutex Class

Summary

Class that models ReaderWriterMutex Concept that is unfair and not scalable.

Syntax

class spin_rw_mutex;

Header

#include "tbb/spin_rw_mutex.h"

Description

A spin_rw_mutex models the ReaderWriterMutex Concept ( 6.1.1). A spin_rw_mutex is not scalable, fair, or reentrant. It is ideal when the lock is lightly contended and is held for only a few machine instructions. If a thread has to wait to acquire a spin_rw_mutex, it busy waits, which can degrade system performance if the wait is long. However, if the wait is typically short, a spin_rw_mutex significantly improve performance compared to other mutexes..

Members

See ReaderWriterMutex concept ( 6.1.5).

6.1.7 queuing_rw_mutex Class

Summary

Class that models ReaderWriterMutex Concept that is fair and scalable.

Syntax

class queuing_rw_mutex;

Header

#include "tbb/queuing_rw_mutex.h"

Description

A queuing_rw_mutex models the ReaderWriterMutex Concept ( 6.1.1). A queuing_rw_mutex is scalable, in the sense that if a thread has to wait to acquire the mutex, it spins on its own local cache line. A queuing_rw_mutex is fair. Threads acquire a lock on a queuing_rw_mutex in the order that they request it. A queuing_rw_mutex is not reentrant.

Members

See ReaderWriterMutex concept ( 6.1.5).

[For complete, up-to-date TBB information visit: http://www.ThreadingBuildingBlocks.org]