critical_section.h Source File

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

- File List
- File Members

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