Shadowrun: Awakened 29 September 2011 - Build 871
queuing_rw_mutex.h
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 #ifndef __TBB_queuing_rw_mutex_H
00030 #define __TBB_queuing_rw_mutex_H
00031 
00032 #include "tbb_config.h"
00033 
00034 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00035     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
00036     #pragma warning (push)
00037     #pragma warning (disable: 4530)
00038 #endif
00039 
00040 #include <cstring>
00041 
00042 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00043     #pragma warning (pop)
00044 #endif
00045 
00046 #include "atomic.h"
00047 #include "tbb_profiling.h"
00048 
00049 namespace tbb {
00050 
00052 
00055 class queuing_rw_mutex {
00056 public:
00058     queuing_rw_mutex() {
00059         q_tail = NULL;
00060 #if TBB_USE_THREADING_TOOLS
00061         internal_construct();
00062 #endif
00063     }
00064 
00066     ~queuing_rw_mutex() {
00067 #if TBB_USE_ASSERT
00068         __TBB_ASSERT( !q_tail, "destruction of an acquired mutex");
00069 #endif
00070     }
00071 
00072     class scoped_lock;
00073     friend class scoped_lock;
00074 
00076 
00078     class scoped_lock: internal::no_copy {
00080         void initialize() {
00081             mutex = NULL;
00082 #if TBB_USE_ASSERT
00083             state = 0xFF; // Set to invalid state
00084             internal::poison_pointer(next);
00085             internal::poison_pointer(prev);
00086 #endif /* TBB_USE_ASSERT */
00087         }
00088     public:
00090 
00091         scoped_lock() {initialize();}
00092 
00094         scoped_lock( queuing_rw_mutex& m, bool write=true ) {
00095             initialize();
00096             acquire(m,write);
00097         }
00098 
00100         ~scoped_lock() {
00101             if( mutex ) release();
00102         }
00103 
00105         void acquire( queuing_rw_mutex& m, bool write=true );
00106 
00108         bool try_acquire( queuing_rw_mutex& m, bool write=true );
00109 
00111         void release();
00112 
00114 
00115         bool upgrade_to_writer();
00116 
00118         bool downgrade_to_reader();
00119 
00120     private:
00122         queuing_rw_mutex* mutex;
00123 
00125         scoped_lock * prev, * next;
00126 
00127         typedef unsigned char state_t;
00128 
00130         atomic<state_t> state;
00131 
00133 
00134         unsigned char going;
00135 
00137         unsigned char internal_lock;
00138 
00140         void acquire_internal_lock();
00141 
00143 
00144         bool try_acquire_internal_lock();
00145 
00147         void release_internal_lock();
00148 
00150         void wait_for_release_of_internal_lock();
00151 
00153         void unblock_or_wait_on_internal_lock( uintptr_t );
00154     };
00155 
00156     void __TBB_EXPORTED_METHOD internal_construct();
00157 
00158     // Mutex traits
00159     static const bool is_rw_mutex = true;
00160     static const bool is_recursive_mutex = false;
00161     static const bool is_fair_mutex = true;
00162 
00163 private:
00165     atomic<scoped_lock*> q_tail;
00166 
00167 };
00168 
00169 __TBB_DEFINE_PROFILING_SET_NAME(queuing_rw_mutex)
00170 
00171 } // namespace tbb
00172 
00173 #endif /* __TBB_queuing_rw_mutex_H */

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net