https://github.com/python/cpython/commit/49fb46f555881c9f2d20ca87c8187c8718217c77
commit: 49fb46f555881c9f2d20ca87c8187c8718217c77
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-10-08T19:49:54+05:30
summary:
gh-139774: use relaxed atomics for datetime hashes (#139775)
files:
M Modules/_datetimemodule.c
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 12d316985fceb9..46c4f57984b0df 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -15,6 +15,7 @@
#include "pycore_time.h" // _PyTime_ObjectToTime_t()
#include "pycore_unicodeobject.h" // _PyUnicode_Copy()
#include "pycore_initconfig.h" // _PyStatus_OK()
+#include "pycore_pyatomic_ft_wrappers.h"
#include "datetime.h"
@@ -2540,14 +2541,16 @@ static Py_hash_t
delta_hash(PyObject *op)
{
PyDateTime_Delta *self = PyDelta_CAST(op);
- if (self->hashcode == -1) {
+ Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
+ if (hash == -1) {
PyObject *temp = delta_getstate(self);
if (temp != NULL) {
- self->hashcode = PyObject_Hash(temp);
+ hash = PyObject_Hash(temp);
+ FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
Py_DECREF(temp);
}
}
- return self->hashcode;
+ return hash;
}
static PyObject *
@@ -3921,12 +3924,14 @@ static Py_hash_t
date_hash(PyObject *op)
{
PyDateTime_Date *self = PyDate_CAST(op);
- if (self->hashcode == -1) {
- self->hashcode = generic_hash(
+ Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
+ if (hash == -1) {
+ hash = generic_hash(
(unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
+ FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
}
- return self->hashcode;
+ return hash;
}
static PyObject *
@@ -5043,7 +5048,8 @@ static Py_hash_t
time_hash(PyObject *op)
{
PyDateTime_Time *self = PyTime_CAST(op);
- if (self->hashcode == -1) {
+ Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
+ if (hash == -1) {
PyObject *offset, *self0;
if (TIME_GET_FOLD(self)) {
self0 = new_time_ex2(TIME_GET_HOUR(self),
@@ -5065,10 +5071,11 @@ time_hash(PyObject *op)
return -1;
/* Reduce this to a hash of another object. */
- if (offset == Py_None)
- self->hashcode = generic_hash(
+ if (offset == Py_None) {
+ hash = generic_hash(
(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
- else {
+ FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
+ } else {
PyObject *temp1, *temp2;
int seconds, microseconds;
assert(HASTZINFO(self));
@@ -5087,12 +5094,13 @@ time_hash(PyObject *op)
Py_DECREF(offset);
return -1;
}
- self->hashcode = PyObject_Hash(temp2);
+ hash = PyObject_Hash(temp2);
+ FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
Py_DECREF(temp2);
}
Py_DECREF(offset);
}
- return self->hashcode;
+ return hash;
}
/*[clinic input]
@@ -6627,7 +6635,8 @@ static Py_hash_t
datetime_hash(PyObject *op)
{
PyDateTime_DateTime *self = PyDateTime_CAST(op);
- if (self->hashcode == -1) {
+ Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
+ if (hash == -1) {
PyObject *offset, *self0;
if (DATE_GET_FOLD(self)) {
self0 = new_datetime_ex2(GET_YEAR(self),
@@ -6652,10 +6661,11 @@ datetime_hash(PyObject *op)
return -1;
/* Reduce this to a hash of another object. */
- if (offset == Py_None)
- self->hashcode = generic_hash(
+ if (offset == Py_None) {
+ hash = generic_hash(
(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
- else {
+ FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
+ } else {
PyObject *temp1, *temp2;
int days, seconds;
@@ -6679,12 +6689,13 @@ datetime_hash(PyObject *op)
Py_DECREF(offset);
return -1;
}
- self->hashcode = PyObject_Hash(temp2);
+ hash = PyObject_Hash(temp2);
+ FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
Py_DECREF(temp2);
}
Py_DECREF(offset);
}
- return self->hashcode;
+ return hash;
}
/*[clinic input]
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]