diff --git a/src/interpret.h b/src/interpret.h
index f400097679d290bcc265e87859494ec6b1f5f2b9..c4d060539909831b8dfae41103bc26a43368c8d9 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.47 2000/07/07 00:59:21 hubbe Exp $
+ * $Id: interpret.h,v 1.48 2000/07/07 01:19:04 hubbe Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -18,7 +18,7 @@ struct Pike_interpreter {
   /* Swapped variables */
   struct svalue *stack_pointer;
   struct svalue *evaluator_stack;
-  struct svalue **mark_sp;
+  struct svalue **mark_stack_pointer;
   struct svalue **mark_stack;
   struct pike_frame *frame_pointer;
   int evaluator_stack_malloced;
@@ -248,7 +248,7 @@ extern struct Pike_interpreter Pike_interpreter;
 
 #define Pike_sp Pike_interpreter.stack_pointer
 #define Pike_fp Pike_interpreter.frame_pointer
-#define Pike_mark_sp Pike_interpreter.mark_sp
+#define Pike_mark_sp Pike_interpreter.mark_stack_pointer
 #ifdef PIKE_THREADS
 #define Pike_thread_id Pike_interpreter.thread_id
 #endif
@@ -259,6 +259,7 @@ extern struct Pike_interpreter Pike_interpreter;
 #define stack_size Pike_stack_size
 #define sp Pike_sp
 #define fp Pike_fp
+#define mark_sp Pike_mark_sp
 
 #endif /* !NO_PIKE_SHORTHAND */
 
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index 188c386ec10d65e31cdbdf3afa3e6ff551adebc7..2776299eec0f97dcbf4a416580d334800ae8469d 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -1,5 +1,5 @@
 /*
- * $Id: interpret_functions.h,v 1.24 2000/06/20 23:31:25 hubbe Exp $
+ * $Id: interpret_functions.h,v 1.25 2000/07/07 01:24:14 hubbe Exp $
  *
  * Opcode definitions for the interpreter.
  */
@@ -787,7 +787,7 @@ OPCODE0(F_MARK,"mark")
   *(Pike_mark_sp++)=Pike_sp;
 BREAK;
 
-OPCODE1(F_MARK_X, "mark sp-X")
+OPCODE1(F_MARK_X, "mark Pike_sp-X")
   *(Pike_mark_sp++)=Pike_sp-arg1;
 BREAK;
 
@@ -998,7 +998,7 @@ BREAK;
 
 OPCODE1(F_CALL_LFUN_AND_RETURN,"call lfun & return")
 {
-  INT32 args=sp - *--Pike_mark_sp;
+  INT32 args=Pike_sp - *--Pike_mark_sp;
 
   if(Pike_fp->expendible >= Pike_sp-args)
   {
@@ -1025,7 +1025,7 @@ BREAK
       CASE(F_RETURN_LOCAL);
       instr=GET_ARG();
 #if defined(PIKE_DEBUG) && defined(GC2)
-      /* special case! mark_stack may be invalid at the time we
+      /* special case! Pike_interpreter.mark_stack may be invalid at the time we
        * call return -1, so we must call the callbacks here to
        * prevent false alarms! /Hubbe
        */
@@ -1139,24 +1139,24 @@ OPCODE0(F_ADD, "+")
 BREAK;
 
 OPCODE0(F_ADD_INTS, "int+int")
-  if(sp[-1].type == T_INT && sp[-2].type == T_INT 
+  if(Pike_sp[-1].type == T_INT && Pike_sp[-2].type == T_INT 
 #ifdef AUTO_BIGNUM
-      && (!INT_TYPE_ADD_OVERFLOW(sp[-1].u.integer, sp[-2].u.integer))
+      && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer))
 #endif
     )
   {
-    sp[-2].u.integer+=sp[-1].u.integer;
-    sp--;
+    Pike_sp[-2].u.integer+=Pike_sp[-1].u.integer;
+    Pike_sp--;
   }else{
     f_add(2);
   }
 BREAK;
 
 OPCODE0(F_ADD_FLOATS, "float+float")
-  if(sp[-1].type == T_FLOAT && sp[-2].type == T_FLOAT)
+  if(Pike_sp[-1].type == T_FLOAT && Pike_sp[-2].type == T_FLOAT)
   {
-    sp[-2].u.float_number+=sp[-1].u.float_number;
-    sp--;
+    Pike_sp[-2].u.float_number+=Pike_sp[-1].u.float_number;
+    Pike_sp--;
   }else{
     f_add(2);
   }
@@ -1191,13 +1191,13 @@ OPCODE0(F_MOD, "%")
 BREAK;
 
 OPCODE1(F_ADD_INT, "add integer")
-  if(sp[-1].type == T_INT
+  if(Pike_sp[-1].type == T_INT
 #ifdef AUTO_BIGNUM
-      && (!INT_TYPE_ADD_OVERFLOW(sp[-1].u.integer, arg1))
+      && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, arg1))
 #endif
      )
   {
-    sp[-1].u.integer+=arg1;
+    Pike_sp[-1].u.integer+=arg1;
   }else{
     push_int(arg1);
     f_add(2);
@@ -1205,13 +1205,13 @@ OPCODE1(F_ADD_INT, "add integer")
 BREAK;
 
 OPCODE1(F_ADD_NEG_INT, "add -integer")
-  if(sp[-1].type == T_INT
+  if(Pike_sp[-1].type == T_INT
 #ifdef AUTO_BIGNUM
-      && (!INT_TYPE_ADD_OVERFLOW(sp[-1].u.integer, -arg1))
+      && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, -arg1))
 #endif
      )
   {
-    sp[-1].u.integer-=arg1;
+    Pike_sp[-1].u.integer-=arg1;
   }else{
     push_int(-arg1);
     f_add(2);
@@ -1522,17 +1522,17 @@ OPCODE0_JUMP(F_RECUR,"recur")
 {
   int x,num_locals,args;
   char *addr;
-  struct svalue *expendible=fp->expendible;
-  struct svalue *locals=fp->locals;
+  struct svalue *expendible=Pike_fp->expendible;
+  struct svalue *locals=Pike_fp->locals;
   struct svalue *save_sp, **save_mark_sp;
 
   fast_check_threads_etc(6);
   check_c_stack(8192);
   check_stack(256);
 
-  save_sp=fp->expendible=fp->locals=*--Pike_mark_sp;
-  args=sp-fp->locals;
-  save_mark_sp=mark_sp;
+  save_sp=Pike_fp->expendible=Pike_fp->locals=*--Pike_mark_sp;
+  args=Pike_sp-Pike_fp->locals;
+  save_mark_sp=Pike_mark_sp;
 
   addr=pc+EXTRACT_INT(pc);
   num_locals=EXTRACT_UCHAR(addr-2);
@@ -1542,28 +1542,28 @@ OPCODE0_JUMP(F_RECUR,"recur")
     fatal("Wrong number of arguments in F_RECUR %d!=%d\n",args,EXTRACT_UCHAR(addr-1));
 #endif
 
-  clear_svalues(sp, num_locals - args);
-  sp += num_locals - args;
+  clear_svalues(Pike_sp, num_locals - args);
+  Pike_sp += num_locals - args;
 
   x=eval_instruction(addr);
 #ifdef PIKE_DEBUG
-  if(mark_sp < save_mark_sp)
-    fatal("mark sp underflow in F_RECUR.\n");
+  if(Pike_mark_sp < save_mark_sp)
+    fatal("mark Pike_sp underflow in F_RECUR.\n");
 #endif
-  mark_sp=save_mark_sp;
+  Pike_mark_sp=save_mark_sp;
   if(x!=-1) mega_apply(APPLY_STACK, x, 0,0);
   pc+=sizeof(INT32);
-  if(save_sp+1 < sp)
+  if(save_sp+1 < Pike_sp)
   {
-    assign_svalue(save_sp,sp-1);
-    pop_n_elems(sp-save_sp-1);
+    assign_svalue(save_sp,Pike_sp-1);
+    pop_n_elems(Pike_sp-save_sp-1);
   }
-  fp->expendible=expendible;
-  fp->locals=locals;
+  Pike_fp->expendible=expendible;
+  Pike_fp->locals=locals;
   print_return_value();
 #ifdef PIKE_DEBUG
-  if(sp != save_sp+1)
-    fatal("Stack whack in F_RECUR sp=%p, expected=%p\n",sp,save_sp+1);
+  if(Pike_sp != save_sp+1)
+    fatal("Stack whack in F_RECUR Pike_sp=%p, expected=%p\n",Pike_sp,save_sp+1);
 #endif
 }
 BREAK
@@ -1574,8 +1574,8 @@ OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded")
   int x,num_locals,args;
   char *addr;
 
-  struct svalue *expendible=fp->expendible;
-  struct svalue *locals=fp->locals;
+  struct svalue *expendible=Pike_fp->expendible;
+  struct svalue *locals=Pike_fp->locals;
   struct svalue *save_sp, **save_mark_sp;
 
   /* FIXME:
@@ -1583,7 +1583,7 @@ OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded")
    * overloaded or not. Currently it only tests if
    * this context is inherited or not.
    */
-  if(fp->current_object->prog != fp->context.prog)
+  if(Pike_fp->current_object->prog != Pike_fp->context.prog)
   {
     apply_low(Pike_fp->current_object,
 	      arg1+Pike_fp->context.identifier_level,
@@ -1594,9 +1594,9 @@ OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded")
     check_c_stack(8192);
     check_stack(256);
     
-    save_sp=fp->expendible=fp->locals=*--Pike_mark_sp;
-    args=sp-fp->locals;
-    save_mark_sp=mark_sp;
+    save_sp=Pike_fp->expendible=Pike_fp->locals=*--Pike_mark_sp;
+    args=Pike_sp-Pike_fp->locals;
+    save_mark_sp=Pike_mark_sp;
     
     addr=pc+EXTRACT_INT(pc);
     num_locals=EXTRACT_UCHAR(addr-2);
@@ -1606,40 +1606,40 @@ OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded")
       fatal("Wrong number of arguments in F_RECUR %d!=%d\n",args,EXTRACT_UCHAR(addr-1));
 #endif
     
-    clear_svalues(sp, num_locals - args);
-    sp += num_locals - args;
+    clear_svalues(Pike_sp, num_locals - args);
+    Pike_sp += num_locals - args;
     
     x=eval_instruction(addr);
 #ifdef PIKE_DEBUG
-  if(mark_sp < save_mark_sp)
-    fatal("mark sp underflow in F_RECUR.\n");
+  if(Pike_mark_sp < save_mark_sp)
+    fatal("mark Pike_sp underflow in F_RECUR.\n");
 #endif
-    mark_sp=save_mark_sp;
+    Pike_mark_sp=save_mark_sp;
     if(x!=-1) mega_apply(APPLY_STACK, x, 0,0);
     pc+=sizeof(INT32);
-    if(save_sp+1 < sp)
+    if(save_sp+1 < Pike_sp)
     {
-      assign_svalue(save_sp,sp-1);
-      pop_n_elems(sp-save_sp-1);
+      assign_svalue(save_sp,Pike_sp-1);
+      pop_n_elems(Pike_sp-save_sp-1);
     }
-    fp->expendible=expendible;
-    fp->locals=locals;
+    Pike_fp->expendible=expendible;
+    Pike_fp->locals=locals;
     print_return_value();
 #ifdef PIKE_DEBUG
-    if(sp != save_sp+1)
-      fatal("Stack whack in F_RECUR sp=%p, expected=%p\n",sp,save_sp+1);
+    if(Pike_sp != save_sp+1)
+      fatal("Stack whack in F_RECUR Pike_sp=%p, expected=%p\n",Pike_sp,save_sp+1);
 #endif
   }
 }
 BREAK
 
 /* Assume that the number of arguments is correct */
-/* FIXME: adjust mark_sp */
+/* FIXME: adjust Pike_mark_sp */
 OPCODE0_JUMP(F_TAIL_RECUR,"tail recursion")
 {
   int x,num_locals;
   char *addr;
-  int args=sp - *--mark_sp;
+  int args=Pike_sp - *--Pike_mark_sp;
 
   fast_check_threads_etc(6);
 
@@ -1652,17 +1652,17 @@ OPCODE0_JUMP(F_TAIL_RECUR,"tail recursion")
     fatal("Wrong number of arguments in F_TAIL_RECUR %d != %d\n",args,EXTRACT_UCHAR(addr-1));
 #endif
 
-  if(sp-args != fp->locals)
+  if(Pike_sp-args != Pike_fp->locals)
   {
-    assign_svalues(fp->locals, sp-args, args, BIT_MIXED);
-    pop_n_elems(sp - (fp->locals + args));
+    assign_svalues(Pike_fp->locals, Pike_sp-args, args, BIT_MIXED);
+    pop_n_elems(Pike_sp - (Pike_fp->locals + args));
   }
 
-  clear_svalues(sp, num_locals - args);
-  sp += num_locals - args;
+  clear_svalues(Pike_sp, num_locals - args);
+  Pike_sp += num_locals - args;
 
 #ifdef PIKE_DEBUG
-  if(sp != fp->locals + fp->num_locals)
+  if(Pike_sp != Pike_fp->locals + Pike_fp->num_locals)
     fatal("Sp whacked!\n");
 #endif
 
diff --git a/src/interpreter.h b/src/interpreter.h
index ec9d81c891f7bcfb57fd251c9cebf788f376917f..4c0f4b23bcf27bfab4470b13d978392be9ef045c 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -49,19 +49,19 @@ static int eval_instruction(unsigned char *pc)
       Pike_sp[2].type=99;
       Pike_sp[3].type=99;
       
-      if(Pike_sp<Pike_interpreter.evaluator_stack || Pike_interpreter.mark_sp < Pike_interpreter.mark_stack || Pike_fp->locals>Pike_sp)
-	fatal("Stack error (generic) Pike_sp=%p/%p Pike_interpreter.mark_sp=%p/%p locals=%p.\n",
+      if(Pike_sp<Pike_interpreter.evaluator_stack || Pike_mark_sp < Pike_interpreter.mark_stack || Pike_fp->locals>Pike_sp)
+	fatal("Stack error (generic) Pike_sp=%p/%p Pike_mark_sp=%p/%p locals=%p.\n",
 	      Pike_sp,
 	      Pike_interpreter.evaluator_stack,
-	      Pike_interpreter.mark_sp,
+	      Pike_mark_sp,
 	      Pike_interpreter.mark_stack,
 	      Pike_fp->locals);
       
-      if(Pike_interpreter.mark_sp > Pike_interpreter.mark_stack+Pike_stack_size)
+      if(Pike_mark_sp > Pike_interpreter.mark_stack+Pike_stack_size)
 	fatal("Mark Stack error (overflow).\n");
 
 
-      if(Pike_interpreter.mark_sp < Pike_interpreter.mark_stack)
+      if(Pike_mark_sp < Pike_interpreter.mark_stack)
 	fatal("Mark Stack error (underflow).\n");
 
       if(Pike_sp > Pike_interpreter.evaluator_stack+Pike_stack_size)
@@ -74,7 +74,7 @@ static int eval_instruction(unsigned char *pc)
       if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer)
 	fatal("Stack error (underflow).\n");
 
-      if(Pike_interpreter.mark_sp > Pike_interpreter.mark_stack && Pike_interpreter.mark_sp[-1] > Pike_sp)
+      if(Pike_mark_sp > Pike_interpreter.mark_stack && Pike_mark_sp[-1] > Pike_sp)
 	fatal("Stack error (underflow?)\n");
       
       if(d_flag > 9) do_debug();
@@ -90,7 +90,7 @@ static int eval_instruction(unsigned char *pc)
       backlog[backlogp].instruction=instr;
       backlog[backlogp].pc=pc;
       backlog[backlogp].stack = Pike_sp - Pike_interpreter.evaluator_stack;
-      backlog[backlogp].mark_stack = Pike_interpreter.mark_sp - Pike_interpreter.mark_stack;
+      backlog[backlogp].mark_stack = Pike_mark_sp - Pike_interpreter.mark_stack;
 #ifdef _REENTRANT
       backlog[backlogp].thread_id=Pike_interpreter.thread_id;
 #endif
@@ -125,7 +125,7 @@ static int eval_instruction(unsigned char *pc)
 	      (long)(pc-Pike_fp->context.prog->program-1),
 	      get_f_name(instr + F_OFFSET),
 	      (long)(Pike_sp-Pike_interpreter.evaluator_stack),
-	      (long)(Pike_interpreter.mark_sp-Pike_interpreter.mark_stack));
+	      (long)(Pike_mark_sp-Pike_interpreter.mark_stack));
     }
 
     if(instr + F_OFFSET < F_MAX_OPCODE) 
diff --git a/src/threads.c b/src/threads.c
index 0187e6d08bb9a5b98ab05d1578be5b22cb57bb36..b77b20d828f7d441f33ad86c1efddb6cc76adcbc 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.131 2000/06/24 07:20:27 hubbe Exp $");
+RCSID("$Id: threads.c,v 1.132 2000/07/07 01:24:14 hubbe Exp $");
 
 int num_threads = 1;
 int threads_disabled = 0;
@@ -194,9 +194,8 @@ int co_destroy(COND_T *c)
 #endif
 
 
-#define THIS_THREAD ((struct Pike_interpreter *)CURRENT_STORAGE)
+#define THIS_THREAD ((struct thread_state *)CURRENT_STORAGE)
 
-struct object *thread_id = NULL;
 static struct callback *threads_evaluator_callback=0;
 int thread_id_result_variable;
 
@@ -239,7 +238,7 @@ void low_init_threads_disable(void)
     THREADS_FPRINTF(0,
 		    (stderr, "low_init_threads_disable(): Locking IM's...\n"));
 
-    if (thread_id) {
+    if (Pike_interpreter.thread_id) {
       /* Threads have been enabled. */
 
       IMUTEX_T *im;
@@ -385,7 +384,7 @@ void exit_interleave_mutex(IMUTEX_T *im)
 
 #define THREAD_TABLE_SIZE 127  /* Totally arbitrary prime */
 
-static struct Pike_interpreter *thread_table_chains[THREAD_TABLE_SIZE];
+static struct thread_state *thread_table_chains[THREAD_TABLE_SIZE];
 static int num_pike_threads=0;
 
 void thread_table_init(void)
@@ -415,7 +414,7 @@ static void dumpmem(char *desc, void *x, int size)
 
 void thread_table_insert(struct object *o)
 {
-  struct Pike_interpreter *s = OBJ2THREAD(o);
+  struct thread_state *s = OBJ2THREAD(o);
   unsigned INT32 h = thread_table_hash(&s->id);
 #ifdef PIKE_DEBUG
   if(h>=THREAD_TABLE_SIZE)
@@ -440,7 +439,7 @@ void thread_table_insert(struct object *o)
 
 void thread_table_delete(struct object *o)
 {
-  struct Pike_interpreter *s = OBJ2THREAD(o);
+  struct thread_state *s = OBJ2THREAD(o);
 /*  dumpmem("thread_table_delete",&s->id, sizeof(THREAD_T)); */
   mt_lock( & thread_table_lock );
   num_pike_threads--;
@@ -450,10 +449,10 @@ void thread_table_delete(struct object *o)
   mt_unlock( & thread_table_lock );
 }
 
-struct Pike_interpreter *thread_state_for_id(THREAD_T tid)
+struct thread_state *thread_state_for_id(THREAD_T tid)
 {
   unsigned INT32 h = thread_table_hash(&tid);
-  struct Pike_interpreter *s = NULL;
+  struct thread_state *s = NULL;
 #if 0
   if(num_threads>1)
     dumpmem("thread_state_for_id: ",&tid,sizeof(tid));
@@ -503,7 +502,7 @@ struct Pike_interpreter *thread_state_for_id(THREAD_T tid)
 
 struct object *thread_for_id(THREAD_T tid)
 {
-  struct Pike_interpreter *s = thread_state_for_id(tid);
+  struct thread_state *s = thread_state_for_id(tid);
   return (s == NULL? NULL : THREADSTATE2OBJ(s));
   /* See NB in thread_state_for_id.  Lifespan of result can be prolonged
      by incrementing refcount though. */
@@ -517,10 +516,10 @@ void f_all_threads(INT32 args)
 
   INT32 x;
   struct svalue *oldsp;
-  struct Pike_interpreter *s;
+  struct thread_state *s;
 
   pop_n_elems(args);
-  oldsp = sp;
+  oldsp = Pike_sp;
   mt_lock( & thread_table_lock );
   for(x=0; x<THREAD_TABLE_SIZE; x++)
     for(s=thread_table_chains[x]; s; s=s->hashlink) {
@@ -528,7 +527,7 @@ void f_all_threads(INT32 args)
       ref_push_object(o);
     }
   mt_unlock( & thread_table_lock );
-  f_aggregate(sp-oldsp);
+  f_aggregate(Pike_sp-oldsp);
 }
 
 
@@ -543,8 +542,11 @@ static void check_threads(struct callback *cb, void *arg, void * arg2)
   if(div_++ & 255) return;
 
 #ifdef DEBUG
-  if(thread_for_id(th_self()) != thread_id)
-    fatal("thread_for_id() (or thread_id) failed!\n")
+  if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
+    fatal("thread_for_id() (or Pike_interpreter.thread_id) failed!\n")
+
+  if(Pike_interpreter.backlink != OBJ2THREAD(Pike_interpreter.thread_id))
+    fatal("Hashlink is wrong!\n");
 #endif
 
   THREADS_ALLOW();
@@ -552,8 +554,8 @@ static void check_threads(struct callback *cb, void *arg, void * arg2)
   THREADS_DISALLOW();
 
 #ifdef DEBUG
-  if(thread_for_id(th_self()) != thread_id)
-    fatal("thread_for_id() (or thread_id) failed!\n")
+  if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
+    fatal("thread_for_id() (or Pike_interpreter.thread_id) failed!\n")
 #endif
 }
 
@@ -584,25 +586,26 @@ TH_RETURN_TYPE new_thread_func(void * data)
 	  errno
 #endif
 	  );
+  SWAP_IN_THREAD(OBJ2THREAD(arg.id)); /* Init struct */
   init_interpreter();
-  thread_id=arg.id;
-  stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION;
-  recoveries = NULL;
-  SWAP_OUT_THREAD(OBJ2THREAD(thread_id)); /* Init struct */
-  OBJ2THREAD(thread_id)->swapped=0;
+  Pike_interpreter.thread_id=arg.id;
+  Pike_interpreter.stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION;
+  Pike_interpreter.recoveries = NULL;
+  SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id)); /* Init struct */
+  OBJ2THREAD(Pike_interpreter.thread_id)->swapped=0;
 
 #if defined(PIKE_DEBUG)
   if(d_flag)
     {
       THREAD_T self = th_self();
 
-      if( thread_id && !th_equal( OBJ2THREAD(thread_id)->id, self) )
+      if( Pike_interpreter.thread_id && !th_equal( OBJ2THREAD(Pike_interpreter.thread_id)->id, self) )
 	fatal("Current thread is wrong. %lx %lx\n",
-	      (long)OBJ2THREAD(thread_id)->id, (long)self);
+	      (long)OBJ2THREAD(Pike_interpreter.thread_id)->id, (long)self);
 	
-      if(thread_for_id(th_self()) != thread_id)
-	fatal("thread_for_id() (or thread_id) failed in new_thread_func! "
-	      "%p != %p\n", thread_for_id(self), thread_id);
+      if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
+	fatal("thread_for_id() (or Pike_interpreter.thread_id) failed in new_thread_func! "
+	      "%p != %p\n", thread_for_id(self), Pike_interpreter.thread_id);
     }
 #endif
 
@@ -612,14 +615,14 @@ TH_RETURN_TYPE new_thread_func(void * data)
   }
 #endif /* THREAD_TRACE */
 
-  THREADS_FPRINTF(0, (stderr,"THREAD %08x INITED\n",(unsigned int)thread_id));
+  THREADS_FPRINTF(0, (stderr,"THREAD %08x INITED\n",(unsigned int)Pike_interpreter.thread_id));
   if(SETJMP(back))
   {
     if(throw_severity < THROW_EXIT)
     {
       ONERROR tmp;
       SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
-      assign_svalue_no_free(sp++, & throw_value);
+      assign_svalue_no_free(Pike_sp++, & throw_value);
       APPLY_MASTER("handle_error", 1);
       pop_stack();
       UNSET_ONERROR(tmp);
@@ -636,35 +639,35 @@ TH_RETURN_TYPE new_thread_func(void * data)
     arg.args=0;
     f_call_function(args);
 
-    /* copy return value to the thread_id here */
-    object_low_set_index(thread_id,
+    /* copy return value to the Pike_interpreter.thread_id here */
+    object_low_set_index(Pike_interpreter.thread_id,
 			 thread_id_result_variable,
-			 sp-1);
+			 Pike_sp-1);
     pop_stack();
   }
 
-  if(OBJ2THREAD(thread_id)->thread_local != NULL) {
-    free_mapping(OBJ2THREAD(thread_id)->thread_local);
-    OBJ2THREAD(thread_id)->thread_local = NULL;
+  if(OBJ2THREAD(Pike_interpreter.thread_id)->thread_local != NULL) {
+    free_mapping(OBJ2THREAD(Pike_interpreter.thread_id)->thread_local);
+    OBJ2THREAD(Pike_interpreter.thread_id)->thread_local = NULL;
   }
 
-   OBJ2THREAD(thread_id)->status=THREAD_EXITED;
-   co_broadcast(& OBJ2THREAD(thread_id)->status_change);
+   OBJ2THREAD(Pike_interpreter.thread_id)->status=THREAD_EXITED;
+   co_broadcast(& OBJ2THREAD(Pike_interpreter.thread_id)->status_change);
 
   free((char *)data); /* Moved by per, to avoid some bugs.... */
   UNSETJMP(back);
 
   THREADS_FPRINTF(0, (stderr,"THREADS_ALLOW() Thread %08x done\n",
-		      (unsigned int)thread_id));
+		      (unsigned int)Pike_interpreter.thread_id));
 
   cleanup_interpret();
   DO_IF_DMALLOC(
-    SWAP_OUT_THREAD(OBJ2THREAD(thread_id)); /* de-Init struct */
-    OBJ2THREAD(thread_id)->swapped=0;
+    SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id)); /* de-Init struct */
+    OBJ2THREAD(Pike_interpreter.thread_id)->swapped=0;
     )
-  thread_table_delete(thread_id);
-  free_object(thread_id);
-  thread_id=0;
+  thread_table_delete(Pike_interpreter.thread_id);
+  free_object(Pike_interpreter.thread_id);
+  Pike_interpreter.thread_id=0;
   num_threads--;
   if(!num_threads && threads_evaluator_callback)
   {
@@ -728,7 +731,7 @@ void f_thread_create(INT32 args)
 void f_thread_set_concurrency(INT32 args)
 {
   int c=1;
-  if(args) c=sp[-args].u.integer;
+  if(args) c=Pike_sp[-args].u.integer;
   else error("No argument to thread_set_concurrency(int concurrency);\n");
   pop_n_elems(args);
   num_lwps=c;
@@ -739,7 +742,7 @@ void f_thread_set_concurrency(INT32 args)
 void f_this_thread(INT32 args)
 {
   pop_n_elems(args);
-  ref_push_object(thread_id);
+  ref_push_object(Pike_interpreter.thread_id);
 }
 
 #define THIS_MUTEX ((struct mutex_storage *)(CURRENT_STORAGE))
@@ -781,20 +784,20 @@ void f_mutex_lock(INT32 args)
   switch(type)
   {
     default:
-      bad_arg_error("mutex->lock", sp-args, args, 2, "int(0..2)", sp+1-args,
+      bad_arg_error("mutex->lock", Pike_sp-args, args, 2, "int(0..2)", Pike_sp+1-args,
 		  "Unknown mutex locking style: %d\n",type);
       
 
     case 0:
     case 2:
-      if(m->key && OB2KEY(m->key)->owner == thread_id)
+      if(m->key && OB2KEY(m->key)->owner == Pike_interpreter.thread_id)
       {
 	THREADS_FPRINTF(0,
 			(stderr, "Recursive LOCK k:%08x, m:%08x(%08x), t:%08x\n",
 			 (unsigned int)OB2KEY(m->key),
 			 (unsigned int)m,
 			 (unsigned int)OB2KEY(m->key)->mut,
-			 (unsigned int) thread_id));
+			 (unsigned int) Pike_interpreter.thread_id));
 
 	if(type==0) error("Recursive mutex locks!\n");
 
@@ -811,8 +814,8 @@ void f_mutex_lock(INT32 args)
    */
   o=clone_object(mutex_key,0);
 
-  DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id)
-	       fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; )
+  DO_IF_DEBUG( if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
+	       fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ; )
 
   if(m->key)
   {
@@ -832,14 +835,14 @@ void f_mutex_lock(INT32 args)
   m->key=o;
   OB2KEY(o)->mut=m;
 
-  DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id)
-	       fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; )
+  DO_IF_DEBUG( if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
+	       fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ; )
 
   THREADS_FPRINTF(1, (stderr, "LOCK k:%08x, m:%08x(%08x), t:%08x\n",
 		      (unsigned int)OB2KEY(o),
 		      (unsigned int)m,
 		      (unsigned int)OB2KEY(m->key)->mut,
-		      (unsigned int)thread_id));
+		      (unsigned int)Pike_interpreter.thread_id));
   pop_n_elems(args);
   push_object(o);
 }
@@ -865,11 +868,11 @@ void f_mutex_trylock(INT32 args)
   switch(type)
   {
     default:
-      bad_arg_error("mutex->trylock", sp-args, args, 2, "int(0..2)", sp+1-args,
+      bad_arg_error("mutex->trylock", Pike_sp-args, args, 2, "int(0..2)", Pike_sp+1-args,
 		  "Unknown mutex locking style: %d\n",type);
 
     case 0:
-      if(m->key && OB2KEY(m->key)->owner == thread_id)
+      if(m->key && OB2KEY(m->key)->owner == Pike_interpreter.thread_id)
       {
 	error("Recursive mutex locks!\n");
       }
@@ -918,9 +921,9 @@ void exit_mutex_obj(struct object *o)
 void init_mutex_key_obj(struct object *o)
 {
   THREADS_FPRINTF(1, (stderr, "KEY k:%08x, o:%08x\n",
-		      (unsigned int)THIS_KEY, (unsigned int)thread_id));
+		      (unsigned int)THIS_KEY, (unsigned int)Pike_interpreter.thread_id));
   THIS_KEY->mut=0;
-  add_ref(THIS_KEY->owner=thread_id);
+  add_ref(THIS_KEY->owner=Pike_interpreter.thread_id);
   THIS_KEY->initialized=1;
 }
 
@@ -929,7 +932,7 @@ void exit_mutex_key_obj(struct object *o)
   THREADS_FPRINTF(1, (stderr, "UNLOCK k:%08x m:(%08x) t:%08x o:%08x\n",
 		      (unsigned int)THIS_KEY,
 		      (unsigned int)THIS_KEY->mut,
-		      (unsigned int)thread_id,
+		      (unsigned int)Pike_interpreter.thread_id,
 		      (unsigned int)THIS_KEY->owner));
   if(THIS_KEY->mut)
   {
@@ -965,15 +968,15 @@ void f_cond_wait(INT32 args)
 
   c=THIS_COND;
 
-  if((args > 0) && !IS_ZERO(sp-1))
+  if((args > 0) && !IS_ZERO(Pike_sp-1))
   {
     struct object *key;
     struct mutex_storage *mut;
 
-    if(sp[-1].type != T_OBJECT)
+    if(Pike_sp[-1].type != T_OBJECT)
       error("Bad argument 1 to condition->wait()\n");
     
-    key=sp[-1].u.object;
+    key=Pike_sp[-1].u.object;
     
     if(key->prog != mutex_key)
       error("Bad argument 1 to condition->wait()\n");
@@ -1017,23 +1020,24 @@ void f_cond_broadcast(INT32 args) { pop_n_elems(args); co_broadcast(THIS_COND);
 void init_cond_obj(struct object *o) { co_init(THIS_COND); }
 void exit_cond_obj(struct object *o) { co_destroy(THIS_COND); }
 
+/* FIXME:  -Hubbe */
 void f_thread_backtrace(INT32 args)
 {
-  struct Pike_interpreter *foo = THIS_THREAD;
-  struct Pike_interpreter *bar = OBJ2THREAD( thread_id );
-  struct svalue *osp = sp;
+  struct thread_state *foo = THIS_THREAD;
+  struct thread_state *bar = OBJ2THREAD( Pike_interpreter.thread_id );
+  struct svalue *osp = Pike_sp;
   pop_n_elems(args);
-  if(foo->sp)
+  if(foo->state.stack_pointer)
   {
     SWAP_OUT_THREAD(bar);
     SWAP_IN_THREAD(foo);
-    sp=osp;
+    Pike_sp=osp;
     f_backtrace(0);
-    osp=sp;
-    sp=foo->sp;
+    osp=Pike_sp;
+    Pike_sp=foo->state.stack_pointer;
     SWAP_OUT_THREAD(foo);
     SWAP_IN_THREAD(bar);
-    sp=osp;
+    Pike_sp=osp;
   } else {
     push_int(0);
     f_allocate(1);
@@ -1057,7 +1061,7 @@ void f_thread_id__sprintf (INT32 args)
 
 static void f_thread_id_result(INT32 args)
 {
-  struct Pike_interpreter *th=THIS_THREAD;
+  struct thread_state *th=THIS_THREAD;
 
   SWAP_OUT_CURRENT_THREAD();
 
@@ -1066,10 +1070,10 @@ static void f_thread_id_result(INT32 args)
 
   SWAP_IN_CURRENT_THREAD();
 
-  low_object_index_no_free(sp,
-			   fp->current_object, 
+  low_object_index_no_free(Pike_sp,
+			   Pike_fp->current_object, 
 			   thread_id_result_variable);
-  sp++;
+  Pike_sp++;
 }
 
 void init_thread_obj(struct object *o)
@@ -1093,14 +1097,14 @@ void exit_thread_obj(struct object *o)
 
 static void thread_was_recursed(struct object *o)
 {
-  struct Pike_interpreter *tmp=THIS_THREAD;
+  struct thread_state *tmp=THIS_THREAD;
   if(tmp->thread_local != NULL)
     gc_recurse_mapping(tmp->thread_local);
 }
 
 static void thread_was_checked(struct object *o)
 {
-  struct Pike_interpreter *tmp=THIS_THREAD;
+  struct thread_state *tmp=THIS_THREAD;
   if(tmp->thread_local != NULL)
     debug_gc_check(tmp->thread_local, T_OBJECT, o);
 
@@ -1109,15 +1113,17 @@ static void thread_was_checked(struct object *o)
   {
     struct pike_frame *f;
     debug_malloc_touch(o);
-    debug_gc_xmark_svalues(tmp->evaluator_stack,tmp->sp-tmp->evaluator_stack-1," in idle thread stack");
+    debug_gc_xmark_svalues(tmp->state.evaluator_stack,
+			   tmp->state.stack_pointer-tmp->state.evaluator_stack-1,
+			   " in idle thread stack");
     
-    for(f=tmp->fp;f;f=f->next)
+    for(f=tmp->state.frame_pointer;f;f=f->next)
     {
       debug_malloc_touch(f);
       if(f->context.parent)
-	gc_external_mark2(f->context.parent,0," in fp->context.parent of idle thread");
-      gc_external_mark2(f->current_object,0," in fp->current_object of idle thread");
-      gc_external_mark2(f->context.prog,0," in fp->context.prog of idle thread");
+	gc_external_mark2(f->context.parent,0," in Pike_fp->context.parent of idle thread");
+      gc_external_mark2(f->current_object,0," in Pike_fp->current_object of idle thread");
+      gc_external_mark2(f->context.prog,0," in Pike_fp->context.prog of idle thread");
     }
   }
 #endif
@@ -1141,12 +1147,12 @@ void f_thread_local_get(INT32 args)
   key.type = T_INT;
   key.subtype = NUMBER_NUMBER;
   pop_n_elems(args);
-  if(thread_id != NULL &&
-     (m = OBJ2THREAD(thread_id)->thread_local) != NULL)
-    mapping_index_no_free(sp++, m, &key);
+  if(Pike_interpreter.thread_id != NULL &&
+     (m = OBJ2THREAD(Pike_interpreter.thread_id)->thread_local) != NULL)
+    mapping_index_no_free(Pike_sp++, m, &key);
   else {
     push_int(0);
-    sp[-1].subtype=NUMBER_UNDEFINED;
+    Pike_sp[-1].subtype=NUMBER_UNDEFINED;
   }
 }
 
@@ -1162,14 +1168,14 @@ void f_thread_local_set(INT32 args)
   else if(args<1)
     error("Too few arguments to thread_local->set()\n");
 
-  if(thread_id == NULL)
+  if(Pike_interpreter.thread_id == NULL)
     error("Trying to set thread_local without thread!\n");
 
-  if((m = OBJ2THREAD(thread_id)->thread_local) == NULL)
-    m = OBJ2THREAD(thread_id)->thread_local =
+  if((m = OBJ2THREAD(Pike_interpreter.thread_id)->thread_local) == NULL)
+    m = OBJ2THREAD(Pike_interpreter.thread_id)->thread_local =
       allocate_mapping(4);
 
-  mapping_insert(m, &key, &sp[-1]);
+  mapping_insert(m, &key, &Pike_sp[-1]);
 }
 
 void low_th_init(void)
@@ -1295,7 +1301,7 @@ void th_init(void)
 	   OPT_SIDE_EFFECT);
 
   START_NEW_PROGRAM_ID(THREAD_ID);
-  thread_storage_offset=ADD_STORAGE(struct Pike_interpreter);
+  thread_storage_offset=ADD_STORAGE(struct thread_state);
   thread_id_result_variable=simple_add_variable("result","mixed",0);
   /* function(:array) */
   ADD_FUNCTION("backtrace",f_thread_backtrace,tFunc(tNone,tArray),0);
@@ -1313,17 +1319,17 @@ void th_init(void)
   add_ref(thread_id_prog);
   end_class("thread_id", 0);
 
-  /* function(mixed ...:object(thread_id)) */
+  /* function(mixed ...:object(Pike_interpreter.thread_id)) */
   ADD_EFUN("thread_create",f_thread_create,
 	   tFuncV(tNone,tMixed,tObjIs_THREAD_ID),
 	   OPT_SIDE_EFFECT);
 
-  /* function(:object(thread_id)) */
+  /* function(:object(Pike_interpreter.thread_id)) */
   ADD_EFUN("this_thread",f_this_thread,
 	   tFunc(tNone,tObjIs_THREAD_ID),
 	   OPT_EXTERNAL_DEPEND);
 
-  /* function(:array(object(thread_id))) */
+  /* function(:array(object(Pike_interpreter.thread_id))) */
   ADD_EFUN("all_threads",f_all_threads,
 	   tFunc(tNone,tArr(tObjIs_THREAD_ID)),
 	   OPT_EXTERNAL_DEPEND);
@@ -1336,23 +1342,23 @@ void th_init(void)
   if(!mutex_key)
     fatal("Failed to initialize thread program!\n");
 
-  thread_id=clone_object(thread_id_prog,0);
-  SWAP_OUT_THREAD(OBJ2THREAD(thread_id)); /* Init struct */
-  OBJ2THREAD(thread_id)->swapped=0;
-  OBJ2THREAD(thread_id)->id=th_self();
-  thread_table_insert(thread_id);
+  Pike_interpreter.thread_id=clone_object(thread_id_prog,0);
+  SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id)); /* Init struct */
+  OBJ2THREAD(Pike_interpreter.thread_id)->id=th_self();
+  OBJ2THREAD(Pike_interpreter.thread_id)->swapped=0;
+  thread_table_insert(Pike_interpreter.thread_id);
 }
 
 void th_cleanup(void)
 {
   th_running = 0;
 
-  if(thread_id)
+  if(Pike_interpreter.thread_id)
   {
-    thread_table_delete(thread_id);
-    destruct(thread_id);
-    free_object(thread_id);
-    thread_id=0;
+    thread_table_delete(Pike_interpreter.thread_id);
+    destruct(Pike_interpreter.thread_id);
+    free_object(Pike_interpreter.thread_id);
+    Pike_interpreter.thread_id=0;
   }
 
   if(mutex_key)