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

base/Threads

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2001 by Andrei Alexandrescu
00003 
00004   This file is a derivative of a file from the Loki Library written by
00005   Andrei Alexandrescu.  It was distributed by him under the terms
00006   listed below (titled Loki Original Distribution Terms).
00007   In accordance with the terms, this distribution contains the copyright
00008   notice here and the copyright notice and permission notice
00009   in supporting documentation.  The terms do *not* require
00010   redistribution under those same terms.  This code is distributed
00011   to you under the terms of the GNU General Public License (GPL) 
00012   below.  The GPL does not require you to maintain the terms of
00013   the Loki Original Distribution Terms, but you are encouraged to do so.
00014 
00015   This program/file is free software; you can redistribute it and/or modify
00016   it under the terms of the GNU General Public License as published by
00017   the Free Software Foundation; either version 2 of the License, or
00018   (at your option) any later version.
00019   
00020   This program is distributed in the hope that it will be useful,
00021   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023   GNU General Public License for more details. (http://www.gnu.org)
00024   
00025   You should have received a copy of the GNU General Public License
00026   along with this program; if not, write to the Free Software
00027   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028   
00029  ****************************************************************************
00030   Loki Original Distribution Terms:
00031 
00032   The Loki Library
00033   Copyright (c) 2001 by Andrei Alexandrescu
00034   This code accompanies the book:
00035   Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
00036       Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00037   Permission to use, copy, modify, distribute and sell this software for any 
00038       purpose is hereby granted without fee, provided that the above copyright 
00039       notice appear in all copies and that both that copyright notice and this 
00040       permission notice appear in supporting documentation.
00041   The author or Addison-Welsey Longman make no representations about the 
00042       suitability of this software for any purpose. It is provided "as is" 
00043       without express or implied warranty.
00044  ****************************************************************************
00045 
00046   $Id: Threads 1029 2004-02-11 20:45:54Z jungd $
00047   $Revision: 1.1 $
00048   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00049   $Author: jungd $
00050  
00051 ****************************************************************************/
00052 
00053 #ifndef THREADS_H_
00054 #define THREADS_H_
00055 
00056 ////////////////////////////////////////////////////////////////////////////////
00057 // macro DEFAULT_THREADING
00058 // Selects the default threading model for certain components of Loki
00059 // If you don't define it, it defaults to single-threaded
00060 // All classes in Loki have configurable threading model; DEFAULT_THREADING
00061 // affects only default template arguments
00062 ////////////////////////////////////////////////////////////////////////////////
00063 
00064 // Last update: June 20, 2001
00065 
00066 #ifndef DEFAULT_THREADING
00067 #define DEFAULT_THREADING /**/ ::base::SingleThreaded
00068 #endif
00069 
00070 namespace base
00071 {
00072 ////////////////////////////////////////////////////////////////////////////////
00073 // class template SingleThreaded
00074 // Implementation of the ThreadingModel policy used by various classes
00075 // Implements a single-threaded model; no synchronization
00076 ////////////////////////////////////////////////////////////////////////////////
00077 
00078     template <class Host>
00079     class SingleThreaded
00080     {
00081     public:
00082         struct Lock
00083         {
00084             Lock() {}
00085             Lock(const Host&) {}
00086         };
00087         
00088         typedef Host VolatileType;
00089 
00090         typedef int IntType; 
00091 
00092         static IntType AtomicAdd(volatile IntType& lval, IntType val)
00093         { return lval += val; }
00094         
00095         static IntType AtomicSubtract(volatile IntType& lval, IntType val)
00096         { return lval -= val; }
00097 
00098         static IntType AtomicMultiply(volatile IntType& lval, IntType val)
00099         { return lval *= val; }
00100         
00101         static IntType AtomicDivide(volatile IntType& lval, IntType val)
00102         { return lval /= val; }
00103         
00104         static IntType AtomicIncrement(volatile IntType& lval)
00105         { return ++lval; }
00106         
00107         static IntType AtomicDivide(volatile IntType& lval)
00108         { return --lval; }
00109         
00110         static void AtomicAssign(volatile IntType & lval, IntType val)
00111         { lval = val; }
00112         
00113         static void AtomicAssign(IntType & lval, volatile IntType & val)
00114         { lval = val; }
00115     };
00116     
00117 #ifdef _WINDOWS_
00118 
00119 ////////////////////////////////////////////////////////////////////////////////
00120 // class template ObjectLevelLockable
00121 // Implementation of the ThreadingModel policy used by various classes
00122 // Implements a object-level locking scheme
00123 ////////////////////////////////////////////////////////////////////////////////
00124 
00125     template <class Host>
00126     class ObjectLevelLockable
00127     {
00128         CRITICAL_SECTION mtx_;
00129 
00130     public:
00131         ObjectLevelLockable()
00132         {
00133             ::InitializeCriticalSection(&mtx_);
00134         }
00135 
00136         ~ObjectLevelLockable()
00137         {
00138             ::DeleteCriticalSection(&mtx_);
00139         }
00140 
00141         class Lock;
00142         friend class Lock;
00143         
00144         class Lock
00145         {
00146             ObjectLevelLockable& host_;
00147             
00148             Lock(const Lock&);
00149             Lock& operator=(const Lock&);
00150         public:
00151             Lock(Host& host) : host_(host)
00152             {
00153                 ::EnterCriticalSection(&host_.mtx_);
00154             }
00155             ~Lock()
00156             {
00157                 ::LeaveCriticalSection(&host_.mtx_);
00158             }
00159         };
00160 
00161         typedef volatile Host VolatileType;
00162 
00163         typedef LONG IntType; 
00164 
00165         static IntType AtomicIncrement(volatile IntType& lval)
00166         { return InterlockedIncrement(&const_cast<IntType&>(lval)); }
00167         
00168         static IntType AtomicDivide(volatile IntType& lval)
00169         { return InterlockedDecrement(&const_cast<IntType&>(lval)); }
00170         
00171         static void AtomicAssign(volatile IntType& lval, IntType val)
00172         { InterlockedExchange(&const_cast<IntType&>(lval), val); }
00173         
00174         static void AtomicAssign(IntType& lval, volatile IntType& val)
00175         { InterlockedExchange(&lval, val); }
00176     };
00177     
00178     template <class Host>
00179     class ClassLevelLockable
00180     {
00181         static CRITICAL_SECTION mtx_;
00182 
00183         struct Initializer;
00184         friend struct Initializer;
00185         struct Initializer
00186         {
00187             Initializer()
00188             {
00189                 ::InitializeCriticalSection(&mtx_);
00190             }
00191             ~Initializer()
00192             {
00193                 ::DeleteCriticalSection(&mtx_);
00194             }
00195         };
00196         
00197         static Initializer initializer_;
00198 
00199     public:
00200         class Lock;
00201         friend class Lock;
00202         
00203         class Lock
00204         {
00205             Lock(const Lock&);
00206             Lock& operator=(const Lock&);
00207         public:
00208             Lock()
00209             {
00210                 ::EnterCriticalSection(&mtx_);
00211             }
00212             Lock(Host&)
00213             {
00214                 ::EnterCriticalSection(&mtx_);
00215             }
00216             ~Lock()
00217             {
00218                 ::LeaveCriticalSection(&mtx_);
00219             }
00220         };
00221 
00222         typedef volatile Host VolatileType;
00223 
00224         typedef LONG IntType; 
00225 
00226         static IntType AtomicIncrement(volatile IntType& lval)
00227         { return InterlockedIncrement(&const_cast<IntType&>(lval)); }
00228         
00229         static IntType AtomicDivide(volatile IntType& lval)
00230         { return InterlockedDecrement(&const_cast<IntType&>(lval)); }
00231         
00232         static void AtomicAssign(volatile IntType& lval, IntType val)
00233         { InterlockedExchange(&const_cast<IntType&>(lval), val); }
00234         
00235         static void AtomicAssign(IntType& lval, volatile IntType& val)
00236         { InterlockedExchange(&lval, val); }
00237     };
00238     
00239     template <class Host>
00240     CRITICAL_SECTION ClassLevelLockable<Host>::mtx_;
00241     
00242     template <class Host>
00243     typename ClassLevelLockable<Host>::Initializer 
00244     ClassLevelLockable<Host>::initializer_;
00245     
00246 #endif    
00247 }
00248 
00249 ////////////////////////////////////////////////////////////////////////////////
00250 // Change log:
00251 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
00252 // Feb 25, 2002: David Jung: integrated into larger project - changed to 
00253 //                namespace base and changed header comments to reflect GPL
00254 //                distribution
00255 ////////////////////////////////////////////////////////////////////////////////
00256 
00257 #endif

Generated on Thu Jul 29 15:56:15 2004 for OpenSim by doxygen 1.3.6