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:
Skip Montanaro 2002-09-03 20:10:45 +00:00
parent d229b3ae04
commit d581d7792b
5 changed files with 15 additions and 10 deletions

View File

@ -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

View File

@ -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;

View File

@ -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; } \
} }

View File

@ -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;

View File

@ -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;