Index: trunk/kernel/syscalls/sys_kill.c
===================================================================
--- trunk/kernel/syscalls/sys_kill.c	(revision 435)
+++ trunk/kernel/syscalls/sys_kill.c	(revision 436)
@@ -37,8 +37,7 @@
               uint32_t sig_id )
 {
-    uint32_t    save_sr;       // required to enable IRQs
-    xptr_t      owner_xp;      // extended pointer on target reference process
-    cxy_t       owner_cxy;     // target process cluster
-    process_t * owner_ptr;     // local pointer on target process
+    xptr_t      owner_xp;      // extended pointer on target process in owner cluster
+    cxy_t       owner_cxy;     // target process owner cluster
+    process_t * owner_ptr;     // local pointer on target process in owner cluster
     xptr_t      parent_xp;     // extended pointer on parent process
     cxy_t       parent_cxy;    // parent process cluster
@@ -49,4 +48,5 @@
     thread_t  * this    = CURRENT_THREAD;
     process_t * process = this->process;
+    trdid_t     trdid   = this->trdid;
 
 #if CONFIG_DEBUG_SYS_KILL
@@ -59,10 +59,15 @@
 #endif
 
-    // process cannot kill itself
-    if( pid == process->pid )
+    // get pointers on process descriptor in owner cluster
+    owner_xp  = cluster_get_owner_process_from_pid( pid );
+    owner_cxy = GET_CXY( owner_xp );
+    owner_ptr = GET_PTR( owner_xp );
+    
+    // check process found
+    if( owner_xp == XPTR_NULL)
     {
 
 #if CONFIG_DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : process %d cannot kill itself\n", __FUNCTION__ , pid );
+printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__, pid );
 #endif
         this->errno = EINVAL;
@@ -70,20 +75,15 @@
     }
 
-    // get cluster and pointers on owner target process descriptor
-    owner_xp  = cluster_get_owner_process_from_pid( pid );
-    owner_cxy = GET_CXY( owner_xp );
-    owner_ptr = GET_PTR( owner_xp );
-
-    // check process existence
-    if( owner_xp == XPTR_NULL )
+    // process can kill itself only when calling thread is the main thread
+    if( (pid == process->pid) && ((owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ))) ) 
     {
 
 #if CONFIG_DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid );
+printk("\n[ERROR] in %s : only main thread can kill itself\n", __FUNCTION__ );
 #endif
         this->errno = EINVAL;
         return -1;
     }
-    
+
     // get parent process PID
     parent_xp  = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
@@ -92,5 +92,5 @@
     ppid       = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
 
-    // processes INIT 
+    // check processe INIT 
     if( pid == 1 )
     {
@@ -103,37 +103,38 @@
     }
 
-    // enable IRQs
-    hal_enable_irq( &save_sr );
-
     // analyse signal type / supported values are : 0, SIGSTOP, SIGCONT, SIGKILL
     switch( sig_id )
     {
-        case 0 :
+        case 0 :          // does nothing
         {
-            // does nothing
             retval = 0;
             break;
         }
-        case SIGSTOP:     
+        case SIGSTOP:     // block all target process threads
         {
-            // remove TXT ownership from target process 
-            process_txt_reset_ownership( owner_xp );
+            // transfer TXT ownership 
+            process_txt_transfer_ownership( owner_xp );
 
-            // block all threads in all clusters
+            // block all threads in all clusters, but the main thread
             process_sigaction( pid , BLOCK_ALL_THREADS );
+
+            // get pointer on target process main thread
+            xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
+
+            // block main thread
+            thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
 
             // atomically update owner process termination state
             hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
                                   PROCESS_TERM_STOP );
- 
             retval = 0;
             break;
         }
-        case SIGCONT:
+        case SIGCONT:     // unblock all target process threads
         {
             // unblock all threads in all clusters
             process_sigaction( pid , UNBLOCK_ALL_THREADS );
 
-            // atomically update reference process termination state
+            // atomically update owner process termination state
             hal_remote_atomic_and( XPTR( owner_cxy , &owner_ptr->term_state ) ,
                                    ~PROCESS_TERM_STOP );
@@ -144,17 +145,20 @@
         case SIGKILL:
         {
-            // remove TXT ownership from owner process descriptor
-            process_txt_reset_ownership( owner_xp );
+            // remove process from TXT list
+            process_txt_detach( owner_xp );
 
-            // block all process threads in all clusters
-            process_sigaction( pid , BLOCK_ALL_THREADS );
-
-            // mark all process threads in all clusters for delete 
+            // mark for delete all process threads in all clusters, but the main 
             process_sigaction( pid , DELETE_ALL_THREADS );
 
-            // atomically update owner process descriptor flags
+            // get pointer on target process main thread
+            xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
+
+            // block main thread
+            thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
+
+            // atomically update owner process descriptor term_state to ask
+            // the parent process sys_wait() function to delete this main thread
             hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
                                   PROCESS_TERM_KILL );
-
             retval = 0;
             break;
@@ -172,7 +176,4 @@
     }
     
-    // restore IRQs
-    hal_restore_irq( save_sr );
-
     hal_fence();
 
@@ -180,5 +181,5 @@
 tm_end = hal_get_cycles();
 if( CONFIG_DEBUG_SYS_KILL < tm_end )
-printk("\n[DBG] %s : thread %x enter / process %x / sig %d / cost = %d / cycle %d\n",
+printk("\n[DBG] %s : thread %x exit / process %x / sig %d / cost = %d / cycle %d\n",
 __FUNCTION__ , this, pid, sig_id, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
 #endif
