Intel® Advisor User Guide

ID 766448
Date 12/16/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Intel® oneAPI Threading Building Blocks (oneTBB) Simple Mutex - Example

The following examples shows basic usage of a Intel® oneAPI Threading Building Blocks (oneTBB) mutex to protect a shared variable named count using simple mutexes and scoped locks:

Simple Mutex Example

#include <tbb/mutex.h>

int count;
tbb::mutex countMutex;

int IncrementCount() {
    int result;
    // Add oneTBB mutex       
    countMutex.lock();     // Implements ANNOTATE_LOCK_ACQUIRE()
    result = count++;      // Save result until after unlock
    countMutex.unlock();   // Implements ANNOTATE_LOCK_RELEASE()
    return result;
}

The semantics of countMutex.lock() and unlock() on countMutex correspond directly to the annotations ANNOTATE_LOCK_ACQUIRE() and ANNOTATE_LOCK_RELEASE(). However, it is generally better to use the scoped locking pattern.

Scoped Lock Example

With a scoped lock, you construct a temporary scoped_lock object that represents acquisition of a lock. Destruction of the scoped_lock object releases the lock on the mutex.

The following code shows the previous example rewritten using scoped locking:

#include <tbb/mutex.h>
int          count;
tbb::mutex   countMutex;

int IncrementCount() {
    int result;
    {
       // Add oneTBB scoped lock at location of ANNOTATE_LOCK annotations
       tbb::mutex::scoped_lock lock(countMutex);  // Implements ANNOTATE_LOCK_ACQUIRE()
       result = count++;
	      // Implicit ANNOTATE_LOCK_RELEASE() when leaving the scope below. 
    }  // scoped lock is automatically released here
    return result;
}

The scoped_lock pattern is preferred because it releases the lock no matter how control leaves the block. The scoped lock is released when destruction of the scoped_lock object occurs. In particular, it releases the lock even when control leaves because an exception was thrown.

oneTBB also has a tbb::atomic template class that can be used in simple cases such as managing a shared integer variable. Check the Related Information for details.