replace thread state objects' ticker and checkinterval fields with two
globals, _Py_Ticker and _Py_CheckInterval. This also implements Jeremy's shortcut in Py_AddPendingCall that zeroes out _Py_Ticker. This allows the test in the main loop to only test a single value. The gory details are at http://python.org/sf/602191
This commit is contained in:
parent
d229b3ae04
commit
d581d7792b
|
@ -48,6 +48,10 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void);
|
||||||
PyAPI_FUNC(char *) PyEval_GetFuncName(PyObject *);
|
PyAPI_FUNC(char *) PyEval_GetFuncName(PyObject *);
|
||||||
PyAPI_FUNC(char *) PyEval_GetFuncDesc(PyObject *);
|
PyAPI_FUNC(char *) PyEval_GetFuncDesc(PyObject *);
|
||||||
|
|
||||||
|
/* this used to be handled on a per-thread basis - now just two globals */
|
||||||
|
PyAPI_DATA(volatile int) _Py_Ticker;
|
||||||
|
PyAPI_DATA(int) _Py_CheckInterval;
|
||||||
|
|
||||||
/* Interface for threads.
|
/* Interface for threads.
|
||||||
|
|
||||||
A module that plans to do a blocking system call (or something else
|
A module that plans to do a blocking system call (or something else
|
||||||
|
|
|
@ -22,7 +22,6 @@ typedef struct _is {
|
||||||
PyObject *sysdict;
|
PyObject *sysdict;
|
||||||
PyObject *builtins;
|
PyObject *builtins;
|
||||||
|
|
||||||
int checkinterval;
|
|
||||||
#ifdef HAVE_DLOPEN
|
#ifdef HAVE_DLOPEN
|
||||||
int dlopenflags;
|
int dlopenflags;
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,7 +49,6 @@ typedef struct _ts {
|
||||||
|
|
||||||
struct _frame *frame;
|
struct _frame *frame;
|
||||||
int recursion_depth;
|
int recursion_depth;
|
||||||
int ticker;
|
|
||||||
int tracing;
|
int tracing;
|
||||||
int use_tracing;
|
int use_tracing;
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,9 @@ static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit);
|
||||||
static PyLongObject *divrem1(PyLongObject *, digit, digit *);
|
static PyLongObject *divrem1(PyLongObject *, digit, digit *);
|
||||||
static PyObject *long_format(PyObject *aa, int base, int addL);
|
static PyObject *long_format(PyObject *aa, int base, int addL);
|
||||||
|
|
||||||
static int ticker; /* XXX Could be shared with ceval? */
|
|
||||||
|
|
||||||
#define SIGCHECK(PyTryBlock) \
|
#define SIGCHECK(PyTryBlock) \
|
||||||
if (--ticker < 0) { \
|
if (--_Py_Ticker < 0) { \
|
||||||
ticker = 100; \
|
_Py_Ticker = _Py_CheckInterval; \
|
||||||
if (PyErr_CheckSignals()) { PyTryBlock; } \
|
if (PyErr_CheckSignals()) { PyTryBlock; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,8 @@ Py_AddPendingCall(int (*func)(void *), void *arg)
|
||||||
pendingcalls[i].func = func;
|
pendingcalls[i].func = func;
|
||||||
pendingcalls[i].arg = arg;
|
pendingcalls[i].arg = arg;
|
||||||
pendinglast = j;
|
pendinglast = j;
|
||||||
|
|
||||||
|
_Py_Ticker = 0;
|
||||||
things_to_do = 1; /* Signal main loop */
|
things_to_do = 1; /* Signal main loop */
|
||||||
busy = 0;
|
busy = 0;
|
||||||
/* XXX End critical section */
|
/* XXX End critical section */
|
||||||
|
@ -465,6 +467,10 @@ enum why_code {
|
||||||
static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
|
static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
|
||||||
static int unpack_iterable(PyObject *, int, PyObject **);
|
static int unpack_iterable(PyObject *, int, PyObject **);
|
||||||
|
|
||||||
|
/* for manipulating the thread switch and periodic "stuff" - used to be
|
||||||
|
per thread, now just a pair o' globals */
|
||||||
|
int _Py_CheckInterval = 10;
|
||||||
|
volatile int _Py_Ticker = 10;
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
|
PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
|
||||||
|
@ -669,8 +675,8 @@ eval_frame(PyFrameObject *f)
|
||||||
async I/O handler); see Py_AddPendingCall() and
|
async I/O handler); see Py_AddPendingCall() and
|
||||||
Py_MakePendingCalls() above. */
|
Py_MakePendingCalls() above. */
|
||||||
|
|
||||||
if (things_to_do || --tstate->ticker < 0) {
|
if (--_Py_Ticker < 0) {
|
||||||
tstate->ticker = tstate->interp->checkinterval;
|
_Py_Ticker = _Py_CheckInterval;
|
||||||
if (things_to_do) {
|
if (things_to_do) {
|
||||||
if (Py_MakePendingCalls() < 0) {
|
if (Py_MakePendingCalls() < 0) {
|
||||||
why = WHY_EXCEPTION;
|
why = WHY_EXCEPTION;
|
||||||
|
|
|
@ -352,8 +352,7 @@ and return. See the profiler chapter in the library manual."
|
||||||
static PyObject *
|
static PyObject *
|
||||||
sys_setcheckinterval(PyObject *self, PyObject *args)
|
sys_setcheckinterval(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = PyThreadState_Get();
|
if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))
|
||||||
if (!PyArg_ParseTuple(args, "i:setcheckinterval", &tstate->interp->checkinterval))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
|
Loading…
Reference in New Issue