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-2011 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 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00134             __TBB_ASSERT( mutex, "lock is not acquired" );
    00135             __TBB_ASSERT( is_writer, "not a writer" );
    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
    00142             return true;
    00143         }
    00144
    00146         bool try_acquire( spin_rw_mutex& m, bool write = true ) {
    00147             __TBB_ASSERT( !mutex, "holding mutex already" );
    00148             bool result;
    00149             is_writer = write;
    00150             result = write? m.internal_try_acquire_writer()
    00151                           : m.internal_try_acquire_reader();
    00152             if( result )
    00153                 mutex = &m;
    00154             return result;
    00155         }
    00156
    00157     protected:
    00159         spin_rw_mutex* mutex;
    00160
    00162
    00163         bool is_writer;
    00164     };
    00165
    00166     // Mutex traits
    00167     static const bool is_rw_mutex = true;
    00168     static const bool is_recursive_mutex = false;
    00169     static const bool is_fair_mutex = false;
    00170
    00171     // ISO C++0x compatibility methods
    00172
    00174     void lock() {internal_acquire_writer();}
    00175
    00177
    00178     bool try_lock() {return internal_try_acquire_writer();}
    00179
    00181     void unlock() {
    00182 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00183         if( state&WRITER ) internal_release_writer();
    00184         else               internal_release_reader();
    00185 #else
    00186         if( state&WRITER ) __TBB_AtomicAND( &state, READERS );
    00187         else               __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER);
    00188 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
    00189     }
    00190
    00191     // Methods for reader locks that resemble ISO C++0x compatibility methods.
    00192
    00194     void lock_read() {internal_acquire_reader();}
    00195
    00197
    00198     bool try_lock_read() {return internal_try_acquire_reader();}
    00199
    00200 private:
    00201     typedef intptr_t state_t;
    00202     static const state_t WRITER = 1;
    00203     static const state_t WRITER_PENDING = 2;
    00204     static const state_t READERS = ~(WRITER | WRITER_PENDING);
    00205     static const state_t ONE_READER = 4;
    00206     static const state_t BUSY = WRITER | READERS;
    00208
    00211     state_t state;
    00212
    00213     void __TBB_EXPORTED_METHOD internal_construct();
    00214 };
    00215
    00216 __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex)
    00217
    00218 } // namespace tbb
    00219
    00220 #endif /* __TBB_spin_rw_mutex_H */

Copyright © 2005-2011 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.