Index: trunk/kernel/syscalls/sys_thread_join.c
===================================================================
--- trunk/kernel/syscalls/sys_thread_join.c	(revision 408)
+++ trunk/kernel/syscalls/sys_thread_join.c	(revision 409)
@@ -40,10 +40,10 @@
     cxy_t         target_cxy;
     ltid_t        target_ltid;
-    uint32_t      flags;        // target thread flags
-    intptr_t      value;        // value returned by target thread
-    paddr_t       paddr;        // required for vmm_v2p_translate()
+	uint32_t      target_blocked;   // target thread blocked bit-vector
+    uint32_t      target_flags;     // target thread flags bit-bector
+    paddr_t       paddr;            // required for vmm_v2p_translate()
 
-	thread_t  * this    = CURRENT_THREAD;
-    process_t * process = this->process;
+	thread_t    * this    = CURRENT_THREAD;
+    process_t   * process = this->process;
 
     // get target thread ltid and cxy
@@ -89,6 +89,6 @@
 
     // check target thread joinable
-    flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
-    if( flags & THREAD_FLAG_DETACHED )
+    target_flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
+    if( target_flags & THREAD_FLAG_DETACHED )
     {
         printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ );
@@ -100,49 +100,47 @@
     if( target_ptr->signature != THREAD_SIGNATURE )
     {
-        printk("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ );
-        hal_core_sleep();
+        panic("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ );
     }
 
-    // wait target thread exit
-    while( 1 )
+    // get the lock protecting the join in target thread
+    remote_spinlock_lock( XPTR( target_cxy , &target_ptr->join_lock ) );
+
+    // get the blocked bit_vector from the target thread
+    target_blocked = hal_remote_lw( XPTR( target_cxy , &target_ptr->blocked ) );
+
+    if( target_blocked & THREAD_BLOCKED_JOIN )    // target thread arrived first
     {
-        // take the target thread lock protecting flags      
-        remote_spinlock_lock( XPTR( target_cxy , &target_ptr->flags_lock ) );
+        // unblock the target thread
+        thread_unblock( target_xp , THREAD_BLOCKED_JOIN );
 
-        // get the remote thread flags
-        flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
+        // release the lock protecting flags      
+        remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) );
 
-        // check the EXIT flag
-        if( flags & THREAD_FLAG_EXIT )   // target made an exit
-        {
-            // unblock the target thread
-            thread_unblock( target_xp , THREAD_BLOCKED_EXIT );
+        // get the exit value from target thread
+        *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) );
+    }
+    else                                          // this thread arrived first
+    {
+        // register this thread extended pointer in target thread
+        hal_remote_swd( XPTR( target_cxy , &target_ptr->join_xp ) , 
+                              XPTR( local_cxy , this ) );
 
-            // release the target thread lock protecting flags      
-            remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
+        // set the JOIN_DONE flag in target thread
+        hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) ,
+                              THREAD_FLAG_JOIN_DONE );
 
-            // exit while
-            break;
-        }
-        else                             // no exit done by target thread
-        {
-            // set the JOIN flag in target thread
-            hal_remote_atomic_or( XPTR( target_xp , &target_ptr->flags ) , 
-                                  THREAD_BLOCKED_JOIN );
+        // block this thread on BLOCKED_EXIT
+        thread_block( this , THREAD_BLOCKED_EXIT ); 
 
-            // block this thread 
-            thread_block( this , THREAD_BLOCKED_JOIN );
+        // release the lock protecting flags      
+        remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) );
 
-            // release the target thread lock protecting flags
-	        remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
-
-            // deschedule
-            sched_yield("waiting child exit");
-        }
+        // deschedule
+        sched_yield( "WAITING_EXIT" );
+    
+        // get the exit value from target thread when resume
+        *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) );
     }
 
-    // return exit_value from target thread descriptor
-    value = (intptr_t)hal_remote_lpt( XPTR( target_cxy , &target_ptr->exit_value ) );
-    *exit_value = (void *)value;
     return 0;
 
