Index: trunk/kernel/kern/process.c
===================================================================
--- trunk/kernel/kern/process.c	(revision 624)
+++ trunk/kernel/kern/process.c	(revision 625)
@@ -91,9 +91,10 @@
 }
 
-/////////////////////////////////////////////////
-void process_reference_init( process_t * process,
-                             pid_t       pid,
-                             xptr_t      parent_xp )
-{
+////////////////////////////////////////////////////
+error_t process_reference_init( process_t * process,
+                                pid_t       pid,
+                                xptr_t      parent_xp )
+{
+    error_t     error;
     xptr_t      process_xp;
     cxy_t       parent_cxy;
@@ -105,5 +106,4 @@
     uint32_t    stdout_id;
     uint32_t    stderr_id;
-    error_t     error;
     uint32_t    txt_id;
     char        rx_path[40];
@@ -111,10 +111,14 @@
     xptr_t      file_xp;
     xptr_t      chdev_xp;
-    chdev_t *   chdev_ptr;
+    chdev_t   * chdev_ptr;
     cxy_t       chdev_cxy;
     pid_t       parent_pid;
+    vmm_t     * vmm;
 
     // build extended pointer on this reference process
     process_xp = XPTR( local_cxy , process );
+
+    // get pointer on process vmm
+    vmm = &process->vmm;
 
     // get parent process cluster and local pointer
@@ -129,6 +133,6 @@
 uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
-printk("\n[%s] thread[%x,%x] enter to initalialize process %x / cycle %d\n",
-__FUNCTION__, parent_pid, this->trdid, pid, cycle );
+printk("\n[%s] thread[%x,%x] enter to initialize process %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, pid, cycle );
 #endif
 
@@ -144,14 +148,55 @@
     process->cwd_xp      = hal_remote_l64( XPTR( parent_cxy, &parent_ptr->cwd_xp ) );
 
-    // initialize vmm as empty 
-    error = vmm_init( process );
-
-assert( (error == 0) , "cannot initialize VMM\n" );
+    // initialize VSL as empty
+    vmm->vsegs_nr = 0;
+	xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) );
+
+    // create an empty GPT as required by the architecture
+    error = hal_gpt_create( &vmm->gpt );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot create empty GPT\n", __FUNCTION__ );
+        return -1;
+    }
+
+#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
+if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
+printk("\n[%s] thread[%x,%x] created empty GPT for process %x\n",
+__FUNCTION__, parent_pid, this->trdid, pid );
+#endif
+
+    // initialize GPT and VSL locks
+    remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );
+	remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL );
+
+    // register kernel vsegs in VMM as required by the architecture
+    error = hal_vmm_kernel_update( process );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot register kernel vsegs in VMM\n", __FUNCTION__ );
+        return -1;
+    }
+
+#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
+if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
+printk("\n[%s] thread[%x,%x] registered kernel vsegs for process %x\n",
+__FUNCTION__, parent_pid, this->trdid, pid );
+#endif
+
+    // create "args" and "envs" vsegs
+    // create "stacks" and "mmap" vsegs allocators 
+    // initialize locks protecting GPT and VSL
+    error = vmm_user_init( process );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot register user vsegs in VMM\n", __FUNCTION__ );
+        return -1;
+    }
  
 #if (DEBUG_PROCESS_REFERENCE_INIT & 1)
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
-printk("\n[%s] thread[%x,%x] / vmm empty for process %x / cycle %d\n", 
-__FUNCTION__, parent_pid, this->trdid, pid, cycle );
+printk("\n[%s] thread[%x,%x] initialized vmm for process %x\n", 
+__FUNCTION__, parent_pid, this->trdid, pid );
 #endif
 
@@ -187,6 +232,10 @@
                            &stdin_xp, 
                            &stdin_id );
-
-assert( (error == 0) , "cannot open stdin pseudo file" );
+        if( error )
+        {
+            printk("\n[ERROR] in %s : cannot open stdout pseudo-file\n", __FUNCTION__ );
+            return -1;
+        }
+
 assert( (stdin_id == 0) , "stdin index must be 0" );
 
@@ -206,7 +255,11 @@
                            &stdout_xp, 
                            &stdout_id );
-
-        assert( (error == 0) , "cannot open stdout pseudo file" );
-        assert( (stdout_id == 1) , "stdout index must be 1" );
+        if( error )
+        {
+            printk("\n[ERROR] in %s : cannot open stdout pseudo-file\n", __FUNCTION__ );
+            return -1;
+        }
+
+assert( (stdout_id == 1) , "stdout index must be 1" );
 
 #if (DEBUG_PROCESS_REFERENCE_INIT & 1)
@@ -225,7 +278,11 @@
                            &stderr_xp, 
                            &stderr_id );
-
-        assert( (error == 0) , "cannot open stderr pseudo file" );
-        assert( (stderr_id == 2) , "stderr index must be 2" );
+        if( error )
+        {
+            printk("\n[ERROR] in %s : cannot open stderr pseudo-file\n", __FUNCTION__ );
+            return -1;
+        }
+
+assert( (stderr_id == 2) , "stderr index must be 2" );
 
 #if (DEBUG_PROCESS_REFERENCE_INIT & 1)
@@ -240,5 +297,6 @@
     {
         // get extended pointer on stdin pseudo file in parent process
-        file_xp = (xptr_t)hal_remote_l64( XPTR( parent_cxy , &parent_ptr->fd_array.array[0] ) );
+        file_xp = (xptr_t)hal_remote_l64( XPTR( parent_cxy,
+                                                &parent_ptr->fd_array.array[0] ) );
 
         // get extended pointer on parent process TXT chdev
@@ -261,5 +319,6 @@
 
     // initialize lock protecting CWD changes
-    remote_busylock_init( XPTR( local_cxy , &process->cwd_lock ), LOCK_PROCESS_CWD );
+    remote_busylock_init( XPTR( local_cxy , 
+                                &process->cwd_lock ), LOCK_PROCESS_CWD );
 
 #if (DEBUG_PROCESS_REFERENCE_INIT & 1)
@@ -273,5 +332,6 @@
     xlist_root_init( XPTR( local_cxy , &process->children_root ) );
     process->children_nr     = 0;
-    remote_queuelock_init( XPTR( local_cxy , &process->children_lock ), LOCK_PROCESS_CHILDREN );
+    remote_queuelock_init( XPTR( local_cxy,
+                                 &process->children_lock ), LOCK_PROCESS_CHILDREN );
 
     // reset semaphore / mutex / barrier / condvar list roots and lock
@@ -280,9 +340,11 @@
     xlist_root_init( XPTR( local_cxy , &process->barrier_root ) );
     xlist_root_init( XPTR( local_cxy , &process->condvar_root ) );
-    remote_queuelock_init( XPTR( local_cxy , &process->sync_lock ), LOCK_PROCESS_USERSYNC );
+    remote_queuelock_init( XPTR( local_cxy , 
+                                 &process->sync_lock ), LOCK_PROCESS_USERSYNC );
 
     // reset open directories root and lock 
     xlist_root_init( XPTR( local_cxy , &process->dir_root ) );
-    remote_queuelock_init( XPTR( local_cxy , &process->dir_lock ), LOCK_PROCESS_DIR );
+    remote_queuelock_init( XPTR( local_cxy , 
+                                 &process->dir_lock ), LOCK_PROCESS_DIR );
 
     // register new process in the local cluster manager pref_tbl[]
@@ -315,4 +377,6 @@
 #endif
 
+    return 0;
+
 }  // process_reference_init()
 
@@ -321,9 +385,13 @@
                            xptr_t      reference_process_xp )
 {
-    error_t error;
+    error_t   error;
+    vmm_t   * vmm;
 
     // get reference process cluster and local pointer
     cxy_t       ref_cxy = GET_CXY( reference_process_xp );
     process_t * ref_ptr = GET_PTR( reference_process_xp );
+
+    // get pointer on process vmm
+    vmm = &local_process->vmm;
 
     // initialize PID, REF_XP, PARENT_XP, and STATE
@@ -343,14 +411,51 @@
 
 // check user process
-assert( (local_process->pid != 0), "PID cannot be 0" );
-
-    // reset local process vmm
-    error = vmm_init( local_process );
-    assert( (error == 0) , "cannot initialize VMM\n");
-
-    // reset process file descriptors array
+assert( (local_process->pid != 0), "LPID cannot be 0" );
+
+    // initialize VSL as empty
+    vmm->vsegs_nr = 0;
+	xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) );
+
+    // create an empty GPT as required by the architecture
+    error = hal_gpt_create( &vmm->gpt );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot create empty GPT\n", __FUNCTION__ );
+        return -1;
+    }
+
+    // initialize GPT and VSL locks
+    remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );
+	remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL );
+
+    // register kernel vsegs in VMM as required by the architecture
+    error = hal_vmm_kernel_update( local_process );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot register kernel vsegs in VMM\n", __FUNCTION__ );
+        return -1;
+    }
+
+    // create "args" and "envs" vsegs
+    // create "stacks" and "mmap" vsegs allocators 
+    // initialize locks protecting GPT and VSL
+    error = vmm_user_init( local_process );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot register user vsegs in VMM\n", __FUNCTION__ );
+        return -1;
+    }
+ 
+#if (DEBUG_PROCESS_COPY_INIT & 1)
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_COPY_INIT < cycle )
+printk("\n[%s] thread[%x,%x] initialized vmm for process %x / cycle %d\n", 
+__FUNCTION__, parent_pid, this->trdid, pid, cycle );
+#endif
+
+    // set process file descriptors array
 	process_fd_init( local_process );
 
-    // reset vfs_root_xp / vfs_bin_xp / cwd_xp fields
+    // set vfs_root_xp / vfs_bin_xp / cwd_xp fields
     local_process->vfs_root_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) );
     local_process->vfs_bin_xp  = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) );
@@ -380,5 +485,4 @@
     local_process->th_nr  = 0;
     rwlock_init( &local_process->th_lock , LOCK_PROCESS_THTBL );
-
 
     // register new process descriptor in local cluster manager local_list
@@ -451,8 +555,18 @@
 #endif
 
-    // remove process from children_list 
-    // and release PID if owner cluster
+    // when target process cluster is the owner cluster
+    // - remove process from TXT list and transfer ownership
+    // - remove process from children_list 
+    // - release PID
     if( CXY_FROM_PID( pid ) == local_cxy )
     {
+        process_txt_detach( XPTR( local_cxy , process ) );
+
+#if (DEBUG_PROCESS_DESTROY & 1)
+if( DEBUG_PROCESS_DESTROY < cycle )
+printk("\n[%s] thread[%x,%x] removed process %x from TXT list\n",
+__FUNCTION__, this->process->pid, this->trdid, pid );
+#endif
+
         // get pointers on parent process
         parent_xp  = process->parent_xp;
@@ -472,6 +586,6 @@
 #if (DEBUG_PROCESS_DESTROY & 1)
 if( DEBUG_PROCESS_DESTROY < cycle )
-printk("\n[%s] thread[%x,%x] removed process %x in cluster %x from children list\n",
-__FUNCTION__, this->process->pid, this->trdid, pid, local_cxy );
+printk("\n[%s] thread[%x,%x] removed process %x from parent process children list\n",
+__FUNCTION__, this->process->pid, this->trdid, pid );
 #endif
 
@@ -777,6 +891,6 @@
 uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_SIGACTION < cycle )
-printk("\n[%s] thread[%x,%x] enter in cluster %x for process %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, local_cxy, process->pid, cycle );
+printk("\n[%s] thread[%x,%x] enter for process %x n cluster %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, process->pid, local_cxy, cycle );
 #endif
 
@@ -1189,8 +1303,11 @@
 }  // end process_register_thread()
 
-/////////////////////////////////////////////////
-bool_t process_remove_thread( thread_t * thread )
+///////////////////////////////////////////////////
+uint32_t process_remove_thread( thread_t * thread )
 {
     uint32_t count;  // number of threads in local process descriptor
+
+// check thread
+assert( (thread != NULL) , "thread argument is NULL" );
 
     process_t * process = thread->process;
@@ -1205,7 +1322,4 @@
     count = process->th_nr;
 
-// check thread
-assert( (thread != NULL) , "thread argument is NULL" );
-
 // check th_nr value
 assert( (count > 0) , "process th_nr cannot be 0" );
@@ -1218,5 +1332,5 @@
     rwlock_wr_release( &process->th_lock );
 
-    return (count == 1);
+    return count;
 
 }  // end process_remove_thread()
@@ -1283,12 +1397,19 @@
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_MAKE_FORK < cycle )
-printk("\n[%s] thread[%x,%x] allocated process %x / cycle %d\n",
+printk("\n[%s] thread[%x,%x] allocated child_process %x / cycle %d\n",
 __FUNCTION__, pid, trdid, new_pid, cycle );
 #endif
 
     // initializes child process descriptor from parent process descriptor 
-    process_reference_init( process,
-                            new_pid,
-                            parent_process_xp );
+    error = process_reference_init( process,
+                                    new_pid,
+                                    parent_process_xp );
+    if( error ) 
+    {
+        printk("\n[ERROR] in %s : cannot initialize child process in cluster %x\n", 
+        __FUNCTION__, local_cxy ); 
+        process_free( process );
+        return -1;
+    }
 
 #if( DEBUG_PROCESS_MAKE_FORK & 1 )
@@ -1298,5 +1419,4 @@
 __FUNCTION__, pid, trdid, new_pid, cycle );
 #endif
-
 
     // copy VMM from parent descriptor to child descriptor
@@ -1361,6 +1481,6 @@
 #endif
 
-    // set Copy_On_Write flag in parent process GPT 
-    // this includes all replicated GPT copies
+    // set COW flag in DATA, ANON, REMOTE vsegs for parent process VMM
+    // this includes all parnet process copies in all clusters
     if( parent_process_cxy == local_cxy )   // reference is local
     {
@@ -1373,5 +1493,5 @@
     }
 
-    // set Copy_On_Write flag in child process GPT 
+    // set COW flag in DATA, ANON, REMOTE vsegs for child process VMM
     vmm_set_cow( process );
  
@@ -1423,5 +1543,5 @@
     char          ** args_pointers;           // array of pointers on main thread arguments
 
-    // get thread, process, pid and ref_xp 
+    // get calling thread, process, pid and ref_xp 
     thread  = CURRENT_THREAD;
     process = thread->process;
@@ -1470,20 +1590,20 @@
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
-printk("\n[%s] thread[%x,%x] deleted all threads / cycle %d\n",
+printk("\n[%s] thread[%x,%x] deleted existing threads / cycle %d\n",
 __FUNCTION__, pid, thread->trdid, cycle );
 #endif
 
-    // reset local process VMM
-    vmm_destroy( process );
+    // reset calling process VMM
+    vmm_user_reset( process );
 
 #if( DEBUG_PROCESS_MAKE_EXEC & 1 )
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
-printk("\n[%s] thread[%x,%x] reset VMM / cycle %d\n",
+printk("\n[%s] thread[%x,%x] completed VMM reset / cycle %d\n",
 __FUNCTION__, pid, thread->trdid, cycle );
 #endif
 
-    // re-initialize the VMM (kentry/args/envs vsegs registration)
-    error = vmm_init( process );
+    // re-initialize the VMM (args/envs vsegs registration)
+    error = vmm_user_init( process );
     if( error )
     {
@@ -1497,5 +1617,5 @@
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
-printk("\n[%s] thread[%x,%x] / kentry/args/envs vsegs registered / cycle %d\n",
+printk("\n[%s] thread[%x,%x] registered args/envs vsegs / cycle %d\n",
 __FUNCTION__, pid, thread->trdid, cycle );
 #endif
@@ -1515,5 +1635,5 @@
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
-printk("\n[%s] thread[%x,%x] / code/data vsegs registered / cycle %d\n",
+printk("\n[%s] thread[%x,%x] registered code/data vsegs / cycle %d\n",
 __FUNCTION__, pid, thread->trdid, cycle );
 #endif
@@ -1577,9 +1697,7 @@
     vmm->vsegs_nr = 0;
 	xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) );
-	remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ) , LOCK_VMM_VSL );
 
     // initialise GPT as empty
     error = hal_gpt_create( &vmm->gpt );
-
     if( error ) 
     {
@@ -1588,10 +1706,10 @@
     }
 
-    // initialize GPT lock
+    // initialize VSL and GPT locks
+	remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL );
     remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );
     
     // create kernel vsegs in GPT and VSL, as required by the hardware architecture
     error = hal_vmm_kernel_init( info );
-
     if( error ) 
     {
@@ -1652,8 +1770,9 @@
     // allocates memory for process descriptor from local cluster
 	process = process_alloc(); 
-	
-// check memory allocator
-assert( (process != NULL),
-"no memory for process descriptor in cluster %x", local_cxy  );
+    if( process == NULL )
+    {
+        printk("\n[PANIC] in %s : cannot allocate process\n", __FUNCTION__ );
+        hal_core_sleep();
+    }
 
     // set the CWD and VFS_ROOT fields in process descriptor
@@ -1663,17 +1782,24 @@
     // get PID from local cluster
     error = cluster_pid_alloc( process , &pid );
-
-// check PID allocator 
-assert( (error == 0),
-"cannot allocate PID in cluster %x", local_cxy );
-
-// check PID value
-assert( (pid == 1) ,
-"process INIT must be first process in cluster 0" );
+    if( error ) 
+    {
+        printk("\n[PANIC] in %s : cannot allocate PID\n", __FUNCTION__ );
+        hal_core_sleep();
+    }
+    if( pid != 1 ) 
+    {
+        printk("\n[PANIC] in %s : process PID must be 0x1\n", __FUNCTION__ );
+        hal_core_sleep();
+    }
 
     // initialize process descriptor / parent is local process_zero
-    process_reference_init( process,
-                            pid,
-                            XPTR( local_cxy , &process_zero ) );  
+    error = process_reference_init( process,
+                                    pid,
+                                    XPTR( local_cxy , &process_zero ) );  
+    if( error )
+    {
+        printk("\n[PANIC] in %s : cannot initialize process\n", __FUNCTION__ );
+        hal_core_sleep();
+    }
 
 #if(DEBUG_PROCESS_INIT_CREATE & 1)
@@ -1693,7 +1819,10 @@
 	                    &file_xp,
 	                    &file_id );
-
-assert( (error == 0),
-"failed to open file <%s>", CONFIG_PROCESS_INIT_PATH );
+    if( error )
+    {
+        printk("\n[PANIC] in %s : cannot open file <%s>\n",
+         __FUNCTION__, CONFIG_PROCESS_INIT_PATH  );
+        hal_core_sleep();
+    }
 
 #if(DEBUG_PROCESS_INIT_CREATE & 1)
@@ -1703,10 +1832,15 @@
 #endif
 
-   // register "code" and "data" vsegs as well as entry-point
+    // register "code" and "data" vsegs as well as entry-point
     // in process VMM, using information contained in the elf file.
 	error = elf_load_process( file_xp , process );
 
-assert( (error == 0),
-"cannot access .elf file <%s>", CONFIG_PROCESS_INIT_PATH );
+    if( error ) 
+    {
+        printk("\n[PANIC] in %s : cannot access file <%s>\n",
+         __FUNCTION__, CONFIG_PROCESS_INIT_PATH  );
+        hal_core_sleep();
+    }
+
 
 #if(DEBUG_PROCESS_INIT_CREATE & 1)
@@ -1714,4 +1848,8 @@
 printk("\n[%s] thread[%x,%x] registered code/data vsegs in VMM\n",
 __FUNCTION__, this->process->pid, this->trdid );
+#endif
+
+#if (DEBUG_PROCESS_INIT_CREATE & 1)
+hal_vmm_display( process , true );
 #endif
 
@@ -1751,9 +1889,14 @@
                                 &thread );
 
-assert( (error == 0),
-"cannot create main thread for <%s>", CONFIG_PROCESS_INIT_PATH );
-
-assert( (thread->trdid == 0),
-"main thread must have index 0 for <%s>", CONFIG_PROCESS_INIT_PATH );
+    if( error )
+    {
+        printk("\n[PANIC] in %s : cannot create main thread\n", __FUNCTION__  );
+        hal_core_sleep();
+    }
+    if( thread->trdid != 0 )
+    {
+        printk("\n[PANIC] in %s : bad main thread trdid\n", __FUNCTION__  );
+        hal_core_sleep();
+    }
 
 #if(DEBUG_PROCESS_INIT_CREATE & 1)
@@ -1989,5 +2132,5 @@
     process_txt_transfer_ownership( process_xp );
 
-    // get extended pointer on process stdin file
+    // get extended pointer on process stdin pseudo file
     file_xp = (xptr_t)hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) );
 
@@ -2014,5 +2157,5 @@
 uint32_t txt_id = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
 if( DEBUG_PROCESS_TXT < cycle )
-printk("\n[%s] thread[%x,%x] detached process %x from TXT %d / cycle %d\n",
+printk("\n[%s] thread[%x,%x] detached process %x from TXT%d / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, process_pid, txt_id, cycle );
 #endif
@@ -2056,5 +2199,5 @@
 uint32_t txt_id = hal_remote_l32( XPTR( txt_cxy , &txt_ptr->channel ) );
 if( DEBUG_PROCESS_TXT < cycle )
-printk("\n[%s] thread[%x,%x] give TXT %d to process %x / cycle %d\n",
+printk("\n[%s] thread[%x,%x] give TXT%d ownership to process %x / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, txt_id, process_pid, cycle );
 #endif
@@ -2078,6 +2221,5 @@
     xptr_t      iter_xp;         // iterator for xlist
     xptr_t      current_xp;      // extended pointer on current process
-    process_t * current_ptr;     // local pointer on current process
-    cxy_t       current_cxy;     // cluster for current process
+    bool_t      found;
 
 #if DEBUG_PROCESS_TXT
@@ -2086,12 +2228,12 @@
 #endif
 
-    // get pointers on process in owner cluster
+    // get pointers on target process 
     process_cxy = GET_CXY( process_xp );
     process_ptr = GET_PTR( process_xp );
     process_pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) );
 
-    // check owner cluster
-    assert( (process_cxy == CXY_FROM_PID( process_pid )) ,
-    "process descriptor not in owner cluster" );
+// check owner cluster
+assert( (process_cxy == CXY_FROM_PID( process_pid )) ,
+"process descriptor not in owner cluster" );
 
     // get extended pointer on stdin pseudo file
@@ -2103,9 +2245,9 @@
     txt_ptr = GET_PTR( txt_xp );
 
-    // get extended pointer on TXT_RX owner and TXT channel
+    // get relevant infos from chdev descriptor
     owner_xp = hal_remote_l64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) );
-    txt_id   = hal_remote_l32 ( XPTR( txt_cxy , &txt_ptr->channel ) );
-
-    // transfer ownership only if process is the TXT owner
+    txt_id   = hal_remote_l32( XPTR( txt_cxy , &txt_ptr->channel ) );
+
+    // transfer ownership only if target process is the TXT owner
     if( (owner_xp == process_xp) && (txt_id > 0) )  
     {
@@ -2114,101 +2256,100 @@
         lock_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.lock );
 
-        // get lock
-        remote_busylock_acquire( lock_xp );
-
-        if( process_get_ppid( process_xp ) != 1 )           // process is not KSH
+        if( process_get_ppid( process_xp ) != 1 )       // target process is not KSH
         {
+            // get lock
+            remote_busylock_acquire( lock_xp );
+
             // scan attached process list to find KSH process
-            XLIST_FOREACH( root_xp , iter_xp )
+            found = false;
+            for( iter_xp = hal_remote_l64( root_xp ) ;
+                 (iter_xp != root_xp) && (found == false) ;
+                 iter_xp = hal_remote_l64( iter_xp ) )
+            {
+                current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list );
+
+                if( process_get_ppid( current_xp ) == 1 )  // current is KSH 
+                {
+                    // set owner field in TXT chdev 
+                    hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
+
+#if DEBUG_PROCESS_TXT
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_TXT < cycle )
+printk("\n[%s] thread[%x,%x] transfered TXT%d ownership to KSH / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, txt_id, cycle );
+#endif
+                    found = true;
+                }
+            }
+
+            // release lock
+            remote_busylock_release( lock_xp );
+
+// It must exist a KSH process for each user TXT channel
+assert( (found == true), "KSH process not found for TXT%d", txt_id );
+
+        }
+        else                                           // target process is KSH
+        {
+            // get lock
+            remote_busylock_acquire( lock_xp );
+
+            // scan attached process list to find another process 
+            found = false;
+            for( iter_xp = hal_remote_l64( root_xp ) ;
+                 (iter_xp != root_xp) && (found == false) ;
+                 iter_xp = hal_remote_l64( iter_xp ) )
             {
                 current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
-                current_cxy = GET_CXY( current_xp );
-                current_ptr = GET_PTR( current_xp );
-
-                if( process_get_ppid( current_xp ) == 1 )  // current is KSH 
+
+                if( current_xp != process_xp )            // current is not KSH 
                 {
-                    // release lock
-                    remote_busylock_release( lock_xp );
-
                     // set owner field in TXT chdev 
                     hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
 
 #if DEBUG_PROCESS_TXT
-cycle = (uint32_t)hal_get_cycles();
-uint32_t ksh_pid = hal_remote_l32( XPTR( current_cxy , &current_ptr->pid ) );
+cycle  = (uint32_t)hal_get_cycles();
+cxy_t       current_cxy = GET_CXY( current_xp );
+process_t * current_ptr = GET_PTR( current_xp );
+uint32_t    new_pid     = hal_remote_l32( XPTR( current_cxy , &current_ptr->pid ) );
 if( DEBUG_PROCESS_TXT < cycle )
-printk("\n[%s] thread[%x,%x] release TXT %d to KSH %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, txt_id, ksh_pid, cycle );
-process_txt_display( txt_id );
-#endif
-                     return;
+printk("\n[%s] thread[%x,%x] transfered TXT%d ownership to process %x / cycle %d\n",
+__FUNCTION__,this->process->pid, this->trdid, txt_id, new_pid, cycle );
+#endif
+                    found = true;
                 }
             }
- 
+
             // release lock
             remote_busylock_release( lock_xp );
 
-            // PANIC if KSH not found
-            assert( false , "KSH process not found for TXT %d" );
-
-            return;
+            // no more owner for TXT if no other process found
+            if( found == false )
+            {
+                // set owner field in TXT chdev 
+                hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL );
+
+#if DEBUG_PROCESS_TXT
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_TXT < cycle )
+printk("\n[%s] thread[%x,%x] released TXT%d (no attached process) / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, txt_id, cycle );
+#endif
+            }
         }
-        else                                               // process is KSH
-        {
-            // scan attached process list to find another process 
-            XLIST_FOREACH( root_xp , iter_xp )
-            {
-                current_xp  = XLIST_ELEMENT( iter_xp , process_t , txt_list );
-                current_cxy = GET_CXY( current_xp );
-                current_ptr = GET_PTR( current_xp );
-
-                if( current_xp != process_xp )            // current is not KSH 
-                {
-                    // release lock
-                    remote_busylock_release( lock_xp );
-
-                    // set owner field in TXT chdev 
-                    hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp );
+    }
+    else
+    {
 
 #if DEBUG_PROCESS_TXT
-cycle  = (uint32_t)hal_get_cycles();
-uint32_t new_pid = hal_remote_l32( XPTR( current_cxy , &current_ptr->pid ) );
+cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_TXT < cycle )
-printk("\n[%s] thread[%x,%x] release TXT %d to process %x / cycle %d\n",
-__FUNCTION__,this->process->pid, this->trdid, txt_id, new_pid, cycle );
-process_txt_display( txt_id );
-#endif
-                     return;
-                }
-            }
-
-            // release lock
-            remote_busylock_release( lock_xp );
-
-            // no more owner for TXT if no other process found
-            hal_remote_s64( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL );
-
-#if DEBUG_PROCESS_TXT
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_PROCESS_TXT < cycle )
-printk("\n[%s] thread[%x,%x] release TXT %d to nobody / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, txt_id, cycle );
-process_txt_display( txt_id );
-#endif
-            return;
-        }
-    }
-    else
-    {
-
-#if DEBUG_PROCESS_TXT
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_PROCESS_TXT < cycle )
-printk("\n[%s] thread %x in process %d does nothing (not TXT owner) / cycle %d\n",
-__FUNCTION__, this->trdid, process_pid, cycle );
-process_txt_display( txt_id );
-#endif
-
-    }
+printk("\n[%s] thread[%x,%x] does nothing for process %x (not TXT owner) / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, process_pid, cycle );
+#endif
+
+    }
+
 }  // end process_txt_transfer_ownership()
 
