Skip to content

Commit ea1ed82

Browse files
[3.14] pythongh-139774: use relaxed atomics for datetime hashes (pythonGH-139775) (python#139780)
pythongh-139774: use relaxed atomics for datetime hashes (pythonGH-139775) (cherry picked from commit 49fb46f) Co-authored-by: Kumar Aditya <[email protected]>
1 parent f10dc26 commit ea1ed82

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

Modules/_datetimemodule.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "pycore_time.h" // _PyTime_ObjectToTime_t()
1616
#include "pycore_unicodeobject.h" // _PyUnicode_Copy()
1717
#include "pycore_initconfig.h" // _PyStatus_OK()
18+
#include "pycore_pyatomic_ft_wrappers.h"
1819

1920
#include "datetime.h"
2021

@@ -2533,14 +2534,16 @@ static Py_hash_t
25332534
delta_hash(PyObject *op)
25342535
{
25352536
PyDateTime_Delta *self = PyDelta_CAST(op);
2536-
if (self->hashcode == -1) {
2537+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
2538+
if (hash == -1) {
25372539
PyObject *temp = delta_getstate(self);
25382540
if (temp != NULL) {
2539-
self->hashcode = PyObject_Hash(temp);
2541+
hash = PyObject_Hash(temp);
2542+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
25402543
Py_DECREF(temp);
25412544
}
25422545
}
2543-
return self->hashcode;
2546+
return hash;
25442547
}
25452548

25462549
static PyObject *
@@ -3860,12 +3863,14 @@ static Py_hash_t
38603863
date_hash(PyObject *op)
38613864
{
38623865
PyDateTime_Date *self = PyDate_CAST(op);
3863-
if (self->hashcode == -1) {
3864-
self->hashcode = generic_hash(
3866+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
3867+
if (hash == -1) {
3868+
hash = generic_hash(
38653869
(unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
3870+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
38663871
}
38673872

3868-
return self->hashcode;
3873+
return hash;
38693874
}
38703875

38713876
static PyObject *
@@ -4944,7 +4949,8 @@ static Py_hash_t
49444949
time_hash(PyObject *op)
49454950
{
49464951
PyDateTime_Time *self = PyTime_CAST(op);
4947-
if (self->hashcode == -1) {
4952+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
4953+
if (hash == -1) {
49484954
PyObject *offset, *self0;
49494955
if (TIME_GET_FOLD(self)) {
49504956
self0 = new_time_ex2(TIME_GET_HOUR(self),
@@ -4966,10 +4972,11 @@ time_hash(PyObject *op)
49664972
return -1;
49674973

49684974
/* Reduce this to a hash of another object. */
4969-
if (offset == Py_None)
4970-
self->hashcode = generic_hash(
4975+
if (offset == Py_None) {
4976+
hash = generic_hash(
49714977
(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
4972-
else {
4978+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
4979+
} else {
49734980
PyObject *temp1, *temp2;
49744981
int seconds, microseconds;
49754982
assert(HASTZINFO(self));
@@ -4988,12 +4995,13 @@ time_hash(PyObject *op)
49884995
Py_DECREF(offset);
49894996
return -1;
49904997
}
4991-
self->hashcode = PyObject_Hash(temp2);
4998+
hash = PyObject_Hash(temp2);
4999+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
49925000
Py_DECREF(temp2);
49935001
}
49945002
Py_DECREF(offset);
49955003
}
4996-
return self->hashcode;
5004+
return hash;
49975005
}
49985006

49995007
/*[clinic input]
@@ -6451,7 +6459,8 @@ static Py_hash_t
64516459
datetime_hash(PyObject *op)
64526460
{
64536461
PyDateTime_DateTime *self = PyDateTime_CAST(op);
6454-
if (self->hashcode == -1) {
6462+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
6463+
if (hash == -1) {
64556464
PyObject *offset, *self0;
64566465
if (DATE_GET_FOLD(self)) {
64576466
self0 = new_datetime_ex2(GET_YEAR(self),
@@ -6476,10 +6485,11 @@ datetime_hash(PyObject *op)
64766485
return -1;
64776486

64786487
/* Reduce this to a hash of another object. */
6479-
if (offset == Py_None)
6480-
self->hashcode = generic_hash(
6488+
if (offset == Py_None) {
6489+
hash = generic_hash(
64816490
(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
6482-
else {
6491+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
6492+
} else {
64836493
PyObject *temp1, *temp2;
64846494
int days, seconds;
64856495

@@ -6503,12 +6513,13 @@ datetime_hash(PyObject *op)
65036513
Py_DECREF(offset);
65046514
return -1;
65056515
}
6506-
self->hashcode = PyObject_Hash(temp2);
6516+
hash = PyObject_Hash(temp2);
6517+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
65076518
Py_DECREF(temp2);
65086519
}
65096520
Py_DECREF(offset);
65106521
}
6511-
return self->hashcode;
6522+
return hash;
65126523
}
65136524

65146525
/*[clinic input]

0 commit comments

Comments
 (0)