diff --git a/src/ChangeLog b/src/ChangeLog
index aec00350992ca9bc00085ec4b1c40b340af0578f..3ede514f3edcacc4c5fecfe62bb185d59f6819d9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+Sun Sep  7 17:55:47 1997  Fredrik Hubinette  <hubbe@cytocin.hubbe.net>
+
+	* array.c: sort() now handles the `< method
+	* thread.c: now works again, also less overhead
+	* lex.c: '\0x20' works now
+	* program.c: fixed a bug with handling inherited functions
+
 Thu Sep  4 18:07:34 1997  Henrik Grubbstr�m  <grubba@infovav.se>
 
 	* modules/spider/dumudp.c (udp_sendto): Fixed threading bug.
diff --git a/src/testsuite.in b/src/testsuite.in
index 7f38e9fb14958ba05ed13bbc6c164e17d23269a3..fcf7a34cc7ef1a1bc99240660a9f103539c4c1eb 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,9 +1,17 @@
-test_true([["$Id: testsuite.in,v 1.49 1997/09/02 22:17:00 grubba Exp $"]])
+test_true([["$Id: testsuite.in,v 1.50 1997/09/08 19:08:57 hubbe Exp $"]])
 test_eq(1e1,10.0)
 test_eq(1E1,10.0)
 test_eq(1e+1,10.0)
 test_eq(1.1e1,11.0)
 test_eq(1e-1,0.1)
+test_eq('\x20',32)
+test_eq("\x20","\040")
+test_any([[
+class p1 { int foo() { return 1; }};
+class p2 { int foo() { return 2; }};
+class c1 { inherit p1; inherit p2; int foo() { return p1::foo()+p2::foo(); }};
+ class c2 { inherit c1; }; return c2()->foo();]],3)
+test_any([[class foo { int x=random(100); int `<(object o) { return x < o->x; } }; object *o=Array.map(allocate(100),foo); sort(o); for(int e=1;e<100;e++) if(o[e-1]->x > o[e]->x) return e; return -1;]],-1)
 test_compile_error([[void foo() { return destruct(this_object()); }]])
 test_any([[class foo { constant x=17; }; class bar { inherit foo; constant x=18; }; return bar()->x;]],18)
 test_program([[inline string foo(string s){ while(s[0] == ' ' || s[0] == '\t') s = s[1..]; return(s); } string a() { return foo("   bar"); }]])
@@ -145,8 +153,8 @@ cond([[all_constants()->thread_create]],
   test_do(add_constant("_tmp_mutex_lock"))
   test_true(_tmp_mutex->trylock())
   test_do(add_constant("_tmp_mutex"))
-  test_true([[ object m = Thread.Mutex(); object k = m->lock(); thread_create(lambda(object k){ sleep(10); destruct(k); }, k);if (catch{m->lock(); return 0;}) { return 1; } return 0; ]])
-  test_any([[ mixed *data=({0,Thread.Mutex(),Thread.Mutex(),0}); data[3]=data[2]->lock(); thread_create(lambda(mixed *data) {object o=data[1]->lock(); destruct(data[3]); sleep(10); data[0]=1; destruct(o);  },data); object l; while (catch(l=data[2]->lock())) sleep(1); object ll=data[1]->lock(); return data[0]; ]],1)
+  test_any([[ object m = Thread.Mutex(); object k = m->lock(); thread_create(lambda(object k){ sleep(10); }, k);if (catch{m->lock(); return 0;}) { return 1; } return 0; ]],1)
+  test_any([[ mixed *data=({0,Thread.Mutex(),Thread.Mutex(),0}); data[3]=data[2]->lock(); thread_create(lambda(mixed *data) {object o=data[1]->lock(); destruct(data[3]); sleep(10); data[0]=1; destruct(o);  },data); object l=data[2]->lock(1); object ll=data[1]->lock(); return data[0]; ]],1)
   test_any([[mixed *data=({1, Thread.Mutex()}); for(int e=0;e<3;e++) thread_create(lambda(mixed *data) { for(int e=0;e<1000;e++) { object o=data[1]->lock(); data[0]*=2; for(int d=0;d<5;d++) { data[0]--; data[0]*=2; } data[0]--; destruct(o); }}, data); return data[0];]],1)
 
 // /precompiled/condition
diff --git a/src/threads.h b/src/threads.h
index 17368d5ed8e3dfff06d6e734441e483759cdbc62..0f223848e36bdd9460c264d6f1d638336b738525 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -179,7 +179,6 @@ struct thread_state {
 
 #define SWAP_OUT_THREAD(_tmp) do { \
        (_tmp)->swapped=1; \
-\
        (_tmp)->evaluator_stack=evaluator_stack;\
        (_tmp)->evaluator_stack_malloced=evaluator_stack_malloced;\
        (_tmp)->fp=fp;\
@@ -193,7 +192,6 @@ struct thread_state {
 
 #define SWAP_IN_THREAD(_tmp) do {\
        (_tmp)->swapped=0; \
-\
        evaluator_stack=(_tmp)->evaluator_stack;\
        evaluator_stack_malloced=(_tmp)->evaluator_stack_malloced;\
        fp=(_tmp)->fp;\
@@ -205,6 +203,29 @@ struct thread_state {
        thread_id=(_tmp)->thread_id;\
      } while(0)
 
+#define SWAP_OUT_CURRENT_THREAD() \
+  do {\
+     struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \
+     SWAP_OUT_THREAD(_tmp); \
+     THREADS_FPRINTF((stderr, "SWAP_OUT_CURRENT_THREAD() %s:%d t:%08x\n", \
+			__FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \
+
+#define SWAP_IN_CURRENT_THREAD() \
+   THREADS_FPRINTF((stderr, "SWAP_IN_CURRENT_THREAD() %s:%d ... t:%08x\n", \
+		    __FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \
+   SWAP_IN_THREAD(_tmp);\
+ } while(0)
+
+#define THREADS_ALLOW() \
+  do {\
+     struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \
+     if(num_threads > 1 && !threads_disabled) { \
+       SWAP_OUT_THREAD(_tmp); \
+       THREADS_FPRINTF((stderr, "THREADS_ALLOW() %s:%d t:%08x\n", \
+			__FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \
+       mt_unlock(& interpreter_lock); \
+     }
+
 #define THREADS_ALLOW() \
   do {\
      struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \