diff -r 96e197d56a5c Include/pyatomic.h --- a/Include/pyatomic.h Wed Jan 14 14:49:16 2015 +0100 +++ b/Include/pyatomic.h Wed Jan 14 15:15:20 2015 +0100 @@ -34,7 +34,7 @@ typedef enum _Py_memory_order { } _Py_memory_order; typedef struct _Py_atomic_address { - _Atomic void *_value; + atomic_uintptr_t _value; } _Py_atomic_address; typedef struct _Py_atomic_int { diff -r 96e197d56a5c Modules/faulthandler.c --- a/Modules/faulthandler.c Wed Jan 14 14:49:16 2015 +0100 +++ b/Modules/faulthandler.c Wed Jan 14 15:15:20 2015 +0100 @@ -458,7 +458,7 @@ faulthandler_thread(void *unused) assert(st == PY_LOCK_FAILURE); /* get the thread holding the GIL, NULL if no thread hold the GIL */ - current = _Py_atomic_load_relaxed(&_PyThreadState_Current); + current = (PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current); write(thread.fd, thread.header, (int)thread.header_len); diff -r 96e197d56a5c Python/ceval_gil.h --- a/Python/ceval_gil.h Wed Jan 14 14:49:16 2015 +0100 +++ b/Python/ceval_gil.h Wed Jan 14 15:15:20 2015 +0100 @@ -111,7 +111,7 @@ static _Py_atomic_int gil_locked = {-1}; static unsigned long gil_switch_number = 0; /* Last PyThreadState holding / having held the GIL. This helps us know 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 the GIL is released. In addition, the mutex also protects the above @@ -191,7 +191,7 @@ static void drop_gil(PyThreadState *tsta if (_Py_atomic_load_relaxed(&gil_drop_request) && tstate != NULL) { MUTEX_LOCK(switch_mutex); /* Not switched yet => wait */ - if (_Py_atomic_load_relaxed(&gil_last_holder) == tstate) { + if ((PyThreadState *)_Py_atomic_load_relaxed(&gil_last_holder) == tstate) { RESET_GIL_DROP_REQUEST(); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take @@ -239,7 +239,7 @@ static void take_gil(PyThreadState *tsta _Py_atomic_store_relaxed(&gil_locked, 1); _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1); - if (tstate != _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); ++gil_switch_number; } diff -r 96e197d56a5c Python/pylifecycle.c --- a/Python/pylifecycle.c Wed Jan 14 14:49:16 2015 +0100 +++ b/Python/pylifecycle.c Wed Jan 14 15:15:20 2015 +0100 @@ -1258,7 +1258,7 @@ Py_FatalError(const char *msg) PyErr_PrintEx(0); } else { - tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current); + tstate = (PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current); if (tstate != NULL) { fputc('\n', stderr); fflush(stderr); diff -r 96e197d56a5c Python/pystate.c --- a/Python/pystate.c Wed Jan 14 14:49:16 2015 +0100 +++ b/Python/pystate.c Wed Jan 14 15:15:20 2015 +0100 @@ -48,9 +48,14 @@ static PyInterpreterState *interp_head = /* Assuming the current thread holds the GIL, this is the PyThreadState for the current thread. */ -_Py_atomic_address _PyThreadState_Current = {NULL}; +_Py_atomic_address _PyThreadState_Current = {0}; PyThreadFrameGetter _PyThreadState_GetFrame = NULL; +#define _PY_GET_CURRENT_THREAD_STATE \ + ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) +#define _PY_SET_CURRENT_THREAD_STATE(value) \ + _Py_atomic_store_relaxed(&_PyThreadState_Current, (value)) + #ifdef WITH_THREAD static void _PyGILState_NoteThreadState(PyThreadState* tstate); #endif @@ -403,7 +408,8 @@ tstate_delete_common(PyThreadState *tsta void PyThreadState_Delete(PyThreadState *tstate) { - if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current)) + + if (tstate == _PY_GET_CURRENT_THREAD_STATE) Py_FatalError("PyThreadState_Delete: tstate is still current"); #ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -417,12 +423,11 @@ PyThreadState_Delete(PyThreadState *tsta void PyThreadState_DeleteCurrent() { - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = _PY_GET_CURRENT_THREAD_STATE; if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL); + _PY_SET_CURRENT_THREAD_STATE(NULL); if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) PyThread_delete_key_value(autoTLSkey); tstate_delete_common(tstate); @@ -471,8 +476,7 @@ void PyThreadState * PyThreadState_Get(void) { - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = _PY_GET_CURRENT_THREAD_STATE; if (tstate == NULL) Py_FatalError("PyThreadState_Get: no current thread"); @@ -483,10 +487,9 @@ PyThreadState_Get(void) PyThreadState * PyThreadState_Swap(PyThreadState *newts) { - PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *oldts = _PY_GET_CURRENT_THREAD_STATE; - _Py_atomic_store_relaxed(&_PyThreadState_Current, newts); + _PY_SET_CURRENT_THREAD_STATE(newts); /* 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 builds. @@ -515,8 +518,7 @@ PyThreadState_Swap(PyThreadState *newts) PyObject * PyThreadState_GetDict(void) { - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = _PY_GET_CURRENT_THREAD_STATE; if (tstate == NULL) return NULL; @@ -662,7 +664,7 @@ PyThreadState_IsCurrent(PyThreadState *t { /* Must be the tstate for this thread */ assert(PyGILState_GetThisThreadState()==tstate); - return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current); + return tstate == _PY_GET_CURRENT_THREAD_STATE; } /* Internal initialization/finalization functions called by @@ -755,8 +757,7 @@ int PyGILState_Check(void) { /* can't use PyThreadState_Get() since it will assert that it has the GIL */ - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = _PY_GET_CURRENT_THREAD_STATE; return tstate && (tstate == PyGILState_GetThisThreadState()); }