critical_section.h

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002      Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 // -*- mode:c++; c-basic-offset:4 -*-
00025 /*<std-header orig-src='shore' incl-file-exclusion='STHREAD_H'>
00026 
00027  $Id: critical_section.h,v 1.1 2010/12/09 15:20:17 nhall Exp $
00028 
00029 SHORE -- Scalable Heterogeneous Object REpository
00030 
00031 Copyright (c) 1994-99 Computer Sciences Department, University of
00032                       Wisconsin -- Madison
00033 All Rights Reserved.
00034 
00035 Permission to use, copy, modify and distribute this software and its
00036 documentation is hereby granted, provided that both the copyright
00037 notice and this permission notice appear in all copies of the
00038 software, derivative works or modified versions, and any portions
00039 thereof, and that both notices appear in supporting documentation.
00040 
00041 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00042 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00043 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00044 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00045 
00046 This software was developed with support by the Advanced Research
00047 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00048 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00049 Further funding for this work was provided by DARPA through
00050 Rome Research Laboratory Contract No. F30602-97-2-0247.
00051 
00052 */
00053 
00054 /*  -- do not edit anything above this line --   </std-header>*/
00055 
00056 #ifndef CRIT_SEC_H
00057 #define CRIT_SEC_H
00058 
00059 /**\def CRITICAL_SECTION(name, lock)
00060  *
00061  * This macro starts a critical section protected by the given lock
00062  * (2nd argument).  The critical_section structure it creates is
00063  * named by the 1st argument.
00064  * The rest of the scope (in which this macro is used) becomes the
00065  * scope of the critical section, since it is the destruction of this
00066  * critical_section structure that releases the lock.
00067  *
00068  * The programmer can release the lock early by calling <name>.pause()
00069  * or <name>.exit().
00070  * The programmer can reacquire the lock by calling <name>.resume() if
00071  * <name>.pause() was called, but not after <name>.exit().
00072  *
00073  * \sa critical_section
00074  */
00075 #define CRITICAL_SECTION(name, lock) critical_section<__typeof__(lock)&> name(lock)
00076 
00077 template<class Lock>
00078 struct critical_section;
00079 
00080 /**\brief Helper class for CRITICAL_SECTION idiom (macro).
00081  *
00082  * This templated class does nothing; its various specializations 
00083  * do the work of acquiring the given lock upon construction and
00084  * releasing it upon destruction. 
00085  * See the macros:
00086  * - SPECIALIZE_CS(Lock, Extra, ExtraInit, Acquire, Release)  
00087  * - CRITICAL_SECTION(name, lock) 
00088  */
00089 template<class Lock>
00090 struct critical_section<Lock*&> : public critical_section<Lock&> {
00091     critical_section<Lock*&>(Lock* mutex) : critical_section<Lock&>(*mutex) { }
00092 };
00093 
00094 /*
00095  * NOTE: I added ExtraInit to make the initialization happen so that
00096  * assertions about holding the mutex don't fail.
00097  * At the same time, I added a holder to the w_pthread_lock_t
00098  * implementation so I could make assertions about the holder outside
00099  * the lock implementation itself.  This might seem like doubly
00100  * asserting, but in the cases where the critical section isn't
00101  * based on a pthread mutex, we really should have this clean
00102  * initialization and the check the assertions.
00103  */
00104 
00105 /**\def SPECIALIZE_CS(Lock, Extra, ExtraInit, Acquire, Release) 
00106  * \brief Macro that enables use of CRITICAL_SECTION(name,lock)
00107  *\addindex SPECIALIZE_CS
00108  * 
00109  * \details
00110  * Create a templated class that holds 
00111  *   - a reference to the given lock and
00112  *   - the Extra (2nd macro argument)
00113  *
00114  *  and it
00115  *   - applies the ExtraInit and Acquire commands upon construction,
00116  *   - applies the Release command upon destruction.
00117  *
00118  */
00119 #define SPECIALIZE_CS(Lock,Extra,ExtraInit,Acquire,Release) \
00120 template<>  struct critical_section<Lock&> { \
00121 critical_section(Lock &mutex) \
00122     : _mutex(&mutex)          \
00123     {   ExtraInit; Acquire; } \
00124     ~critical_section() {     \
00125         if(_mutex)            \
00126             Release;          \
00127             _mutex = NULL;    \
00128         }                     \
00129     void pause() { Release; } \
00130     void resume() { Acquire; }\
00131     void exit() { Release; _mutex = NULL; } \
00132     Lock &hand_off() {        \
00133         Lock* rval = _mutex;  \
00134         _mutex = NULL;        \
00135         return *rval;         \
00136     }                         \
00137 private:                      \
00138     Lock* _mutex;             \
00139     Extra;                    \
00140     void operator=(critical_section const &);   \
00141     critical_section(critical_section const &); \
00142 }
00143 
00144 
00145 // I undef-ed this and found all occurrances of CRITICAL_SECTION with this.
00146 // and hand-checked them.
00147 SPECIALIZE_CS(pthread_mutex_t, int _dummy,  (_dummy=0), 
00148     pthread_mutex_lock(_mutex), pthread_mutex_unlock(_mutex));
00149 
00150 
00151 #endif          /*</std-footer>*/

Generated on Thu Dec 9 08:42:27 2010 for Shore Storage Manager by  doxygen 1.4.7