c5b0d5b86d84a046f20b7eccca61394b5011cde1
[serna.git] / sfworks / common / ThreadMutex.h
1 // 
2 // Copyright(c) 2009 Syntext, Inc. All Rights Reserved.
3 // Contact: info@syntext.com, http://www.syntext.com
4 // 
5 // This file is part of Syntext Serna XML Editor.
6 // 
7 // COMMERCIAL USAGE
8 // Licensees holding valid Syntext Serna commercial licenses may use this file
9 // in accordance with the Syntext Serna Commercial License Agreement provided
10 // with the software, or, alternatively, in accorance with the terms contained
11 // in a written agreement between you and Syntext, Inc.
12 // 
13 // GNU GENERAL PUBLIC LICENSE USAGE
14 // Alternatively, this file may be used under the terms of the GNU General 
15 // Public License versions 2.0 or 3.0 as published by the Free Software 
16 // Foundation and appearing in the file LICENSE.GPL included in the packaging 
17 // of this file. In addition, as a special exception, Syntext, Inc. gives you
18 // certain additional rights, which are described in the Syntext, Inc. GPL 
19 // Exception for Syntext Serna Free Edition, included in the file 
20 // GPL_EXCEPTION.txt in this package.
21 // 
22 // You should have received a copy of appropriate licenses along with this 
23 // package. If not, see <http://www.syntext.com/legal/>. If you are unsure
24 // which license is appropriate for your use, please contact the sales 
25 // department at sales@syntext.com.
26 // 
27 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 // 
30 /*! \file
31      This file contains (machine-dependent) definitions of
32      primitive mutex locks. They are not intended for general
33      use, and used for parametrization of threading policies
34      defined in ThreadingPolicies.h
35  */
36 #ifndef THREAD_MUTEX_H_
37 #define THREAD_MUTEX_H_
38
39 #if defined(_WIN32) && !defined (MULTI_THREADED)
40 # error Under win32 you must define MULTI_THREADED!!!
41 #endif
42
43 #include "common/common_defs.h"
44 #include "common/common_types.h"
45
46
47 #ifdef MULTI_THREADED
48 # ifdef _WIN32
49 #  define VC_EXTRALEAN
50 #  include <windows.h>
51 # else // _WIN32
52 #  include <pthread.h>
53 # endif // _WIN32
54 #endif // MULTI_THREADED
55
56 #if defined(MUTEX_DEBUG) && defined(MULTI_THREADED)
57 # error MUTEX_DEBUG with MULTI_THREADED makes no sense
58 #endif
59
60 COMMON_NS_BEGIN
61
62 /*! A null mutex (no multithreading)
63  */
64 class COMMON_EXPIMP NullThreadMutex {
65 public:
66 #ifndef MUTEX_DEBUG
67     typedef EmptyStruct MutexType;
68 #else
69     typedef NullThreadMutex MutexType;
70 #endif
71
72     typedef int32 IntType;
73     typedef int32 VolatileIntType;
74
75 #ifndef MUTEX_DEBUG
76     static void initialize(MutexType*) {}
77     static void destroy(MutexType*) {}
78     static void lock(MutexType*) {}
79     static void unlock(MutexType*) {}
80 #else // MUTEX_DEBUG
81     static void initialize(MutexType* m)
82     {
83         m->locked_ = false; m->initialized_ = true;
84     }
85     static void destroy(MutexType* m)
86     {
87         assert(m->initialized_); m->initialized_ = false;
88     }
89     static void lock(MutexType* m)
90     {
91        assert(m->initialized_); assert(!m->locked_); m->locked_ = true;
92     }
93     static void unlock(MutexType* m)
94     {
95         assert(m->initialized_); assert(m->locked_); m->locked_ = false;
96     }
97 #endif // MUTEX_DEBUG
98     static IntType atomicIncrement(VolatileIntType& lval)
99     {
100         return ++lval;
101     }
102     static IntType atomicDecrement(VolatileIntType& lval)
103     {
104         return --lval;
105     }
106     static IntType atomicRead(VolatileIntType& lval)
107     {
108         return lval;
109     }
110     static void    atomicAssign(VolatileIntType& lval, IntType rval)
111     {
112         lval = rval;
113     }
114     static IntType atomicExchange(VolatileIntType& lval, IntType rval)
115     {
116         IntType tmp = lval;
117         lval = rval;
118         return tmp;
119     }
120 #ifdef MUTEX_DEBUG
121 private:
122     bool locked_;
123     bool initialized_;
124 #endif // MUTEX_DEBUG
125 };
126
127 #ifdef MULTI_THREADED
128
129 /*! Non-recursive thread mutex
130  */
131 class COMMON_EXPIMP ThreadMutex {
132 public:
133     typedef int32 IntType;
134 # ifdef _WIN32
135     // Win32 critical sections
136     typedef CRITICAL_SECTION MutexType;
137 # else
138     // posix threads mutexes
139     typedef ::pthread_mutex_t MutexType;
140 # endif
141     typedef volatile IntType VolatileIntType;
142
143     static void initialize(MutexType*);
144     static void destroy(MutexType*);
145     static void lock(MutexType*);
146     static void unlock(MutexType*);
147
148     static IntType atomicIncrement(VolatileIntType& lval);
149     static IntType atomicDecrement(VolatileIntType& lval);
150     static IntType atomicRead(VolatileIntType& lval);
151     static void    atomicAssign(VolatileIntType& lval, IntType rval);
152     static IntType atomicExchange(VolatileIntType& lval, IntType rval);
153 };
154
155 #else // MULTI_THREADED
156
157 class COMMON_EXPIMP ThreadMutex : public NullThreadMutex {};
158
159 #endif // MULTI_THREADED
160
161 COMMON_NS_END
162
163 #if defined(NDEBUG) && !defined(_DEBUG)
164 # ifdef INLINE_ATOMICS
165 #  undef INLINE_ATOMICS
166 # endif
167 # define INLINE_ATOMICS inline
168 # include "machdep/ThreadMutexAtomics.i"
169 # undef INLINE_ATOMICS
170 #endif
171
172 #endif // THREAD_MUTEX_H_