@@ -32,7 +32,7 @@ extern "C" {
3232 const bool _should_lock_cs = PyList_CheckExact(_orig_seq); \
3333 PyCriticalSection _cs; \
3434 if (_should_lock_cs) { \
35- _PyCriticalSection_Begin (&_cs, _orig_seq); \
35+ PyCriticalSection_Begin (&_cs, _orig_seq); \
3636 }
3737
3838# define Py_END_CRITICAL_SECTION_SEQUENCE_FAST () \
@@ -77,10 +77,10 @@ _PyCriticalSection_Resume(PyThreadState *tstate);
7777
7878// (private) slow path for locking the mutex
7979PyAPI_FUNC (void )
80- _PyCriticalSection_BeginSlow (PyCriticalSection * c , PyMutex * m );
80+ _PyCriticalSection_BeginSlow (PyThreadState * tstate , PyCriticalSection * c , PyMutex * m );
8181
8282PyAPI_FUNC (void )
83- _PyCriticalSection2_BeginSlow (PyCriticalSection2 * c , PyMutex * m1 , PyMutex * m2 ,
83+ _PyCriticalSection2_BeginSlow (PyThreadState * tstate , PyCriticalSection2 * c , PyMutex * m1 , PyMutex * m2 ,
8484 int is_m1_locked );
8585
8686PyAPI_FUNC (void )
@@ -95,34 +95,30 @@ _PyCriticalSection_IsActive(uintptr_t tag)
9595}
9696
9797static inline void
98- _PyCriticalSection_BeginMutex (PyCriticalSection * c , PyMutex * m )
98+ _PyCriticalSection_BeginMutex (PyThreadState * tstate , PyCriticalSection * c , PyMutex * m )
9999{
100100 if (PyMutex_LockFast (m )) {
101- PyThreadState * tstate = _PyThreadState_GET ();
102101 c -> _cs_mutex = m ;
103102 c -> _cs_prev = tstate -> critical_section ;
104103 tstate -> critical_section = (uintptr_t )c ;
105104 }
106105 else {
107- _PyCriticalSection_BeginSlow (c , m );
106+ _PyCriticalSection_BeginSlow (tstate , c , m );
108107 }
109108}
110- #define PyCriticalSection_BeginMutex _PyCriticalSection_BeginMutex
111109
112110static inline void
113- _PyCriticalSection_Begin (PyCriticalSection * c , PyObject * op )
111+ _PyCriticalSection_Begin (PyThreadState * tstate , PyCriticalSection * c , PyObject * op )
114112{
115- _PyCriticalSection_BeginMutex (c , & op -> ob_mutex );
113+ _PyCriticalSection_BeginMutex (tstate , c , & op -> ob_mutex );
116114}
117- #define PyCriticalSection_Begin _PyCriticalSection_Begin
118115
119116// Removes the top-most critical section from the thread's stack of critical
120117// sections. If the new top-most critical section is inactive, then it is
121118// resumed.
122119static inline void
123- _PyCriticalSection_Pop (PyCriticalSection * c )
120+ _PyCriticalSection_Pop (PyThreadState * tstate , PyCriticalSection * c )
124121{
125- PyThreadState * tstate = _PyThreadState_GET ();
126122 uintptr_t prev = c -> _cs_prev ;
127123 tstate -> critical_section = prev ;
128124
@@ -132,7 +128,7 @@ _PyCriticalSection_Pop(PyCriticalSection *c)
132128}
133129
134130static inline void
135- _PyCriticalSection_End (PyCriticalSection * c )
131+ _PyCriticalSection_End (PyThreadState * tstate , PyCriticalSection * c )
136132{
137133 // If the mutex is NULL, we used the fast path in
138134 // _PyCriticalSection_BeginSlow for locks already held in the top-most
@@ -141,18 +137,17 @@ _PyCriticalSection_End(PyCriticalSection *c)
141137 return ;
142138 }
143139 PyMutex_Unlock (c -> _cs_mutex );
144- _PyCriticalSection_Pop (c );
140+ _PyCriticalSection_Pop (tstate , c );
145141}
146- #define PyCriticalSection_End _PyCriticalSection_End
147142
148143static inline void
149- _PyCriticalSection2_BeginMutex (PyCriticalSection2 * c , PyMutex * m1 , PyMutex * m2 )
144+ _PyCriticalSection2_BeginMutex (PyThreadState * tstate , PyCriticalSection2 * c , PyMutex * m1 , PyMutex * m2 )
150145{
151146 if (m1 == m2 ) {
152147 // If the two mutex arguments are the same, treat this as a critical
153148 // section with a single mutex.
154149 c -> _cs_mutex2 = NULL ;
155- _PyCriticalSection_BeginMutex (& c -> _cs_base , m1 );
150+ _PyCriticalSection_BeginMutex (tstate , & c -> _cs_base , m1 );
156151 return ;
157152 }
158153
@@ -167,7 +162,6 @@ _PyCriticalSection2_BeginMutex(PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2)
167162
168163 if (PyMutex_LockFast (m1 )) {
169164 if (PyMutex_LockFast (m2 )) {
170- PyThreadState * tstate = _PyThreadState_GET ();
171165 c -> _cs_base ._cs_mutex = m1 ;
172166 c -> _cs_mutex2 = m2 ;
173167 c -> _cs_base ._cs_prev = tstate -> critical_section ;
@@ -176,24 +170,22 @@ _PyCriticalSection2_BeginMutex(PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2)
176170 tstate -> critical_section = p ;
177171 }
178172 else {
179- _PyCriticalSection2_BeginSlow (c , m1 , m2 , 1 );
173+ _PyCriticalSection2_BeginSlow (tstate , c , m1 , m2 , 1 );
180174 }
181175 }
182176 else {
183- _PyCriticalSection2_BeginSlow (c , m1 , m2 , 0 );
177+ _PyCriticalSection2_BeginSlow (tstate , c , m1 , m2 , 0 );
184178 }
185179}
186- #define PyCriticalSection2_BeginMutex _PyCriticalSection2_BeginMutex
187180
188181static inline void
189- _PyCriticalSection2_Begin (PyCriticalSection2 * c , PyObject * a , PyObject * b )
182+ _PyCriticalSection2_Begin (PyThreadState * tstate , PyCriticalSection2 * c , PyObject * a , PyObject * b )
190183{
191- _PyCriticalSection2_BeginMutex (c , & a -> ob_mutex , & b -> ob_mutex );
184+ _PyCriticalSection2_BeginMutex (tstate , c , & a -> ob_mutex , & b -> ob_mutex );
192185}
193- #define PyCriticalSection2_Begin _PyCriticalSection2_Begin
194186
195187static inline void
196- _PyCriticalSection2_End (PyCriticalSection2 * c )
188+ _PyCriticalSection2_End (PyThreadState * tstate , PyCriticalSection2 * c )
197189{
198190 // if mutex1 is NULL, we used the fast path in
199191 // _PyCriticalSection_BeginSlow for mutexes that are already held,
@@ -207,9 +199,8 @@ _PyCriticalSection2_End(PyCriticalSection2 *c)
207199 PyMutex_Unlock (c -> _cs_mutex2 );
208200 }
209201 PyMutex_Unlock (c -> _cs_base ._cs_mutex );
210- _PyCriticalSection_Pop (& c -> _cs_base );
202+ _PyCriticalSection_Pop (tstate , & c -> _cs_base );
211203}
212- #define PyCriticalSection2_End _PyCriticalSection2_End
213204
214205static inline void
215206_PyCriticalSection_AssertHeld (PyMutex * mutex )
@@ -251,6 +242,45 @@ _PyCriticalSection_AssertHeldObj(PyObject *op)
251242
252243#endif
253244}
245+
246+ #undef Py_BEGIN_CRITICAL_SECTION
247+ # define Py_BEGIN_CRITICAL_SECTION (op ) \
248+ { \
249+ PyCriticalSection _py_cs; \
250+ PyThreadState *_cs_tstate = _PyThreadState_GET(); \
251+ _PyCriticalSection_Begin(_cs_tstate, &_py_cs, _PyObject_CAST(op))
252+
253+ #undef Py_BEGIN_CRITICAL_SECTION_MUTEX
254+ # define Py_BEGIN_CRITICAL_SECTION_MUTEX (mutex ) \
255+ { \
256+ PyCriticalSection _py_cs; \
257+ PyThreadState *_cs_tstate = _PyThreadState_GET(); \
258+ _PyCriticalSection_BeginMutex(_cs_tstate, &_py_cs, mutex)
259+
260+ #undef Py_END_CRITICAL_SECTION
261+ # define Py_END_CRITICAL_SECTION () \
262+ _PyCriticalSection_End(_cs_tstate, &_py_cs); \
263+ }
264+
265+ #undef Py_BEGIN_CRITICAL_SECTION2
266+ # define Py_BEGIN_CRITICAL_SECTION2 (a , b ) \
267+ { \
268+ PyCriticalSection2 _py_cs2; \
269+ PyThreadState *_cs_tstate = _PyThreadState_GET(); \
270+ _PyCriticalSection2_Begin(_cs_tstate, &_py_cs2, _PyObject_CAST(a), _PyObject_CAST(b))
271+
272+ #undef Py_BEGIN_CRITICAL_SECTION2_MUTEX
273+ # define Py_BEGIN_CRITICAL_SECTION2_MUTEX (m1 , m2 ) \
274+ { \
275+ PyCriticalSection2 _py_cs2; \
276+ PyThreadState *_cs_tstate = _PyThreadState_GET(); \
277+ _PyCriticalSection2_BeginMutex(_cs_tstate, &_py_cs2, m1, m2)
278+
279+ #undef Py_END_CRITICAL_SECTION2
280+ # define Py_END_CRITICAL_SECTION2 () \
281+ _PyCriticalSection2_End(_cs_tstate, &_py_cs2); \
282+ }
283+
254284#endif /* Py_GIL_DISABLED */
255285
256286#ifdef __cplusplus
0 commit comments