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

- File List
- File Members

# critical_section.h

    00001 /*
    00002     Copyright 2005-2012 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_CRITICAL_SECTION_H_
    00030 #define _TBB_CRITICAL_SECTION_H_
    00031
    00032 #if _WIN32||_WIN64
    00033 #include "machine/windows_api.h"
    00034 #else
    00035 #include <pthread.h>
    00036 #include <errno.h>
    00037 #endif  // _WIN32||WIN64
    00038
    00039 #include "tbb_stddef.h"
    00040 #include "tbb_thread.h"
    00041 #include "tbb_exception.h"
    00042
    00043 #include "tbb_profiling.h"
    00044
    00045 namespace tbb {
    00046
    00047     namespace internal {
    00048 class critical_section_v4 : internal::no_copy {
    00049 #if _WIN32||_WIN64
    00050     CRITICAL_SECTION my_impl;
    00051 #else
    00052     pthread_mutex_t my_impl;
    00053 #endif
    00054     tbb_thread::id my_tid;
    00055 public:
    00056
    00057     void __TBB_EXPORTED_METHOD internal_construct();
    00058
    00059     critical_section_v4() {
    00060 #if _WIN32||_WIN64
    00061         InitializeCriticalSectionEx( &my_impl, 4000, 0 );
    00062 #else
    00063         pthread_mutex_init(&my_impl, NULL);
    00064 #endif
    00065         internal_construct();
    00066     }
    00067
    00068     ~critical_section_v4() {
    00069         __TBB_ASSERT(my_tid == tbb_thread::id(), "Destroying a still-held critical section");
    00070 #if _WIN32||_WIN64
    00071         DeleteCriticalSection(&my_impl);
    00072 #else
    00073         pthread_mutex_destroy(&my_impl);
    00074 #endif
    00075     }
    00076
    00077     class scoped_lock : internal::no_copy {
    00078     private:
    00079         critical_section_v4 &my_crit;
    00080     public:
    00081         scoped_lock( critical_section_v4& lock_me) :my_crit(lock_me) {
    00082             my_crit.lock();
    00083         }
    00084
    00085         ~scoped_lock() {
    00086             my_crit.unlock();
    00087         }
    00088     };
    00089
    00090     void lock() {
    00091         tbb_thread::id local_tid = this_tbb_thread::get_id();
    00092         if(local_tid == my_tid) throw_exception( eid_improper_lock );
    00093 #if _WIN32||_WIN64
    00094         EnterCriticalSection( &my_impl );
    00095 #else
    00096         int rval = pthread_mutex_lock(&my_impl);
    00097         __TBB_ASSERT_EX(!rval, "critical_section::lock: pthread_mutex_lock failed");
    00098 #endif
    00099         __TBB_ASSERT(my_tid == tbb_thread::id(), NULL);
    00100         my_tid = local_tid;
    00101     }
    00102
    00103     bool try_lock() {
    00104         bool gotlock;
    00105         tbb_thread::id local_tid = this_tbb_thread::get_id();
    00106         if(local_tid == my_tid) return false;
    00107 #if _WIN32||_WIN64
    00108         gotlock = TryEnterCriticalSection( &my_impl ) != 0;
    00109 #else
    00110         int rval = pthread_mutex_trylock(&my_impl);
    00111         // valid returns are 0 (locked) and [EBUSY]
    00112         __TBB_ASSERT(rval == 0 || rval == EBUSY, "critical_section::trylock: pthread_mutex_trylock failed");
    00113         gotlock = rval == 0;
    00114 #endif
    00115         if(gotlock)  {
    00116             my_tid = local_tid;
    00117         }
    00118         return gotlock;
    00119     }
    00120
    00121     void unlock() {
    00122         __TBB_ASSERT(this_tbb_thread::get_id() == my_tid, "thread unlocking critical_section is not thread that locked it");
    00123         my_tid = tbb_thread::id();
    00124 #if _WIN32||_WIN64
    00125         LeaveCriticalSection( &my_impl );
    00126 #else
    00127         int rval = pthread_mutex_unlock(&my_impl);
    00128         __TBB_ASSERT_EX(!rval, "critical_section::unlock: pthread_mutex_unlock failed");
    00129 #endif
    00130     }
    00131
    00132     static const bool is_rw_mutex = false;
    00133     static const bool is_recursive_mutex = false;
    00134     static const bool is_fair_mutex = true;
    00135 }; // critical_section_v4
    00136 } // namespace internal
    00137 typedef internal::critical_section_v4 critical_section;
    00138
    00139 __TBB_DEFINE_PROFILING_SET_NAME(critical_section)
    00140 } // namespace tbb
    00141 #endif  // _TBB_CRITICAL_SECTION_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.