Lunchbox  1.13.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
lunchbox::SpinLock Class Reference

A fast lock for uncontended memory access. More...

#include <spinLock.h>

+ Inheritance diagram for lunchbox::SpinLock:
+ Collaboration diagram for lunchbox::SpinLock:

Public Member Functions

 SpinLock ()
 Construct a new lock. More...
 
 ~SpinLock ()
 Destruct the lock. More...
 
void set ()
 Acquire the lock exclusively. More...
 
void unset ()
 Release an exclusive lock. More...
 
bool trySet ()
 Attempt to acquire the lock exclusively. More...
 
void setRead ()
 Acquire the lock shared with other readers. More...
 
void unsetRead ()
 Release a shared read lock. More...
 
bool trySetRead ()
 Attempt to acquire the lock shared with other readers. More...
 
bool isSet ()
 Test if the lock is set. More...
 
bool isSetWrite ()
 Test if the lock is set exclusively. More...
 
bool isSetRead ()
 Test if the lock is set shared. More...
 

Detailed Description

A fast lock for uncontended memory access.

If Thread::yield() does not work, priority inversion is possible. If used as a read-write lock, readers or writers will starve on high contention.

See also
ScopedMutex

Example:

/* Copyright (c) 2006-2014, Stefan Eilemann <eile@equalizergraphics.com>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 2.1 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define TEST_RUNTIME 600 // seconds, needed for NighlyMemoryCheck
#include "test.h"
#include <lunchbox/atomic.h>
#include <lunchbox/clock.h>
#include <lunchbox/debug.h>
#include <lunchbox/init.h>
#include <lunchbox/lock.h>
#include <lunchbox/omp.h>
#include <lunchbox/spinLock.h>
#include <lunchbox/timedLock.h>
#include <iostream>
#define MAXTHREADS 256
#define TIME 500 // ms
bool _running = false;
template< class T > class Thread : public lunchbox::Thread
{
public:
Thread() : lock( 0 ), ops( 0 ) {}
T* lock;
size_t ops;
virtual void run()
{
ops = 0;
while( LB_LIKELY( _running ))
{
lock->set();
#ifndef _MSC_VER
TEST( lock->isSet( ));
#endif
lock->unset();
++ops;
}
}
};
template< class T > void _test()
{
T* lock = new T;
lock->set();
#ifdef LUNCHBOX_USE_OPENMP
const size_t nThreads = LB_MIN( lunchbox::OMP::getNThreads() * 3,
MAXTHREADS );
#else
const size_t nThreads = 16;
#endif
Thread< T > threads[MAXTHREADS];
for( size_t i = 1; i <= nThreads; i = i << 1 )
{
_running = true;
for( size_t j = 0; j < i; ++j )
{
threads[j].lock = lock;
TEST( threads[j].start( ));
}
lunchbox::sleep( 10 ); // let threads initialize
_clock.reset();
lock->unset();
lunchbox::sleep( TIME ); // let threads run
_running = false;
for( size_t j = 0; j < i; ++j )
TEST( threads[j].join( ));
const float time = _clock.getTimef();
TEST( !lock->isSet( ));
lock->set();
size_t ops = 0;
for( size_t j = 0; j < nThreads; ++j )
ops += threads[j].ops;
std::cout << std::setw(20) << lunchbox::className( lock ) << ", "
<< std::setw(12) << /*set, test, unset*/ 3 * ops / time
<< ", " << std::setw(3) << i << std::endl;
}
delete lock;
}
int main( int argc, char **argv )
{
TEST( lunchbox::init( argc, argv ));
std::cout << " Class, ops/ms, threads" << std::endl;
_test< lunchbox::SpinLock >();
std::cout << std::endl;
_test< lunchbox::Lock >();
std::cout << std::endl;
_test< lunchbox::TimedLock >();
TEST( lunchbox::exit( ));
return EXIT_SUCCESS;
}

Definition at line 38 of file spinLock.h.

Constructor & Destructor Documentation

lunchbox::SpinLock::SpinLock ( )

Construct a new lock.

Version
1.0
lunchbox::SpinLock::~SpinLock ( )

Destruct the lock.

Version
1.0

Member Function Documentation

bool lunchbox::SpinLock::isSet ( )

Test if the lock is set.

Returns
true if the lock is set, false if it is not set.
Version
1.0
bool lunchbox::SpinLock::isSetRead ( )

Test if the lock is set shared.

Returns
true if the lock is set, false if it is not set.
Version
1.1.2
bool lunchbox::SpinLock::isSetWrite ( )

Test if the lock is set exclusively.

Returns
true if the lock is set, false if it is not set.
Version
1.1.2
void lunchbox::SpinLock::set ( )

Acquire the lock exclusively.

Version
1.0
void lunchbox::SpinLock::setRead ( )

Acquire the lock shared with other readers.

Version
1.1.2
bool lunchbox::SpinLock::trySet ( )

Attempt to acquire the lock exclusively.

Returns
true if the lock was set, false if it was not set.
Version
1.0
bool lunchbox::SpinLock::trySetRead ( )

Attempt to acquire the lock shared with other readers.

Returns
true if the lock was set, false if it was not set.
Version
1.1.2
void lunchbox::SpinLock::unset ( )

Release an exclusive lock.

Version
1.0
void lunchbox::SpinLock::unsetRead ( )

Release a shared read lock.

Version
1.1.2

The documentation for this class was generated from the following file: