diff --git a/src/threads.c b/src/threads.c
index 71ebc4a70ec5f26dd00ad12613c2468cd61f7ac4..9252895d2d2b2d3b7d303f9442ed421d8724a3fa 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.93 1999/05/02 08:11:50 hubbe Exp $");
+RCSID("$Id: threads.c,v 1.94 1999/05/08 00:41:01 hubbe Exp $");
 
 int num_threads = 1;
 int threads_disabled = 0;
@@ -336,6 +336,19 @@ unsigned INT32 thread_table_hash(THREAD_T *tid)
   return th_hash(*tid) % THREAD_TABLE_SIZE;
 }
 
+#ifdef PIKE_DEBUG
+static void dumpmem(char *desc, void *x, int size)
+{
+  int e;
+  unsigned char *tmp=(unsigned char *)x;
+  fprintf(stderr,"%s: ",desc);
+  for(e=0;e<size;e++)
+    fprintf(stderr,"%02x",tmp[e]);
+  fprintf(stderr,"\n");
+}
+#endif
+
+
 void thread_table_insert(struct object *o)
 {
   struct thread_state *s = OBJ2THREAD(o);
@@ -343,6 +356,9 @@ void thread_table_insert(struct object *o)
 #ifdef PIKE_DEBUG
   if(h>=THREAD_TABLE_SIZE)
     fatal("thread_table_hash failed miserably!\n");
+  if(thread_state_for_id(s->id))
+    fatal("Registring thread twice!\n");
+/*  dumpmem("thread_table_insert",&s->id, sizeof(THREAD_T)); */
 #endif
   mt_lock( & thread_table_lock );
   if((s->hashlink = thread_table_chains[h]) != NULL)
@@ -355,6 +371,7 @@ void thread_table_insert(struct object *o)
 void thread_table_delete(struct object *o)
 {
   struct thread_state *s = OBJ2THREAD(o);
+/*  dumpmem("thread_table_delete",&s->id, sizeof(THREAD_T)); */
   mt_lock( & thread_table_lock );
   if(s->hashlink != NULL)
     s->hashlink->backlink = s->backlink;
@@ -366,6 +383,10 @@ struct thread_state *thread_state_for_id(THREAD_T tid)
 {
   unsigned INT32 h = thread_table_hash(&tid);
   struct thread_state *s = NULL;
+#if 0
+  if(num_threads>1)
+    dumpmem("thread_state_for_id: ",&tid,sizeof(tid));
+#endif
 #ifdef PIKE_DEBUG
   if(h>=THREAD_TABLE_SIZE)
     fatal("thread_table_hash failed miserably!\n");
@@ -400,6 +421,10 @@ struct thread_state *thread_state_for_id(THREAD_T tid)
     }
   }
   mt_unlock( & thread_table_lock );
+#if 0
+  if(num_threads>1 && s)
+    dumpmem("thread_state_for_id return value: ",&s->id,sizeof(tid));
+#endif
   return s;
   /* NOTEZ BIEN:  Return value only guaranteed to remain valid as long
      as you have the interpreter lock, unless tid == th_self() */
@@ -408,9 +433,7 @@ struct thread_state *thread_state_for_id(THREAD_T tid)
 struct object *thread_for_id(THREAD_T tid)
 {
   struct thread_state *s = thread_state_for_id(tid);
-  return (s == NULL? NULL :
-	  (struct object *)(((char *)s)-((((struct object *)NULL)->storage)-
-					 ((char*)NULL))));
+  return (s == NULL? NULL : THREADSTATE2OBJ(s));
   /* See NB in thread_state_for_id.  Lifespan of result can be prolonged
      by incrementing refcount though. */
 }
@@ -429,9 +452,7 @@ void f_all_threads(INT32 args)
   mt_lock( & thread_table_lock );
   for(x=0; x<THREAD_TABLE_SIZE; x++)
     for(s=thread_table_chains[x]; s; s=s->hashlink) {
-      struct object *o =
-	(struct object *)(((char *)s)-((((struct object *)NULL)->storage)-
-				       ((char*)NULL)));
+      struct object *o = THREADSTATE2OBJ(s);
       ref_push_object(o);
     }
   mt_unlock( & thread_table_lock );
@@ -444,12 +465,24 @@ static void check_threads(struct callback *cb, void *arg, void * arg2)
   static int div_;
   if(div_++ & 255) return;
 
+#ifdef DEBUG
+  if(thread_for_id(th_self()) != thread_id)
+    fatal("thread_for_id() (or thread_id) failed!\n")
+#endif
+
   THREADS_ALLOW();
   /* Allow other threads to run */
   THREADS_DISALLOW();
+
+#ifdef DEBUG
+  if(thread_for_id(th_self()) != thread_id)
+    fatal("thread_for_id() (or thread_id) failed!\n")
+#endif
+
+
 }
 
-void *new_thread_func(void * data)
+TH_RETURN_TYPE new_thread_func(void * data)
 {
   struct thread_starter arg = *(struct thread_starter *)data;
   JMP_BUF back;
@@ -467,6 +500,17 @@ void *new_thread_func(void * data)
   stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION;
   recoveries = NULL;
 
+#if defined(PIKE_DEBUG)
+  if(d_flag)
+    {
+      if( thread_id && !th_equal( OBJ2THREAD(thread_id)->id, th_self()) )
+	fatal("Current thread is wrong. %x %x\n",OBJ2THREAD(thread_id)->id,th_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(th_self()),thread_id);
+      }
+#endif
+
 #ifdef THREAD_TRACE
   {
     t_flag = default_t_flag;
@@ -659,6 +703,9 @@ 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) ; )
+
   if(m->key)
   {
     SWAP_OUT_CURRENT_THREAD();
@@ -672,6 +719,9 @@ 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) ; )
+
   THREADS_FPRINTF(1, (stderr, "LOCK k:%08x, m:%08x(%08x), t:%08x\n",
 		      (unsigned int)OB2KEY(o),
 		      (unsigned int)m,
@@ -1007,7 +1057,7 @@ void low_th_init(void)
 
   pthread_attr_init(&small_pattr);
 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
-  pthread_attr_setstacksize(&small_pattr, 32768);
+  pthread_attr_setstacksize(&small_pattr, 4096*sizeof(char *));
 #endif
   pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED);
 
@@ -1170,7 +1220,7 @@ static struct farmer {
 
 static MUTEX_T rosie;
 
-static void *farm(void *_a)
+static TH_RETURN_TYPE farm(void *_a)
 {
   struct farmer *me = (struct farmer *)_a;
   do
@@ -1215,14 +1265,7 @@ static struct farmer *new_farmer(void (*fun)(void *), void *args)
   me->field = args;
   me->harvest = fun;
   co_init( &me->harvest_moon );
-#ifdef UNIX_THREADS
-  /* FIXME: Why not increase the stacksize of th_create_small(),
-   * and use it instead?
-   */
-  thr_create(NULL, 65536, farm, me, THR_DAEMON|THR_DETACHED, &me->me);
-#else
   th_create_small(&me->me, farm, me);
-#endif
   return me;
 }
 
diff --git a/src/threads.h b/src/threads.h
index 674248e429ac685ec5f188a6770bb9c794a45488..34d4db6d46012bf24648985cfb62a4761f4f4162 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.65 1999/04/15 19:12:51 hubbe Exp $
+ * $Id: threads.h,v 1.66 1999/05/08 00:41:03 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -126,7 +126,7 @@ extern pthread_attr_t small_pattr;
 #define th_setconcurrency(X) thr_setconcurrency(X)
 
 #define th_create(ID,fun,arg) thr_create(NULL,thread_stack_size,fun,arg,THR_DAEMON|THR_DETACHED,ID)
-#define th_create_small(ID,fun,arg) thr_create(NULL,32768,fun,arg,THR_DAEMON|THR_DETACHED,ID)
+#define th_create_small(ID,fun,arg) thr_create(NULL,8192*sizeof(char *),fun,arg,THR_DAEMON|THR_DETACHED,ID)
 #define th_exit(foo) thr_exit(foo)
 #define th_self() thr_self()
 #define th_kill(ID,sig) thr_kill((ID),(sig))
@@ -179,17 +179,18 @@ extern pthread_attr_t small_pattr;
 #include <process.h>
 #include <windows.h>
 
-#define THREAD_T HANDLE
+#define THREAD_T unsigned
 #define th_setconcurrency(X)
-#define th_create(ID,fun,arg)  (!(*(ID)=_beginthread(fun, 2*1024*1024, arg)))
-#define th_create_small(ID,fun,arg)  (!(*(ID)=_beginthread(fun, 32768, arg)))
+#define th_create(ID,fun,arg) (!_beginthreadex(NULL, 2*1024*1024,fun, arg,0,ID))
+#define th_create_small(ID,fun,arg) (!_beginthreadex(NULL, 8192*sizeof(char *), fun,arg,0,ID))
+#define TH_RETURN_TYPE unsigned __stdcall
 #define th_exit(foo) _endthread(foo)
 #define th_join(ID,res)	/******************* FIXME! ****************/
-#define th_self() GetCurrentThread()
+#define th_self() GetCurrentThreadId()
 #define th_destroy(X)
 #define th_yield() Sleep(0)
 #define th_equal(X,Y) ((X)==(Y))
-#define th_hash(X) ((unsigned INT32)(X))
+#define th_hash(X) (X)
 
 #define MUTEX_T HANDLE
 #define mt_init(X) CheckValidHandle((*(X)=CreateMutex(NULL, 0, NULL)))
@@ -316,6 +317,10 @@ struct thread_state {
 #endif /* THREAD_TRACE */
 };
 
+#ifndef TH_RETURN_TYPE
+#define TH_RETURN_TYPE void *
+#endif
+
 #ifndef th_destroy
 #define th_destroy(X)
 #endif
@@ -433,8 +438,12 @@ struct thread_state {
 #define	OBJ2THREAD(X) \
   ((struct thread_state *)((X)->storage+thread_storage_offset))
 
+#define THREADSTATE2OBJ(X) BASEOF((X),object,storage[thread_storage_offset])
+
 #define THREADS_ALLOW() do { \
      struct thread_state *_tmp=OBJ2THREAD(thread_id); \
+     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) ; ) \
      if(num_threads > 1 && !threads_disabled) { \
        SWAP_OUT_THREAD(_tmp); \
        THREADS_FPRINTF(1, (stderr, "THREADS_ALLOW() %s:%d t:%08x(#%d)\n", \
@@ -458,6 +467,8 @@ struct thread_state {
        } \
        SWAP_IN_THREAD(_tmp);\
      } \
+     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) ; ) \
    } while(0)
 
 #define THREADS_ALLOW_UID() do { \
@@ -507,7 +518,7 @@ struct thread_state {
 
 /* Prototypes begin here */
 struct thread_starter;
-void *new_thread_func(void * data);
+TH_RETURN_TYPE new_thread_func(void * data);
 void f_thread_create(INT32 args);
 void f_thread_set_concurrency(INT32 args);
 void f_this_thread(INT32 args);