Use Py_uintptr_t for atomic pointers
Issue #26161: Use Py_uintptr_t instead of void* for atomic pointers in pyatomic.h. Use atomic_uintptr_t when <stdatomic.h> is used. Using void* causes compilation warnings depending on which implementation of atomic types is used.
This commit is contained in:
parent
4b8b86c6d5
commit
244e12088d
|
@ -30,7 +30,7 @@ typedef enum _Py_memory_order {
|
||||||
} _Py_memory_order;
|
} _Py_memory_order;
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
typedef struct _Py_atomic_address {
|
||||||
_Atomic void *_value;
|
atomic_uintptr_t _value;
|
||||||
} _Py_atomic_address;
|
} _Py_atomic_address;
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
typedef struct _Py_atomic_int {
|
||||||
|
@ -61,7 +61,7 @@ typedef enum _Py_memory_order {
|
||||||
} _Py_memory_order;
|
} _Py_memory_order;
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
typedef struct _Py_atomic_address {
|
||||||
void *_value;
|
Py_uintptr_t _value;
|
||||||
} _Py_atomic_address;
|
} _Py_atomic_address;
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
typedef struct _Py_atomic_int {
|
||||||
|
@ -98,7 +98,7 @@ typedef enum _Py_memory_order {
|
||||||
} _Py_memory_order;
|
} _Py_memory_order;
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
typedef struct _Py_atomic_address {
|
||||||
void *_value;
|
Py_uintptr_t _value;
|
||||||
} _Py_atomic_address;
|
} _Py_atomic_address;
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
typedef struct _Py_atomic_int {
|
||||||
|
|
|
@ -111,7 +111,7 @@ static _Py_atomic_int gil_locked = {-1};
|
||||||
static unsigned long gil_switch_number = 0;
|
static unsigned long gil_switch_number = 0;
|
||||||
/* Last PyThreadState holding / having held the GIL. This helps us know
|
/* Last PyThreadState holding / having held the GIL. This helps us know
|
||||||
whether anyone else was scheduled after we dropped the GIL. */
|
whether anyone else was scheduled after we dropped the GIL. */
|
||||||
static _Py_atomic_address gil_last_holder = {NULL};
|
static _Py_atomic_address gil_last_holder = {0};
|
||||||
|
|
||||||
/* This condition variable allows one or several threads to wait until
|
/* This condition variable allows one or several threads to wait until
|
||||||
the GIL is released. In addition, the mutex also protects the above
|
the GIL is released. In addition, the mutex also protects the above
|
||||||
|
@ -142,7 +142,7 @@ static void create_gil(void)
|
||||||
#ifdef FORCE_SWITCHING
|
#ifdef FORCE_SWITCHING
|
||||||
COND_INIT(switch_cond);
|
COND_INIT(switch_cond);
|
||||||
#endif
|
#endif
|
||||||
_Py_atomic_store_relaxed(&gil_last_holder, NULL);
|
_Py_atomic_store_relaxed(&gil_last_holder, 0);
|
||||||
_Py_ANNOTATE_RWLOCK_CREATE(&gil_locked);
|
_Py_ANNOTATE_RWLOCK_CREATE(&gil_locked);
|
||||||
_Py_atomic_store_explicit(&gil_locked, 0, _Py_memory_order_release);
|
_Py_atomic_store_explicit(&gil_locked, 0, _Py_memory_order_release);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ static void drop_gil(PyThreadState *tstate)
|
||||||
/* Sub-interpreter support: threads might have been switched
|
/* Sub-interpreter support: threads might have been switched
|
||||||
under our feet using PyThreadState_Swap(). Fix the GIL last
|
under our feet using PyThreadState_Swap(). Fix the GIL last
|
||||||
holder variable so that our heuristics work. */
|
holder variable so that our heuristics work. */
|
||||||
_Py_atomic_store_relaxed(&gil_last_holder, tstate);
|
_Py_atomic_store_relaxed(&gil_last_holder, (Py_uintptr_t)tstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_LOCK(gil_mutex);
|
MUTEX_LOCK(gil_mutex);
|
||||||
|
@ -240,7 +240,7 @@ _ready:
|
||||||
_Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1);
|
_Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1);
|
||||||
|
|
||||||
if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder)) {
|
if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder)) {
|
||||||
_Py_atomic_store_relaxed(&gil_last_holder, tstate);
|
_Py_atomic_store_relaxed(&gil_last_holder, (Py_uintptr_t)tstate);
|
||||||
++gil_switch_number;
|
++gil_switch_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
#define GET_TSTATE() \
|
||||||
/* ensure that PyThreadState_GET() is a macro, not an alias to
|
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
|
||||||
* PyThreadState_Get() */
|
#define SET_TSTATE(value) \
|
||||||
# error "pystate.c must be compiled with Py_BUILD_CORE defined"
|
_Py_atomic_store_relaxed(&_PyThreadState_Current, (Py_uintptr_t)(value))
|
||||||
#endif
|
#define GET_INTERP_STATE() \
|
||||||
|
(GET_TSTATE()->interp)
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
CAUTION
|
CAUTION
|
||||||
|
@ -54,7 +56,7 @@ static PyInterpreterState *interp_head = NULL;
|
||||||
|
|
||||||
/* Assuming the current thread holds the GIL, this is the
|
/* Assuming the current thread holds the GIL, this is the
|
||||||
PyThreadState for the current thread. */
|
PyThreadState for the current thread. */
|
||||||
_Py_atomic_address _PyThreadState_Current = {NULL};
|
_Py_atomic_address _PyThreadState_Current = {0};
|
||||||
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
|
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
|
@ -260,7 +262,7 @@ PyObject*
|
||||||
PyState_FindModule(struct PyModuleDef* module)
|
PyState_FindModule(struct PyModuleDef* module)
|
||||||
{
|
{
|
||||||
Py_ssize_t index = module->m_base.m_index;
|
Py_ssize_t index = module->m_base.m_index;
|
||||||
PyInterpreterState *state = PyThreadState_GET()->interp;
|
PyInterpreterState *state = GET_INTERP_STATE();
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
if (module->m_slots) {
|
if (module->m_slots) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -284,7 +286,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def)
|
||||||
"PyState_AddModule called on module with slots");
|
"PyState_AddModule called on module with slots");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
state = PyThreadState_GET()->interp;
|
state = GET_INTERP_STATE();
|
||||||
if (!def)
|
if (!def)
|
||||||
return -1;
|
return -1;
|
||||||
if (!state->modules_by_index) {
|
if (!state->modules_by_index) {
|
||||||
|
@ -304,7 +306,7 @@ int
|
||||||
PyState_AddModule(PyObject* module, struct PyModuleDef* def)
|
PyState_AddModule(PyObject* module, struct PyModuleDef* def)
|
||||||
{
|
{
|
||||||
Py_ssize_t index;
|
Py_ssize_t index;
|
||||||
PyInterpreterState *state = PyThreadState_GET()->interp;
|
PyInterpreterState *state = GET_INTERP_STATE();
|
||||||
if (!def) {
|
if (!def) {
|
||||||
Py_FatalError("PyState_AddModule: Module Definition is NULL");
|
Py_FatalError("PyState_AddModule: Module Definition is NULL");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -331,7 +333,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
|
||||||
"PyState_RemoveModule called on module with slots");
|
"PyState_RemoveModule called on module with slots");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
state = PyThreadState_GET()->interp;
|
state = GET_INTERP_STATE();
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
Py_FatalError("PyState_RemoveModule: Module index invalid.");
|
Py_FatalError("PyState_RemoveModule: Module index invalid.");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -351,7 +353,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
|
||||||
void
|
void
|
||||||
_PyState_ClearModules(void)
|
_PyState_ClearModules(void)
|
||||||
{
|
{
|
||||||
PyInterpreterState *state = PyThreadState_GET()->interp;
|
PyInterpreterState *state = GET_INTERP_STATE();
|
||||||
if (state->modules_by_index) {
|
if (state->modules_by_index) {
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
|
for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
|
||||||
|
@ -429,7 +431,7 @@ tstate_delete_common(PyThreadState *tstate)
|
||||||
void
|
void
|
||||||
PyThreadState_Delete(PyThreadState *tstate)
|
PyThreadState_Delete(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
if (tstate == PyThreadState_GET())
|
if (tstate == GET_TSTATE())
|
||||||
Py_FatalError("PyThreadState_Delete: tstate is still current");
|
Py_FatalError("PyThreadState_Delete: tstate is still current");
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
|
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||||
|
@ -443,11 +445,11 @@ PyThreadState_Delete(PyThreadState *tstate)
|
||||||
void
|
void
|
||||||
PyThreadState_DeleteCurrent()
|
PyThreadState_DeleteCurrent()
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = GET_TSTATE();
|
||||||
if (tstate == NULL)
|
if (tstate == NULL)
|
||||||
Py_FatalError(
|
Py_FatalError(
|
||||||
"PyThreadState_DeleteCurrent: no current tstate");
|
"PyThreadState_DeleteCurrent: no current tstate");
|
||||||
_Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
|
SET_TSTATE(NULL);
|
||||||
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
|
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||||
PyThread_delete_key_value(autoTLSkey);
|
PyThread_delete_key_value(autoTLSkey);
|
||||||
tstate_delete_common(tstate);
|
tstate_delete_common(tstate);
|
||||||
|
@ -496,14 +498,14 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
|
||||||
PyThreadState *
|
PyThreadState *
|
||||||
_PyThreadState_UncheckedGet(void)
|
_PyThreadState_UncheckedGet(void)
|
||||||
{
|
{
|
||||||
return PyThreadState_GET();
|
return GET_TSTATE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PyThreadState *
|
PyThreadState *
|
||||||
PyThreadState_Get(void)
|
PyThreadState_Get(void)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = GET_TSTATE();
|
||||||
if (tstate == NULL)
|
if (tstate == NULL)
|
||||||
Py_FatalError("PyThreadState_Get: no current thread");
|
Py_FatalError("PyThreadState_Get: no current thread");
|
||||||
|
|
||||||
|
@ -514,9 +516,9 @@ PyThreadState_Get(void)
|
||||||
PyThreadState *
|
PyThreadState *
|
||||||
PyThreadState_Swap(PyThreadState *newts)
|
PyThreadState_Swap(PyThreadState *newts)
|
||||||
{
|
{
|
||||||
PyThreadState *oldts = PyThreadState_GET();
|
PyThreadState *oldts = GET_TSTATE();
|
||||||
|
|
||||||
_Py_atomic_store_relaxed(&_PyThreadState_Current, newts);
|
SET_TSTATE(newts);
|
||||||
/* It should not be possible for more than one thread state
|
/* It should not be possible for more than one thread state
|
||||||
to be used for a thread. Check this the best we can in debug
|
to be used for a thread. Check this the best we can in debug
|
||||||
builds.
|
builds.
|
||||||
|
@ -545,7 +547,7 @@ PyThreadState_Swap(PyThreadState *newts)
|
||||||
PyObject *
|
PyObject *
|
||||||
PyThreadState_GetDict(void)
|
PyThreadState_GetDict(void)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = GET_TSTATE();
|
||||||
if (tstate == NULL)
|
if (tstate == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -569,8 +571,7 @@ PyThreadState_GetDict(void)
|
||||||
|
|
||||||
int
|
int
|
||||||
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
|
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyInterpreterState *interp = GET_INTERP_STATE();
|
||||||
PyInterpreterState *interp = tstate->interp;
|
|
||||||
PyThreadState *p;
|
PyThreadState *p;
|
||||||
|
|
||||||
/* Although the GIL is held, a few C API functions can be called
|
/* Although the GIL is held, a few C API functions can be called
|
||||||
|
@ -691,7 +692,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
/* Must be the tstate for this thread */
|
/* Must be the tstate for this thread */
|
||||||
assert(PyGILState_GetThisThreadState()==tstate);
|
assert(PyGILState_GetThisThreadState()==tstate);
|
||||||
return tstate == PyThreadState_GET();
|
return tstate == GET_TSTATE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal initialization/finalization functions called by
|
/* Internal initialization/finalization functions called by
|
||||||
|
@ -783,7 +784,7 @@ PyGILState_GetThisThreadState(void)
|
||||||
int
|
int
|
||||||
PyGILState_Check(void)
|
PyGILState_Check(void)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = GET_TSTATE();
|
||||||
return tstate && (tstate == PyGILState_GetThisThreadState());
|
return tstate && (tstate == PyGILState_GetThisThreadState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue