Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | Related Pages

spin_rw_mutex.h

00001 /*
00002     Copyright 2005-2008 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 
00027 namespace tbb {
00028 
00029 class spin_rw_mutex_v3;
00030 typedef spin_rw_mutex_v3 spin_rw_mutex;
00031 
00033 
00034 class spin_rw_mutex_v3 {
00036 
00038     bool internal_acquire_writer();
00039 
00041 
00042     void internal_release_writer();
00043 
00045     void internal_acquire_reader();
00046 
00048     bool internal_upgrade();
00049 
00051 
00052     void internal_downgrade();
00053 
00055     void internal_release_reader();
00056 
00058     bool internal_try_acquire_writer();
00059 
00061     bool internal_try_acquire_reader();
00062 
00064 public:
00066     spin_rw_mutex_v3() : state(0) {}
00067 
00068 #if TBB_DO_ASSERT
00069 
00070     ~spin_rw_mutex_v3() {
00071         __TBB_ASSERT( !state, "destruction of an acquired mutex");
00072     };
00073 #endif /* TBB_DO_ASSERT */
00074 
00076 
00078     class scoped_lock : private internal::no_copy {
00079     public:
00081 
00082         scoped_lock() : mutex(NULL) {}
00083 
00085 
00086         scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) {
00087             acquire(m, write);
00088         }
00089 
00091         ~scoped_lock() {
00092             if( mutex ) release();
00093         }
00094 
00096         void acquire( spin_rw_mutex& m, bool write = true ) {
00097             __TBB_ASSERT( !mutex, "holding mutex already" );
00098             is_writer = write; 
00099             mutex = &m;
00100             if( write ) mutex->internal_acquire_writer();
00101             else        mutex->internal_acquire_reader();
00102         }
00103 
00105 
00106         bool upgrade_to_writer() {
00107             __TBB_ASSERT( mutex, "lock is not acquired" );
00108             __TBB_ASSERT( !is_writer, "not a reader" );
00109             is_writer = true; 
00110             return mutex->internal_upgrade();
00111         }
00112 
00114         void release() {
00115             __TBB_ASSERT( mutex, "lock is not acquired" );
00116             spin_rw_mutex *m = mutex; 
00117             mutex = NULL;
00118 #if TBB_DO_THREADING_TOOLS||TBB_DO_ASSERT
00119             if( is_writer ) m->internal_release_writer();
00120             else            m->internal_release_reader();
00121 #else
00122             if( is_writer ) __TBB_AtomicAND( &m->state, READERS ); 
00123             else            __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER);
00124 #endif /* TBB_DO_THREADING_TOOLS||TBB_DO_ASSERT */
00125         }
00126 
00128         bool downgrade_to_reader() {
00129 #if TBB_DO_THREADING_TOOLS||TBB_DO_ASSERT
00130             __TBB_ASSERT( mutex, "lock is not acquired" );
00131             __TBB_ASSERT( is_writer, "not a writer" );
00132             mutex->internal_downgrade();
00133 #else
00134              __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER));
00135 #endif /* TBB_DO_THREADING_TOOLS||TBB_DO_ASSERT */
00136             is_writer = false;
00137 
00138             return true;
00139         }
00140 
00142         bool try_acquire( spin_rw_mutex& m, bool write = true ) {
00143             __TBB_ASSERT( !mutex, "holding mutex already" );
00144             bool result;
00145             is_writer = write; 
00146             result = write? m.internal_try_acquire_writer()
00147                           : m.internal_try_acquire_reader();
00148             if( result ) 
00149                 mutex = &m;
00150             return result;
00151         }
00152 
00153     private:
00155         spin_rw_mutex* mutex;
00156 
00158 
00159         bool is_writer;
00160     };
00161 
00162     // Mutex traits
00163     static const bool is_rw_mutex = true;
00164     static const bool is_recursive_mutex = false;
00165     static const bool is_fair_mutex = false;
00166 
00167 private:
00168     typedef intptr_t state_t;
00169     static const state_t WRITER = 1;
00170     static const state_t WRITER_PENDING = 2;
00171     static const state_t READERS = ~(WRITER | WRITER_PENDING);
00172     static const state_t ONE_READER = 4;
00173     static const state_t BUSY = WRITER | READERS;
00175 
00178     state_t state;
00179 };
00180 
00181 } // namespace ThreadingBuildingBlocks
00182 
00183 #endif /* __TBB_spin_rw_mutex_H */

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