bpo-25658: Implement PEP 539 for Thread Specific Storage (TSS) API (GH-1362)

See PEP 539 for details.

Highlights of changes:

- Add Thread Specific Storage (TSS) API
- Document the Thread Local Storage (TLS) API as deprecated
- Update code that used TLS API to use TSS API
This commit is contained in:
Masayuki Yamamoto 2017-10-06 19:41:34 +09:00 committed by Nick Coghlan
parent b8ab9d3fc8
commit 731e189014
18 changed files with 651 additions and 108 deletions

View file

@ -167,14 +167,7 @@ tracemalloc_error(const char *format, ...)
#if defined(TRACE_RAW_MALLOC)
#define REENTRANT_THREADLOCAL
/* If your OS does not provide native thread local storage, you can implement
it manually using a lock. Functions of thread.c cannot be used because
they use PyMem_RawMalloc() which leads to a reentrant call. */
#if !(defined(_POSIX_THREADS) || defined(NT_THREADS))
# error "need native thread local storage (TLS)"
#endif
static int tracemalloc_reentrant_key = -1;
static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT;
/* Any non-NULL pointer can be used */
#define REENTRANT Py_True
@ -184,8 +177,8 @@ get_reentrant(void)
{
void *ptr;
assert(tracemalloc_reentrant_key != -1);
ptr = PyThread_get_key_value(tracemalloc_reentrant_key);
assert(PyThread_tss_is_created(&tracemalloc_reentrant_key));
ptr = PyThread_tss_get(&tracemalloc_reentrant_key);
if (ptr != NULL) {
assert(ptr == REENTRANT);
return 1;
@ -198,15 +191,15 @@ static void
set_reentrant(int reentrant)
{
assert(reentrant == 0 || reentrant == 1);
assert(tracemalloc_reentrant_key != -1);
assert(PyThread_tss_is_created(&tracemalloc_reentrant_key));
if (reentrant) {
assert(!get_reentrant());
PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT);
PyThread_tss_set(&tracemalloc_reentrant_key, REENTRANT);
}
else {
assert(get_reentrant());
PyThread_set_key_value(tracemalloc_reentrant_key, NULL);
PyThread_tss_set(&tracemalloc_reentrant_key, NULL);
}
}
@ -975,8 +968,7 @@ tracemalloc_init(void)
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
#ifdef REENTRANT_THREADLOCAL
tracemalloc_reentrant_key = PyThread_create_key();
if (tracemalloc_reentrant_key == -1) {
if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) {
#ifdef MS_WINDOWS
PyErr_SetFromWindowsErr(0);
#else
@ -1061,8 +1053,7 @@ tracemalloc_deinit(void)
#endif
#ifdef REENTRANT_THREADLOCAL
PyThread_delete_key(tracemalloc_reentrant_key);
tracemalloc_reentrant_key = -1;
PyThread_tss_delete(&tracemalloc_reentrant_key);
#endif
Py_XDECREF(unknown_filename);