Skip to content

Commit 49fb46f

Browse files
gh-139774: use relaxed atomics for datetime hashes (#139775)
1 parent 8b9606a commit 49fb46f

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

@@ -2540,14 +2541,16 @@ static Py_hash_t
25402541
delta_hash(PyObject *op)
25412542
{
25422543
PyDateTime_Delta *self = PyDelta_CAST(op);
2543-
if (self->hashcode == -1) {
2544+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
2545+
if (hash == -1) {
25442546
PyObject *temp = delta_getstate(self);
25452547
if (temp != NULL) {
2546-
self->hashcode = PyObject_Hash(temp);
2548+
hash = PyObject_Hash(temp);
2549+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
25472550
Py_DECREF(temp);
25482551
}
25492552
}
2550-
return self->hashcode;
2553+
return hash;
25512554
}
25522555

25532556
static PyObject *
@@ -3921,12 +3924,14 @@ static Py_hash_t
39213924
date_hash(PyObject *op)
39223925
{
39233926
PyDateTime_Date *self = PyDate_CAST(op);
3924-
if (self->hashcode == -1) {
3925-
self->hashcode = generic_hash(
3927+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
3928+
if (hash == -1) {
3929+
hash = generic_hash(
39263930
(unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
3931+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
39273932
}
39283933

3929-
return self->hashcode;
3934+
return hash;
39303935
}
39313936

39323937
static PyObject *
@@ -5043,7 +5048,8 @@ static Py_hash_t
50435048
time_hash(PyObject *op)
50445049
{
50455050
PyDateTime_Time *self = PyTime_CAST(op);
5046-
if (self->hashcode == -1) {
5051+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
5052+
if (hash == -1) {
50475053
PyObject *offset, *self0;
50485054
if (TIME_GET_FOLD(self)) {
50495055
self0 = new_time_ex2(TIME_GET_HOUR(self),
@@ -5065,10 +5071,11 @@ time_hash(PyObject *op)
50655071
return -1;
50665072

50675073
/* Reduce this to a hash of another object. */
5068-
if (offset == Py_None)
5069-
self->hashcode = generic_hash(
5074+
if (offset == Py_None) {
5075+
hash = generic_hash(
50705076
(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
5071-
else {
5077+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
5078+
} else {
50725079
PyObject *temp1, *temp2;
50735080
int seconds, microseconds;
50745081
assert(HASTZINFO(self));
@@ -5087,12 +5094,13 @@ time_hash(PyObject *op)
50875094
Py_DECREF(offset);
50885095
return -1;
50895096
}
5090-
self->hashcode = PyObject_Hash(temp2);
5097+
hash = PyObject_Hash(temp2);
5098+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
50915099
Py_DECREF(temp2);
50925100
}
50935101
Py_DECREF(offset);
50945102
}
5095-
return self->hashcode;
5103+
return hash;
50965104
}
50975105

50985106
/*[clinic input]
@@ -6627,7 +6635,8 @@ static Py_hash_t
66276635
datetime_hash(PyObject *op)
66286636
{
66296637
PyDateTime_DateTime *self = PyDateTime_CAST(op);
6630-
if (self->hashcode == -1) {
6638+
Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
6639+
if (hash == -1) {
66316640
PyObject *offset, *self0;
66326641
if (DATE_GET_FOLD(self)) {
66336642
self0 = new_datetime_ex2(GET_YEAR(self),
@@ -6652,10 +6661,11 @@ datetime_hash(PyObject *op)
66526661
return -1;
66536662

66546663
/* Reduce this to a hash of another object. */
6655-
if (offset == Py_None)
6656-
self->hashcode = generic_hash(
6664+
if (offset == Py_None) {
6665+
hash = generic_hash(
66576666
(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
6658-
else {
6667+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
6668+
} else {
66596669
PyObject *temp1, *temp2;
66606670
int days, seconds;
66616671

@@ -6679,12 +6689,13 @@ datetime_hash(PyObject *op)
66796689
Py_DECREF(offset);
66806690
return -1;
66816691
}
6682-
self->hashcode = PyObject_Hash(temp2);
6692+
hash = PyObject_Hash(temp2);
6693+
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
66836694
Py_DECREF(temp2);
66846695
}
66856696
Py_DECREF(offset);
66866697
}
6687-
return self->hashcode;
6698+
return hash;
66886699
}
66896700

66906701
/*[clinic input]

0 commit comments

Comments
 (0)