spin_rw_mutex.h Source File

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# spin_rw_mutex.h

    00001 /*
    00002     Copyright 2005-2012 Intel Corporation.  All Rights Reserved.
    00003
    00004     The source code contained or described herein and all documents related
    00005     to the source code ("Material") are owned by Intel Corporation or its
    00006     suppliers or licensors.  Title to the Material remains with Intel
    00007     Corporation or its suppliers and licensors.  The Material is protected
    00008     by worldwide copyright laws and treaty provisions.  No part of the
    00009     Material may be used, copied, reproduced, modified, published, uploaded,
    00010     posted, transmitted, distributed, or disclosed in any way without
    00011     Intel's prior express written permission.
    00012
    00013     No license under any patent, copyright, trade secret or other
    00014     intellectual property right is granted to or conferred upon you by
    00015     disclosure or delivery of the Materials, either expressly, by
    00016     implication, inducement, estoppel or otherwise.  Any license under such
    00017     intellectual property rights must be express and approved by Intel in
    00018     writing.
    00019 */
    00020
    00021 #ifndef __TBB_spin_rw_mutex_H
    00022 #define __TBB_spin_rw_mutex_H
    00023
    00024 #include "tbb_stddef.h"
    00025 #include "tbb_machine.h"
    00026 #include "tbb_profiling.h"
    00027
    00028 namespace tbb {
    00029
    00030 class spin_rw_mutex_v3;
    00031 typedef spin_rw_mutex_v3 spin_rw_mutex;
    00032
    00034
    00035 class spin_rw_mutex_v3 {
    00037
    00039     bool __TBB_EXPORTED_METHOD internal_acquire_writer();
    00040
    00042
    00043     void __TBB_EXPORTED_METHOD internal_release_writer();
    00044
    00046     void __TBB_EXPORTED_METHOD internal_acquire_reader();
    00047
    00049     bool __TBB_EXPORTED_METHOD internal_upgrade();
    00050
    00052
    00053     void __TBB_EXPORTED_METHOD internal_downgrade();
    00054
    00056     void __TBB_EXPORTED_METHOD internal_release_reader();
    00057
    00059     bool __TBB_EXPORTED_METHOD internal_try_acquire_writer();
    00060
    00062     bool __TBB_EXPORTED_METHOD internal_try_acquire_reader();
    00063
    00065 public:
    00067     spin_rw_mutex_v3() : state(0) {
    00068 #if TBB_USE_THREADING_TOOLS
    00069         internal_construct();
    00070 #endif
    00071     }
    00072
    00073 #if TBB_USE_ASSERT
    00075     ~spin_rw_mutex_v3() {
    00076         __TBB_ASSERT( !state, "destruction of an acquired mutex");
    00077     };
    00078 #endif /* TBB_USE_ASSERT */
    00079
    00081
    00083     class scoped_lock : internal::no_copy {
    00084     public:
    00086
    00087         scoped_lock() : mutex(NULL), is_writer(false) {}
    00088
    00090         scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) {
    00091             acquire(m, write);
    00092         }
    00093
    00095         ~scoped_lock() {
    00096             if( mutex ) release();
    00097         }
    00098
    00100         void acquire( spin_rw_mutex& m, bool write = true ) {
    00101             __TBB_ASSERT( !mutex, "holding mutex already" );
    00102             is_writer = write;
    00103             mutex = &m;
    00104             if( write ) mutex->internal_acquire_writer();
    00105             else        mutex->internal_acquire_reader();
    00106         }
    00107
    00109
    00110         bool upgrade_to_writer() {
    00111             __TBB_ASSERT( mutex, "lock is not acquired" );
    00112             __TBB_ASSERT( !is_writer, "not a reader" );
    00113             is_writer = true;
    00114             return mutex->internal_upgrade();
    00115         }
    00116
    00118         void release() {
    00119             __TBB_ASSERT( mutex, "lock is not acquired" );
    00120             spin_rw_mutex *m = mutex;
    00121             mutex = NULL;
    00122 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00123             if( is_writer ) m->internal_release_writer();
    00124             else            m->internal_release_reader();
    00125 #else
    00126             if( is_writer ) __TBB_AtomicAND( &m->state, READERS );
    00127             else            __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER);
    00128 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
    00129         }
    00130
    00132         bool downgrade_to_reader() {
    00133             __TBB_ASSERT( mutex, "lock is not acquired" );
    00134             __TBB_ASSERT( is_writer, "not a writer" );
    00135 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00136             mutex->internal_downgrade();
    00137 #else
    00138             __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER));
    00139 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
    00140             is_writer = false;
    00141             return true;
    00142         }
    00143
    00145         bool try_acquire( spin_rw_mutex& m, bool write = true ) {
    00146             __TBB_ASSERT( !mutex, "holding mutex already" );
    00147             bool result;
    00148             is_writer = write;
    00149             result = write? m.internal_try_acquire_writer()
    00150                           : m.internal_try_acquire_reader();
    00151             if( result )
    00152                 mutex = &m;
    00153             return result;
    00154         }
    00155
    00156     protected:
    00158         spin_rw_mutex* mutex;
    00159
    00161
    00162         bool is_writer;
    00163     };
    00164
    00165     // Mutex traits
    00166     static const bool is_rw_mutex = true;
    00167     static const bool is_recursive_mutex = false;
    00168     static const bool is_fair_mutex = false;
    00169
    00170     // ISO C++0x compatibility methods
    00171
    00173     void lock() {internal_acquire_writer();}
    00174
    00176
    00177     bool try_lock() {return internal_try_acquire_writer();}
    00178
    00180     void unlock() {
    00181 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00182         if( state&WRITER ) internal_release_writer();
    00183         else               internal_release_reader();
    00184 #else
    00185         if( state&WRITER ) __TBB_AtomicAND( &state, READERS );
    00186         else               __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER);
    00187 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
    00188     }
    00189
    00190     // Methods for reader locks that resemble ISO C++0x compatibility methods.
    00191
    00193     void lock_read() {internal_acquire_reader();}
    00194
    00196
    00197     bool try_lock_read() {return internal_try_acquire_reader();}
    00198
    00199 private:
    00200     typedef intptr_t state_t;
    00201     static const state_t WRITER = 1;
    00202     static const state_t WRITER_PENDING = 2;
    00203     static const state_t READERS = ~(WRITER | WRITER_PENDING);
    00204     static const state_t ONE_READER = 4;
    00205     static const state_t BUSY = WRITER | READERS;
    00207
    00210     state_t state;
    00211
    00212     void __TBB_EXPORTED_METHOD internal_construct();
    00213 };
    00214
    00215 __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex)
    00216
    00217 } // namespace tbb
    00218
    00219 #endif /* __TBB_spin_rw_mutex_H */

Copyright © 2005-2012 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.