Skip to content

Commit bfb5436

Browse files
committed
release the GIL for large buffers
1 parent c14c87d commit bfb5436

7 files changed

Lines changed: 87 additions & 62 deletions

File tree

Modules/blake2module.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,10 @@ py_blake2_new(PyTypeObject *type, PyObject *data, int digest_size,
644644
GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
645645
/* Do not use self->mutex here as this is the constructor
646646
* where it is not yet possible to have concurrent access. */
647-
Py_BEGIN_ALLOW_THREADS
648-
blake2_update_unlocked(self, buf.buf, buf.len);
649-
Py_END_ALLOW_THREADS
647+
HASHLIB_EXTERNAL_INSTRUCTIONS(
648+
buf.len,
649+
blake2_update_unlocked(self, buf.buf, buf.len)
650+
)
650651
PyBuffer_Release(&buf);
651652
}
652653

@@ -819,11 +820,10 @@ _blake2_blake2b_update_impl(Blake2Object *self, PyObject *data)
819820
{
820821
Py_buffer buf;
821822
GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
822-
Py_BEGIN_ALLOW_THREADS
823-
HASHLIB_ACQUIRE_LOCK(self);
824-
blake2_update_unlocked(self, buf.buf, buf.len);
825-
HASHLIB_RELEASE_LOCK(self);
826-
Py_END_ALLOW_THREADS
823+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
824+
self, buf.len,
825+
blake2_update_unlocked(self, buf.buf, buf.len)
826+
)
827827
PyBuffer_Release(&buf);
828828
Py_RETURN_NONE;
829829
}

Modules/hashlib.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,29 @@
6363
(OBJ)->mutex = (PyMutex){0}; \
6464
} while (0)
6565

66+
#define HASHLIB_GIL_MINSIZE 2048
67+
#define HASHLIB_EXTERNAL_INSTRUCTIONS(SIZE, STATEMENTS) \
68+
if ((SIZE) > HASHLIB_GIL_MINSIZE) { \
69+
Py_BEGIN_ALLOW_THREADS \
70+
STATEMENTS; \
71+
Py_END_ALLOW_THREADS \
72+
} \
73+
else { \
74+
STATEMENTS; \
75+
}
76+
77+
#define HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(OBJ, SIZE, STATEMENTS) \
78+
if ((SIZE) > HASHLIB_GIL_MINSIZE) { \
79+
Py_BEGIN_ALLOW_THREADS \
80+
HASHLIB_ACQUIRE_LOCK(OBJ); \
81+
STATEMENTS; \
82+
HASHLIB_RELEASE_LOCK(OBJ); \
83+
Py_END_ALLOW_THREADS \
84+
} \
85+
else { \
86+
STATEMENTS; \
87+
}
88+
6689
static inline int
6790
_Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string)
6891
{

Modules/hmacmodule.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -776,9 +776,10 @@ _hmac_new_impl(PyObject *module, PyObject *keyobj, PyObject *msgobj,
776776
GET_BUFFER_VIEW_OR_ERROR(msgobj, &msg, goto error);
777777
/* Do not use self->mutex here as this is the constructor
778778
* where it is not yet possible to have concurrent access. */
779-
Py_BEGIN_ALLOW_THREADS
780-
rc = _hacl_hmac_state_update(self->state, msg.buf, msg.len);
781-
Py_END_ALLOW_THREADS
779+
HASHLIB_EXTERNAL_INSTRUCTIONS(
780+
msg.len,
781+
_hacl_hmac_state_update(self->state, msg.buf, msg.len)
782+
);
782783
PyBuffer_Release(&msg);
783784
#ifndef NDEBUG
784785
if (rc < 0) {
@@ -887,11 +888,10 @@ _hmac_HMAC_update_impl(HMACObject *self, PyObject *msgobj)
887888
int rc = 0;
888889
Py_buffer msg;
889890
GET_BUFFER_VIEW_OR_ERROUT(msgobj, &msg);
890-
Py_BEGIN_ALLOW_THREADS
891-
HASHLIB_ACQUIRE_LOCK(self);
892-
rc = _hacl_hmac_state_update(self->state, msg.buf, msg.len);
893-
HASHLIB_RELEASE_LOCK(self);
894-
Py_END_ALLOW_THREADS
891+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
892+
self, msg.len,
893+
rc = _hacl_hmac_state_update(self->state, msg.buf, msg.len)
894+
)
895895
PyBuffer_Release(&msg);
896896
return rc < 0 ? NULL : Py_None;
897897
}

Modules/md5module.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,10 @@ MD5Type_update_impl(MD5object *self, PyObject *obj)
193193
{
194194
Py_buffer buf;
195195
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
196-
Py_BEGIN_ALLOW_THREADS
197-
HASHLIB_ACQUIRE_LOCK(self);
198-
_hacl_md5_state_update(self->hash_state, buf.buf, buf.len);
199-
HASHLIB_RELEASE_LOCK(self);
200-
Py_END_ALLOW_THREADS
196+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
197+
self, buf.len,
198+
_hacl_md5_state_update(self->hash_state, buf.buf, buf.len)
199+
)
201200
PyBuffer_Release(&buf);
202201
Py_RETURN_NONE;
203202
}
@@ -301,9 +300,10 @@ _md5_md5_impl(PyObject *module, PyObject *data, int usedforsecurity,
301300
if (string) {
302301
/* Do not use self->mutex here as this is the constructor
303302
* where it is not yet possible to have concurrent access. */
304-
Py_BEGIN_ALLOW_THREADS
305-
_hacl_md5_state_update(new->hash_state, buf.buf, buf.len);
306-
Py_END_ALLOW_THREADS
303+
HASHLIB_EXTERNAL_INSTRUCTIONS(
304+
buf.len,
305+
_hacl_md5_state_update(new->hash_state, buf.buf, buf.len)
306+
)
307307
PyBuffer_Release(&buf);
308308
}
309309

Modules/sha1module.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,10 @@ SHA1Type_update_impl(SHA1object *self, PyObject *obj)
196196
{
197197
Py_buffer buf;
198198
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
199-
Py_BEGIN_ALLOW_THREADS
200-
HASHLIB_ACQUIRE_LOCK(self);
201-
_hacl_sha1_state_update(self->hash_state, buf.buf, buf.len);
202-
HASHLIB_RELEASE_LOCK(self);
203-
Py_END_ALLOW_THREADS
199+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
200+
self, buf.len,
201+
_hacl_sha1_state_update(self->hash_state, buf.buf, buf.len)
202+
)
204203
PyBuffer_Release(&buf);
205204
Py_RETURN_NONE;
206205
}
@@ -303,9 +302,10 @@ _sha1_sha1_impl(PyObject *module, PyObject *data, int usedforsecurity,
303302
if (string) {
304303
/* Do not use self->mutex here as this is the constructor
305304
* where it is not yet possible to have concurrent access. */
306-
Py_BEGIN_ALLOW_THREADS
307-
_hacl_sha1_state_update(new->hash_state, buf.buf, buf.len);
308-
Py_END_ALLOW_THREADS
305+
HASHLIB_EXTERNAL_INSTRUCTIONS(
306+
buf.len,
307+
_hacl_sha1_state_update(new->hash_state, buf.buf, buf.len)
308+
)
309309
PyBuffer_Release(&buf);
310310
}
311311

Modules/sha2module.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,10 @@ SHA256Type_update_impl(SHA256object *self, PyObject *obj)
406406
{
407407
Py_buffer buf;
408408
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
409-
Py_BEGIN_ALLOW_THREADS
410-
HASHLIB_ACQUIRE_LOCK(self);
411-
_hacl_sha2_state_update_256(self->state, buf.buf, buf.len);
412-
HASHLIB_RELEASE_LOCK(self);
413-
Py_END_ALLOW_THREADS
409+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
410+
self, buf.len,
411+
_hacl_sha2_state_update_256(self->state, buf.buf, buf.len)
412+
)
414413
PyBuffer_Release(&buf);
415414
Py_RETURN_NONE;
416415
}
@@ -430,11 +429,10 @@ SHA512Type_update_impl(SHA512object *self, PyObject *obj)
430429
{
431430
Py_buffer buf;
432431
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
433-
Py_BEGIN_ALLOW_THREADS
434-
HASHLIB_ACQUIRE_LOCK(self);
435-
_hacl_sha2_state_update_512(self->state, buf.buf, buf.len);
436-
HASHLIB_RELEASE_LOCK(self);
437-
Py_END_ALLOW_THREADS
432+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
433+
self, buf.len,
434+
_hacl_sha2_state_update_512(self->state, buf.buf, buf.len)
435+
)
438436
PyBuffer_Release(&buf);
439437
Py_RETURN_NONE;
440438
}
@@ -616,9 +614,10 @@ _sha2_sha256_impl(PyObject *module, PyObject *data, int usedforsecurity,
616614
if (string) {
617615
/* Do not use self->mutex here as this is the constructor
618616
* where it is not yet possible to have concurrent access. */
619-
Py_BEGIN_ALLOW_THREADS
620-
_hacl_sha2_state_update_256(new->state, buf.buf, buf.len);
621-
Py_END_ALLOW_THREADS
617+
HASHLIB_EXTERNAL_INSTRUCTIONS(
618+
buf.len,
619+
_hacl_sha2_state_update_256(new->state, buf.buf, buf.len)
620+
)
622621
PyBuffer_Release(&buf);
623622
}
624623

@@ -673,9 +672,10 @@ _sha2_sha224_impl(PyObject *module, PyObject *data, int usedforsecurity,
673672
if (string) {
674673
/* Do not use self->mutex here as this is the constructor
675674
* where it is not yet possible to have concurrent access. */
676-
Py_BEGIN_ALLOW_THREADS
677-
_hacl_sha2_state_update_256(new->state, buf.buf, buf.len);
678-
Py_END_ALLOW_THREADS
675+
HASHLIB_EXTERNAL_INSTRUCTIONS(
676+
buf.len,
677+
_hacl_sha2_state_update_256(new->state, buf.buf, buf.len)
678+
)
679679
PyBuffer_Release(&buf);
680680
}
681681

@@ -731,9 +731,10 @@ _sha2_sha512_impl(PyObject *module, PyObject *data, int usedforsecurity,
731731
if (string) {
732732
/* Do not use self->mutex here as this is the constructor
733733
* where it is not yet possible to have concurrent access. */
734-
Py_BEGIN_ALLOW_THREADS
735-
_hacl_sha2_state_update_512(new->state, buf.buf, buf.len);
736-
Py_END_ALLOW_THREADS
734+
HASHLIB_EXTERNAL_INSTRUCTIONS(
735+
buf.len,
736+
_hacl_sha2_state_update_512(new->state, buf.buf, buf.len)
737+
)
737738
PyBuffer_Release(&buf);
738739
}
739740

@@ -789,9 +790,10 @@ _sha2_sha384_impl(PyObject *module, PyObject *data, int usedforsecurity,
789790
if (string) {
790791
/* Do not use self->mutex here as this is the constructor
791792
* where it is not yet possible to have concurrent access. */
792-
Py_BEGIN_ALLOW_THREADS
793-
_hacl_sha2_state_update_512(new->state, buf.buf, buf.len);
794-
Py_END_ALLOW_THREADS
793+
HASHLIB_EXTERNAL_INSTRUCTIONS(
794+
buf.len,
795+
_hacl_sha2_state_update_512(new->state, buf.buf, buf.len)
796+
)
795797
PyBuffer_Release(&buf);
796798
}
797799

Modules/sha3module.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,10 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data_obj, int usedforsecurity,
163163
GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
164164
/* Do not use self->mutex here as this is the constructor
165165
* where it is not yet possible to have concurrent access. */
166-
Py_BEGIN_ALLOW_THREADS
167-
_hacl_sha3_state_update(self->hash_state, buf.buf, buf.len);
168-
Py_END_ALLOW_THREADS
166+
HASHLIB_EXTERNAL_INSTRUCTIONS(
167+
buf.len,
168+
_hacl_sha3_state_update(self->hash_state, buf.buf, buf.len)
169+
)
169170
}
170171

171172
PyBuffer_Release(&buf);
@@ -297,11 +298,10 @@ _sha3_sha3_224_update_impl(SHA3object *self, PyObject *data)
297298
{
298299
Py_buffer buf;
299300
GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
300-
Py_BEGIN_ALLOW_THREADS
301-
HASHLIB_ACQUIRE_LOCK(self);
302-
_hacl_sha3_state_update(self->hash_state, buf.buf, buf.len);
303-
HASHLIB_RELEASE_LOCK(self);
304-
Py_END_ALLOW_THREADS
301+
HASHLIB_EXTERNAL_INSTRUCTIONS_WITH_MUTEX(
302+
self, buf.len,
303+
_hacl_sha3_state_update(self->hash_state, buf.buf, buf.len)
304+
)
305305
PyBuffer_Release(&buf);
306306
Py_RETURN_NONE;
307307
}

0 commit comments

Comments
 (0)