Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-31403: Remove WITHOUT_THREADS from _decimal. #3474

Merged
merged 1 commit into from
Sep 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 1 addition & 94 deletions Modules/_decimal/_decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ typedef struct {
PyObject *traps;
PyObject *flags;
int capitals;
#ifndef WITHOUT_THREADS
PyThreadState *tstate;
#endif
} PyDecContextObject;

typedef struct {
Expand Down Expand Up @@ -124,15 +122,10 @@ incr_false(void)
}


#ifdef WITHOUT_THREADS
/* Default module context */
static PyObject *module_context = NULL;
#else
/* Key for thread state dictionary */
static PyObject *tls_context_key = NULL;
/* Invariant: NULL or the most recently accessed thread local context */
static PyDecContextObject *cached_context = NULL;
#endif

/* Template for creating new thread contexts, calling Context() without
* arguments and initializing the module_context on first access. */
Expand Down Expand Up @@ -1219,21 +1212,18 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED)
SdFlagAddr(self->flags) = &ctx->status;

CtxCaps(self) = 1;
#ifndef WITHOUT_THREADS
self->tstate = NULL;
#endif

return (PyObject *)self;
}

static void
context_dealloc(PyDecContextObject *self)
{
#ifndef WITHOUT_THREADS
if (self == cached_context) {
cached_context = NULL;
}
#endif

Py_XDECREF(self->traps);
Py_XDECREF(self->flags);
Py_TYPE(self)->tp_free(self);
Expand Down Expand Up @@ -1501,76 +1491,6 @@ static PyGetSetDef context_getsets [] =
/* Global, thread local and temporary contexts */
/******************************************************************************/

#ifdef WITHOUT_THREADS
/* Return borrowed reference to the current context. When compiled
* without threads, this is always the module context. */
static int module_context_set = 0;
static PyObject *
current_context(void)
{
/* In decimal.py, the module context is automatically initialized
* from the DefaultContext when it is first accessed. This
* complicates the code and has a speed penalty of 1-2%. */
if (module_context_set) {
return module_context;
}

*CTX(module_context) = *CTX(default_context_template);
CTX(module_context)->status = 0;
CTX(module_context)->newtrap = 0;
CtxCaps(module_context) = CtxCaps(default_context_template);

module_context_set = 1;
return module_context;
}

/* ctxobj := borrowed reference to the current context */
#define CURRENT_CONTEXT(ctxobj) \
ctxobj = current_context()

/* ctx := pointer to the mpd_context_t struct of the current context */
#define CURRENT_CONTEXT_ADDR(ctx) \
ctx = CTX(current_context())

/* Return a new reference to the current context */
static PyObject *
PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
{
PyObject *context;

CURRENT_CONTEXT(context);

Py_INCREF(context);
return context;
}

/* Set the module context to a new context, decrement old reference */
static PyObject *
PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
{
CONTEXT_CHECK(v);

/* If the new context is one of the templates, make a copy.
* This is the current behavior of decimal.py. */
if (v == default_context_template ||
v == basic_context_template ||
v == extended_context_template) {
v = context_copy(v, NULL);
if (v == NULL) {
return NULL;
}
CTX(v)->status = 0;
}
else {
Py_INCREF(v);
}

Py_XDECREF(module_context);
module_context = v;
module_context_set = 1;
Py_RETURN_NONE;
}
#else
/*
* Thread local storage currently has a speed penalty of about 4%.
* All functions that map Python's arithmetic operators to mpdecimal
Expand Down Expand Up @@ -1713,7 +1633,6 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
Py_DECREF(v);
Py_RETURN_NONE;
}
#endif

/* Context manager object for the 'with' statement. The manager
* owns one reference to the global (outer) context and one
Expand Down Expand Up @@ -5840,17 +5759,9 @@ PyInit__decimal(void)
CHECK_INT(PyModule_AddObject(m, "DefaultContext",
default_context_template));

#ifdef WITHOUT_THREADS
/* Init module context */
ASSIGN_PTR(module_context,
PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
Py_INCREF(Py_False);
CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_False));
#else
ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__"));
Py_INCREF(Py_True);
CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True));
#endif

/* Init basic context template */
ASSIGN_PTR(basic_context_template,
Expand Down Expand Up @@ -5906,12 +5817,8 @@ PyInit__decimal(void)
Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */
Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */
#ifdef WITHOUT_THREADS
Py_CLEAR(module_context); /* GCOV_NOT_REACHED */
#else
Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */
Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */
#endif
Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
Py_CLEAR(m); /* GCOV_NOT_REACHED */
Expand Down
34 changes: 15 additions & 19 deletions Modules/_decimal/tests/runall-memorydebugger.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/sh

#
# Purpose: test with and without threads, all machine configurations, pydebug,
# refleaks, release build and release build with valgrind.
# Purpose: test all machine configurations, pydebug, refleaks, release build
# and release build with valgrind.
#
# Synopsis: ./runall-memorydebugger.sh [--all-configs64 | --all-configs32]
#
Expand Down Expand Up @@ -57,8 +57,7 @@ print_config ()
cd ..

# test_decimal: refleak, regular and Valgrind tests
for args in "--without-threads" ""; do
for config in $CONFIGS; do
for config in $CONFIGS; do

unset PYTHON_DECIMAL_WITH_MACHINE
libmpdec_config=$config
Expand All @@ -70,24 +69,24 @@ for args in "--without-threads" ""; do
fi

############ refleak tests ###########
print_config "refleak tests: config=$config" $args
print_config "refleak tests: config=$config"
printf "\nbuilding python ...\n\n"

cd ../../
$GMAKE distclean > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1
$GMAKE | grep _decimal

printf "\n\n# ======================== refleak tests ===========================\n\n"
./python -m test -uall -R 2:2 test_decimal


############ regular tests ###########
print_config "regular tests: config=$config" $args
print_config "regular tests: config=$config"
printf "\nbuilding python ...\n\n"

$GMAKE distclean > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1
$GMAKE | grep _decimal

printf "\n\n# ======================== regular tests ===========================\n\n"
Expand All @@ -104,23 +103,21 @@ for args in "--without-threads" ""; do
esac
esac

print_config "valgrind tests: config=$config" $args
print_config "valgrind tests: config=$config"
printf "\nbuilding python ...\n\n"
$GMAKE distclean > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1
$GMAKE | grep _decimal

printf "\n\n# ======================== valgrind tests ===========================\n\n"
$valgrind ./python -m test -uall test_decimal

cd Modules/_decimal
done
done

# deccheck
cd ../../
for config in $CONFIGS; do
for args in "--without-threads" ""; do

unset PYTHON_DECIMAL_WITH_MACHINE
if [ X"$config" != X"auto" ]; then
Expand All @@ -129,22 +126,22 @@ for config in $CONFIGS; do
fi

############ debug ############
print_config "deccheck: config=$config --with-pydebug" $args
print_config "deccheck: config=$config --with-pydebug"
printf "\nbuilding python ...\n\n"

$GMAKE distclean > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug > /dev/null 2>&1
$GMAKE | grep _decimal

printf "\n\n# ========================== debug ===========================\n\n"
./python Modules/_decimal/tests/deccheck.py

########### regular ###########
print_config "deccheck: config=$config " $args
print_config "deccheck: config=$config "
printf "\nbuilding python ...\n\n"

$GMAKE distclean > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" > /dev/null 2>&1
$GMAKE | grep _decimal

printf "\n\n# ======================== regular ===========================\n\n"
Expand All @@ -160,16 +157,15 @@ for config in $CONFIGS; do
esac
esac

print_config "valgrind deccheck: config=$config " $args
print_config "valgrind deccheck: config=$config "
printf "\nbuilding python ...\n\n"

$GMAKE distclean > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1
./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc > /dev/null 2>&1
$GMAKE | grep _decimal

printf "\n\n# ======================== valgrind ==========================\n\n"
$valgrind ./python Modules/_decimal/tests/deccheck.py
done
done


Expand Down