Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
mutex.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef MUTEX_H
20#define MUTEX_H
21
22#if defined(_MSC_VER)
23#pragma once
24#endif
25
26#include "always.h"
27#include "thread.h"
28
29
30// Always use mutex or critical section when accessing the same data from multiple threads!
31
32// ----------------------------------------------------------------------------
33//
34// Mutex class is an expensive way of synchronization! Use critical sections
35// (below) for all synchronization. Use mutexes for inter-process locking.
36//
37// ----------------------------------------------------------------------------
38
40{
41 void* handle;
42 unsigned locked;
43
44 // Lock and unlock are private so that you can't use them directly. Use LockClass as a sentry instead!
45 // Lock returns true if lock was succesful, false otherwise
46 bool Lock(int time);
47 void Unlock();
48
49public:
50 // Name can (and usually should) be NULL. Use name only if you wish to create a globally unique mutex
51 MutexClass(const char* name = NULL);
53
54 enum {
56 };
57
59 {
60 MutexClass& mutex;
61 bool failed;
62 public:
63
64 // In order to lock a mutex create a local instance of LockClass with mutex as a parameter.
65 // Time is in milliseconds, INFINITE means infinite wait.
67 ~LockClass();
68
69 // Returns true if the lock failed
70 bool Failed() { return failed; }
71 private:
72 LockClass &operator=(const LockClass&) { return(*this); }
73 };
74 friend class LockClass;
75};
76
77// ----------------------------------------------------------------------------
78//
79// Critical sections are faster than mutex classes and they should be used
80// for all synchronization.
81//
82// ----------------------------------------------------------------------------
83
85{
86 void* handle;
87 unsigned locked;
88
89 // Lock and unlock are private so that you can't use them directly. Use LockClass as a sentry instead!
90 void Lock();
91 void Unlock();
92
93public:
94 // Name can (and usually should) be NULL. Use name only if you wish to create a globally unique mutex
97
98 class LockClass
99 {
101 public:
102 // In order to lock a mutex create a local instance of LockClass with mutex as a parameter.
105 private:
106 LockClass &operator=(const LockClass&) { return(*this); }
107 };
108 friend class LockClass;
109};
110
111// ----------------------------------------------------------------------------
112//
113// Fast critical section is really fast version of CriticalSection. The downside
114// of it is that it can't be locked multiple times from the same thread.
115//
116// ----------------------------------------------------------------------------
117
119{
120 unsigned Flag;
121
122public:
123 // Name can (and usually should) be NULL. Use name only if you wish to create a globally unique mutex
125
127 {
129 public:
130 __forceinline LockClass(FastCriticalSectionClass& critical_section) : cs(critical_section)
131 {
132 unsigned& nFlag=cs.Flag;
133
134 #define ts_lock _emit 0xF0
135 assert(((unsigned)&nFlag % 4) == 0);
136
137 // I'm terribly sorry for these emits in here but
138 // VC won't inline any functions that have labels in them...
139
140 // Had to remove the emits back to normal
141 // ASM statements because sometimes the jump
142 // would be 1 byte off....
143
144 __asm mov ebx, [nFlag]
145 __asm ts_lock
146 __asm bts dword ptr [ebx], 0
147 __asm jnc BitSet
148 //__asm _emit 0x73
149 //__asm _emit 0x0f
150
151 The_Bit_Was_Previously_Set_So_Try_Again:
153 __asm mov ebx, [nFlag]
154 __asm ts_lock
155 __asm bts dword ptr [ebx], 0
156 __asm jc The_Bit_Was_Previously_Set_So_Try_Again
157 //_asm _emit 0x72
158 //_asm _emit 0xf1
159
160 BitSet:
161 ;
162 }
163
165 {
166 cs.Flag=0;
167 }
168
169 private:
170 LockClass &operator=(const LockClass&);
171 LockClass(const LockClass&);
172 };
173
174 friend class LockClass;
175};
176
177#endif
#define NULL
Definition BaseType.h:92
#define BitSet(x, i)
Definition BaseType.h:173
LockClass(CriticalSectionClass &c)
__forceinline LockClass(FastCriticalSectionClass &critical_section)
Definition mutex.h:130
friend class LockClass
Definition mutex.h:174
LockClass(MutexClass &m, int time=MutexClass::WAIT_INFINITE)
Definition mutex.cpp:74
friend class LockClass
Definition mutex.h:74
~MutexClass()
Definition mutex.cpp:36
MutexClass(const char *name=NULL)
Definition mutex.cpp:26
@ WAIT_INFINITE
Definition mutex.h:55
static void Switch_Thread()
Definition thread.cpp:130
#define ts_lock