Index: Include/ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.52 diff -c -r2.52 ceval.h *** Include/ceval.h 27 Jun 2004 15:43:12 -0000 2.52 --- Include/ceval.h 10 Oct 2004 16:30:33 -0000 *************** *** 120,125 **** --- 120,126 ---- #ifdef WITH_THREAD + PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); PyAPI_FUNC(void) PyEval_InitThreads(void); PyAPI_FUNC(void) PyEval_AcquireLock(void); PyAPI_FUNC(void) PyEval_ReleaseLock(void); Index: Python/ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.417 diff -c -r2.417 ceval.c *** Python/ceval.c 16 Sep 2004 16:41:57 -0000 2.417 --- Python/ceval.c 10 Oct 2004 16:31:09 -0000 *************** *** 16,22 **** #include ! #ifndef WITH_TSC #define rdtscll(var) #else /*WITH_TSC defined*/ --- 16,22 ---- #include ! #ifndef WITH_TSC #define rdtscll(var) #else /*WITH_TSC defined*/ *************** *** 39,45 **** asm volatile ("mftbu %0" : "=r" (tbu2)); if (__builtin_expect(tbu != tbu2, 0)) goto loop; ! /* The slightly peculiar way of writing the next lines is compiled better by GCC than any other way I tried. */ ((long*)(v))[0] = tbu; ((long*)(v))[1] = tb; --- 39,45 ---- asm volatile ("mftbu %0" : "=r" (tbu2)); if (__builtin_expect(tbu != tbu2, 0)) goto loop; ! /* The slightly peculiar way of writing the next lines is compiled better by GCC than any other way I tried. */ ((long*)(v))[0] = tbu; ((long*)(v))[1] = tb; *************** *** 51,57 **** #endif ! void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1, uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1) { uint64 intr, inst, loop; --- 51,57 ---- #endif ! void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1, uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1) { uint64 intr, inst, loop; *************** *** 208,213 **** --- 208,219 ---- static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */ static long main_thread = 0; + int + PyEval_ThreadsInitialized(void) + { + return interpreter_lock != 0; + } + void PyEval_InitThreads(void) { *************** *** 222,239 **** --- 228,251 ---- void PyEval_AcquireLock(void) { + if (!interpreter_lock) + return; PyThread_acquire_lock(interpreter_lock, 1); } void PyEval_ReleaseLock(void) { + if (!interpreter_lock) + return; PyThread_release_lock(interpreter_lock); } void PyEval_AcquireThread(PyThreadState *tstate) { + if (!interpreter_lock) + return; if (tstate == NULL) Py_FatalError("PyEval_AcquireThread: NULL new thread state"); /* Check someone has called PyEval_InitThreads() to create the lock */ *************** *** 247,252 **** --- 259,266 ---- void PyEval_ReleaseThread(PyThreadState *tstate) { + if (!interpreter_lock) + return; if (tstate == NULL) Py_FatalError("PyEval_ReleaseThread: NULL thread state"); if (PyThreadState_Swap(NULL) != tstate) *************** *** 281,287 **** PyThreadState * PyEval_SaveThread(void) { ! PyThreadState *tstate = PyThreadState_Swap(NULL); if (tstate == NULL) Py_FatalError("PyEval_SaveThread: NULL tstate"); #ifdef WITH_THREAD --- 295,304 ---- PyThreadState * PyEval_SaveThread(void) { ! PyThreadState *tstate; ! if (!interpreter_lock) ! return; ! tstate = PyThreadState_Swap(NULL); if (tstate == NULL) Py_FatalError("PyEval_SaveThread: NULL tstate"); #ifdef WITH_THREAD *************** *** 294,299 **** --- 311,318 ---- void PyEval_RestoreThread(PyThreadState *tstate) { + if (!interpreter_lock) + return; if (tstate == NULL) Py_FatalError("PyEval_RestoreThread: NULL tstate"); #ifdef WITH_THREAD *************** *** 545,551 **** inst0 -- beginning of switch statement for opcode dispatch inst1 -- end of switch statement (may be skipped) loop0 -- the top of the mainloop ! loop1 -- place where control returns again to top of mainloop (may be skipped) intr1 -- beginning of long interruption intr2 -- end of long interruption --- 564,570 ---- inst0 -- beginning of switch statement for opcode dispatch inst1 -- end of switch statement (may be skipped) loop0 -- the top of the mainloop ! loop1 -- place where control returns again to top of mainloop (may be skipped) intr1 -- beginning of long interruption intr2 -- end of long interruption *************** *** 4083,4089 **** result = PyObject_CallFunction(metaclass, "OOO", name, bases, methods); Py_DECREF(metaclass); if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { ! /* A type error here likely means that the user passed in a base that was not a class (such the random module instead of the random.random type). Help them out with by augmenting the error message with more information.*/ --- 4102,4108 ---- result = PyObject_CallFunction(metaclass, "OOO", name, bases, methods); Py_DECREF(metaclass); if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { ! /* A type error here likely means that the user passed in a base that was not a class (such the random module instead of the random.random type). Help them out with by augmenting the error message with more information.*/ *************** *** 4223,4229 **** { /* This function implements 'variable += expr' when both arguments are strings. */ ! if (v->ob_refcnt == 2) { /* In the common case, there are 2 references to the value * stored in 'variable' when the += is performed: one on the --- 4242,4248 ---- { /* This function implements 'variable += expr' when both arguments are strings. */ ! if (v->ob_refcnt == 2) { /* In the common case, there are 2 references to the value * stored in 'variable' when the += is performed: one on the Index: Python/pystate.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v retrieving revision 2.37 diff -c -r2.37 pystate.c *** Python/pystate.c 10 Oct 2004 05:30:40 -0000 2.37 --- Python/pystate.c 10 Oct 2004 16:31:16 -0000 *************** *** 442,447 **** --- 442,450 ---- called Py_Initialize() and usually PyEval_InitThreads(). */ assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */ + if (!PyEval_ThreadsInitialized()) { + return; /* Short-circuit if we're not multi-threaded */ + } tcur = PyThread_get_key_value(autoTLSkey); if (tcur == NULL) { /* Create a new thread state for this thread */ *************** *** 468,474 **** void PyGILState_Release(PyGILState_STATE oldstate) { ! PyThreadState *tcur = PyThread_get_key_value(autoTLSkey); if (tcur == NULL) Py_FatalError("auto-releasing thread-state, " "but no thread-state for this thread"); --- 471,481 ---- void PyGILState_Release(PyGILState_STATE oldstate) { ! PyThreadState *tcur; ! if (!PyEval_ThreadsInitialized()) { ! return; /* Short-circuit if we're not multi-threaded */ ! } ! tcur = PyThread_get_key_value(autoTLSkey); if (tcur == NULL) Py_FatalError("auto-releasing thread-state, " "but no thread-state for this thread");