Massive changes for separate thread state management.
All per-thread globals are moved into a struct which is manipulated
separately.
diff --git a/Include/Python.h b/Include/Python.h
index ffc7e2c..d13003d 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -95,6 +95,8 @@
 #include "import.h"
 #include "bltinmodule.h"
 
+#include "pystate.h"
+
 #include "abstract.h"
 
 #define PyArg_GetInt(v, a)	PyArg_Parse((v), "i", (a))
diff --git a/Include/frameobject.h b/Include/frameobject.h
index 22cc23c..157cba3 100644
--- a/Include/frameobject.h
+++ b/Include/frameobject.h
@@ -52,6 +52,8 @@
 	PyObject *f_locals;	/* local symbol table (PyDictObject) */
 	PyObject **f_valuestack; /* points after the last local */
 	PyObject *f_trace;	/* Trace function */
+	PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
+	PyThreadState *f_tstate;
 	int f_lasti;		/* Last instruction if called */
 	int f_lineno;		/* Current line number */
 	int f_restricted;	/* Flag set if restricted operations
@@ -71,7 +73,7 @@
 #define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type)
 
 PyFrameObject * PyFrame_New
-	Py_PROTO((PyFrameObject *, PyCodeObject *,
+	Py_PROTO((PyThreadState *, PyCodeObject *,
 		  PyObject *, PyObject *));
 
 
diff --git a/Include/pystate.h b/Include/pystate.h
new file mode 100644
index 0000000..514c46d
--- /dev/null
+++ b/Include/pystate.h
@@ -0,0 +1,134 @@
+#ifndef Py_PYSTATE_H
+#define Py_PYSTATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Thread and interpreter state structures and their interfaces */
+
+
+/* State shared between threads */
+
+#define NEXITFUNCS 32
+
+typedef struct _is {
+
+	PyObject *import_modules;
+	PyObject *sysdict;
+
+	int nthreads;
+
+	void (*exitfuncs[NEXITFUNCS])();
+	int nexitfuncs;
+
+} PyInterpreterState;
+
+
+/* State unique per thread */
+
+struct _frame; /* Avoid including frameobject.h */
+
+typedef struct _ts {
+
+	PyInterpreterState *interpreter_state;
+
+	struct _frame *frame;
+	int recursion_depth;
+	int ticker;
+	int tracing;
+
+	PyObject *sys_profilefunc;
+	PyObject *sys_tracefunc;
+	int sys_checkinterval;
+
+	PyObject *curexc_type;
+	PyObject *curexc_value;
+	PyObject *curexc_traceback;
+
+	PyObject *exc_type;
+	PyObject *exc_value;
+	PyObject *exc_traceback;
+
+	/* XXX Other state that should be here:
+	   - signal handlers
+	   - low-level "pending calls"
+	   Problem with both is that they may be referenced from
+	   interrupt handlers where there is no clear concept of a
+	   "current thread"???
+	*/
+
+} PyThreadState;
+
+
+PyInterpreterState *PyInterpreterState_New(void);
+void PyInterpreterState_Delete(PyInterpreterState *);
+
+PyThreadState *PyThreadState_New(PyInterpreterState *);
+void PyThreadState_Delete(PyThreadState *);
+
+PyThreadState *PyThreadState_Get(void);
+PyThreadState *PyThreadState_Swap(PyThreadState *);
+
+/* Some background.
+
+   There are lots of issues here.
+
+   First, we can build Python without threads, with threads, or (when
+   Greg Stein's mods are out of beta, on some platforms) with free
+   threading.
+
+   Next, assuming some form of threading is used, there can be several
+   kinds of threads.  Python code can create threads with the thread
+   module.  C code can create threads with the interface defined in
+   python's "thread.h".  Or C code can create threads directly with
+   the OS threads interface (e.g. Solaris threads, SGI threads or
+   pthreads, whatever is being used, as long as it's the same that
+   Python is configured for).
+
+   Next, let's discuss sharing of interpreter state between threads.
+   The exception state (sys.exc_* currently) should never be shared
+   between threads, because it is stack frame specific.  The contents
+   of the sys module, in particular sys.modules and sys.path, are
+   generally shared between threads.  But occasionally it is useful to
+   have separate module collections, e.g. when threads originate in C
+   code and are used to execute unrelated Python scripts.
+   (Traditionally, one would use separate processes for this, but
+   there are lots of reasons why threads are attractive.)
+
+*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PYSTATE_H */
diff --git a/Include/pythread.h b/Include/pythread.h
index f42e52f..09415c9 100644
--- a/Include/pythread.h
+++ b/Include/pythread.h
@@ -35,6 +35,10 @@
 #define up_sema PyThread_up_sema
 #define exit_prog PyThread_exit_prog
 #define _exit_prog PyThread__exit_prog
+#define create_key PyThread_create_key
+#define delete_key PyThread_delete_key
+#define get_key_value PyThread_get_key_value
+#define set_key_value PyThread_set_key_value
 
 
 void init_thread Py_PROTO((void));
@@ -62,6 +66,11 @@
 void _exit_prog Py_PROTO((int));
 #endif
 
+int create_key Py_PROTO((void));
+void delete_key Py_PROTO((int));
+int set_key_value Py_PROTO((int, void *));
+void * get_key_value Py_PROTO((int));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Include/thread.h b/Include/thread.h
index f42e52f..09415c9 100644
--- a/Include/thread.h
+++ b/Include/thread.h
@@ -35,6 +35,10 @@
 #define up_sema PyThread_up_sema
 #define exit_prog PyThread_exit_prog
 #define _exit_prog PyThread__exit_prog
+#define create_key PyThread_create_key
+#define delete_key PyThread_delete_key
+#define get_key_value PyThread_get_key_value
+#define set_key_value PyThread_set_key_value
 
 
 void init_thread Py_PROTO((void));
@@ -62,6 +66,11 @@
 void _exit_prog Py_PROTO((int));
 #endif
 
+int create_key Py_PROTO((void));
+void delete_key Py_PROTO((int));
+int set_key_value Py_PROTO((int, void *));
+void * get_key_value Py_PROTO((int));
+
 #ifdef __cplusplus
 }
 #endif