Skip to content

Commit e0d2e78

Browse files
committed
post-merge
1 parent d8653b7 commit e0d2e78

File tree

1 file changed

+58
-38
lines changed

1 file changed

+58
-38
lines changed

Modules/_hashlib/hashlib_mutex.h

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,78 @@
55
#include "pycore_lock.h" // PyMutex
66

77
/*
8-
* Maximum number of bytes for a message for which the GIL is held
9-
* when performing incremental hashing.
8+
* Message length above which the GIL is to be released
9+
* when performing hashing operations.
1010
*/
1111
#define HASHLIB_GIL_MINSIZE 2048
1212

1313
/*
1414
* Helper code to synchronize access to the hash object when the GIL is
15-
* released around a CPU consuming hashlib operation. All code paths that
16-
* access a mutable part of obj must be enclosed in an ENTER_HASHLIB /
17-
* LEAVE_HASHLIB block or explicitly acquire and release the lock inside
18-
* a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for
19-
* an operation.
15+
* released around a CPU consuming hashlib operation.
2016
*
21-
* These only drop the GIL if the lock acquisition itself is likely to
22-
* block. Thus the non-blocking acquire gating the GIL release for a
23-
* blocking lock acquisition. The intent of these macros is to surround
24-
* the assumed always "fast" operations that you aren't releasing the
25-
* GIL around. Otherwise use code similar to what you see in hash
26-
* function update() methods.
17+
* Code accessing a mutable part of the hash object must be enclosed in
18+
* an HASHLIB_{ACQUIRE,RELEASE}_LOCK block or explicitly acquire and release
19+
* the mutex inside a Py_BEGIN_ALLOW_THREADS -- Py_END_ALLOW_THREADS block if
20+
* they wish to release the GIL for an operation.
2721
*/
2822

29-
/* Prevent undefined behaviors via multiple threads entering the C API. */
30-
#define HASHLIB_LOCK_HEAD \
31-
bool use_mutex; \
23+
#define HASHLIB_OBJECT_HEAD \
24+
PyObject_HEAD \
25+
/* Guard against race conditions during incremental update(). */ \
3226
PyMutex mutex;
3327

34-
#ifdef Py_GIL_DISABLED
35-
#define HASHLIB_INIT_MUTEX(OBJ) \
36-
do { \
37-
(OBJ)->mutex = (PyMutex){0}; \
38-
(OBJ)->use_mutex = true; \
28+
#define HASHLIB_INIT_MUTEX(OBJ) \
29+
do { \
30+
(OBJ)->mutex = (PyMutex){0}; \
3931
} while (0)
40-
#else
41-
#define HASHLIB_INIT_MUTEX(OBJ) \
42-
do { \
43-
(OBJ)->mutex = (PyMutex){0}; \
44-
(OBJ)->use_mutex = false; \
45-
} while (0)
46-
#endif
4732

48-
#define ENTER_HASHLIB(OBJ) \
49-
do { \
50-
if ((OBJ)->use_mutex) { \
51-
PyMutex_Lock(&(OBJ)->mutex); \
52-
} \
33+
#define HASHLIB_ACQUIRE_LOCK(OBJ) PyMutex_Lock(&(OBJ)->mutex)
34+
#define HASHLIB_RELEASE_LOCK(OBJ) PyMutex_Unlock(&(OBJ)->mutex)
35+
36+
// Macros for executing code while conditionally holding the GIL.
37+
//
38+
// These only drop the GIL if the lock acquisition itself is likely to
39+
// block. Thus the non-blocking acquire gating the GIL release for a
40+
// blocking lock acquisition. The intent of these macros is to surround
41+
// the assumed always "fast" operations that you aren't releasing the
42+
// GIL around.
43+
44+
/*
45+
* Execute a suite of C statements 'STATEMENTS'.
46+
*
47+
* The GIL is held if 'SIZE' is below the HASHLIB_GIL_MINSIZE threshold.
48+
*/
49+
#define HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(SIZE, STATEMENTS) \
50+
do { \
51+
if ((SIZE) > HASHLIB_GIL_MINSIZE) { \
52+
Py_BEGIN_ALLOW_THREADS \
53+
STATEMENTS; \
54+
Py_END_ALLOW_THREADS \
55+
} \
56+
else { \
57+
STATEMENTS; \
58+
} \
5359
} while (0)
5460

55-
#define LEAVE_HASHLIB(OBJ) \
56-
do { \
57-
if ((OBJ)->use_mutex) { \
58-
PyMutex_Unlock(&(OBJ)->mutex); \
59-
} \
61+
/*
62+
* Lock 'OBJ' and execute a suite of C statements 'STATEMENTS'.
63+
*
64+
* The GIL is held if 'SIZE' is below the HASHLIB_GIL_MINSIZE threshold.
65+
*/
66+
#define HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(OBJ, SIZE, STATEMENTS) \
67+
do { \
68+
if ((SIZE) > HASHLIB_GIL_MINSIZE) { \
69+
Py_BEGIN_ALLOW_THREADS \
70+
HASHLIB_ACQUIRE_LOCK(OBJ); \
71+
STATEMENTS; \
72+
HASHLIB_RELEASE_LOCK(OBJ); \
73+
Py_END_ALLOW_THREADS \
74+
} \
75+
else { \
76+
HASHLIB_ACQUIRE_LOCK(OBJ); \
77+
STATEMENTS; \
78+
HASHLIB_RELEASE_LOCK(OBJ); \
79+
} \
6080
} while (0)
6181

6282
#endif // !_HASHLIB_HASHLIB_MUTEX_H

0 commit comments

Comments
 (0)