gh-139774: use relaxed atomics for datetime hashes (#139775)

This commit is contained in:
Kumar Aditya 2025-10-08 19:49:54 +05:30 committed by GitHub
parent 8b9606a2c5
commit 49fb46f555
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -15,6 +15,7 @@
#include "pycore_time.h" // _PyTime_ObjectToTime_t() #include "pycore_time.h" // _PyTime_ObjectToTime_t()
#include "pycore_unicodeobject.h" // _PyUnicode_Copy() #include "pycore_unicodeobject.h" // _PyUnicode_Copy()
#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_pyatomic_ft_wrappers.h"
#include "datetime.h" #include "datetime.h"
@ -2540,14 +2541,16 @@ static Py_hash_t
delta_hash(PyObject *op) delta_hash(PyObject *op)
{ {
PyDateTime_Delta *self = PyDelta_CAST(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); PyObject *temp = delta_getstate(self);
if (temp != NULL) { if (temp != NULL) {
self->hashcode = PyObject_Hash(temp); hash = PyObject_Hash(temp);
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
Py_DECREF(temp); Py_DECREF(temp);
} }
} }
return self->hashcode; return hash;
} }
static PyObject * static PyObject *
@ -3921,12 +3924,14 @@ static Py_hash_t
date_hash(PyObject *op) date_hash(PyObject *op)
{ {
PyDateTime_Date *self = PyDate_CAST(op); PyDateTime_Date *self = PyDate_CAST(op);
if (self->hashcode == -1) { Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hashcode);
self->hashcode = generic_hash( if (hash == -1) {
hash = generic_hash(
(unsigned char *)self->data, _PyDateTime_DATE_DATASIZE); (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
} }
return self->hashcode; return hash;
} }
static PyObject * static PyObject *
@ -5043,7 +5048,8 @@ static Py_hash_t
time_hash(PyObject *op) time_hash(PyObject *op)
{ {
PyDateTime_Time *self = PyTime_CAST(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; PyObject *offset, *self0;
if (TIME_GET_FOLD(self)) { if (TIME_GET_FOLD(self)) {
self0 = new_time_ex2(TIME_GET_HOUR(self), self0 = new_time_ex2(TIME_GET_HOUR(self),
@ -5065,10 +5071,11 @@ time_hash(PyObject *op)
return -1; return -1;
/* Reduce this to a hash of another object. */ /* Reduce this to a hash of another object. */
if (offset == Py_None) if (offset == Py_None) {
self->hashcode = generic_hash( hash = generic_hash(
(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE); (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
else { FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
} else {
PyObject *temp1, *temp2; PyObject *temp1, *temp2;
int seconds, microseconds; int seconds, microseconds;
assert(HASTZINFO(self)); assert(HASTZINFO(self));
@ -5087,12 +5094,13 @@ time_hash(PyObject *op)
Py_DECREF(offset); Py_DECREF(offset);
return -1; return -1;
} }
self->hashcode = PyObject_Hash(temp2); hash = PyObject_Hash(temp2);
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
Py_DECREF(temp2); Py_DECREF(temp2);
} }
Py_DECREF(offset); Py_DECREF(offset);
} }
return self->hashcode; return hash;
} }
/*[clinic input] /*[clinic input]
@ -6627,7 +6635,8 @@ static Py_hash_t
datetime_hash(PyObject *op) datetime_hash(PyObject *op)
{ {
PyDateTime_DateTime *self = PyDateTime_CAST(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; PyObject *offset, *self0;
if (DATE_GET_FOLD(self)) { if (DATE_GET_FOLD(self)) {
self0 = new_datetime_ex2(GET_YEAR(self), self0 = new_datetime_ex2(GET_YEAR(self),
@ -6652,10 +6661,11 @@ datetime_hash(PyObject *op)
return -1; return -1;
/* Reduce this to a hash of another object. */ /* Reduce this to a hash of another object. */
if (offset == Py_None) if (offset == Py_None) {
self->hashcode = generic_hash( hash = generic_hash(
(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE); (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
else { FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
} else {
PyObject *temp1, *temp2; PyObject *temp1, *temp2;
int days, seconds; int days, seconds;
@ -6679,12 +6689,13 @@ datetime_hash(PyObject *op)
Py_DECREF(offset); Py_DECREF(offset);
return -1; return -1;
} }
self->hashcode = PyObject_Hash(temp2); hash = PyObject_Hash(temp2);
FT_ATOMIC_STORE_SSIZE_RELAXED(self->hashcode, hash);
Py_DECREF(temp2); Py_DECREF(temp2);
} }
Py_DECREF(offset); Py_DECREF(offset);
} }
return self->hashcode; return hash;
} }
/*[clinic input] /*[clinic input]