Index: trunk/kernel/syscalls/sys_exec.c
===================================================================
--- trunk/kernel/syscalls/sys_exec.c	(revision 421)
+++ trunk/kernel/syscalls/sys_exec.c	(revision 433)
@@ -149,7 +149,8 @@
 /////////////////////////////////////////////////////////////////////////////////////////
 // Implementation note:
-// This function build an exec_info_t structure containing all informations
+// This function must be called by the main thread (thread 0 in owner cluster).
+// IT build an exec_info_t structure containing all informations
 // required to initialize the new process descriptor and the associated thread.
-// It includes the process PID (unchanged), main() arguments, environment variables, 
+// It includes the process main() arguments, the environment variables, 
 // and the pathname to the new process .elf file. 
 // It calls the process_exec_get_strings() functions to copy the main() arguments and 
@@ -169,38 +170,45 @@
     error_t       error;
 
-    // get parent process pid
+    // get calling thread, process, & pid
     thread_t    * this    = CURRENT_THREAD;
     process_t   * process = this->process;
     pid_t         pid     = process->pid;
 
-#if CONFIG_SYSCALL_DEBUG
+    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ ,
+    "must be called in the owner cluster\n");
+
+    assert( (LTID_FROM_TRDID( this->trdid ) == 0) , __FUNCTION__ ,
+    "must be called by the main thread\n");
+
+    assert( (args == NULL) , __FUNCTION__ , 
+    "args not supported yet\n" );
+
+    assert( (envs == NULL) , __FUNCTION__ , 
+    "args not supported yet\n" );
+
+    // get owner cluster
+
+    // check pathname length
+    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
+    {
+
+#if CONFIG_DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
+#endif
+        this->errno = ENFILE;
+        return -1;
+    }
+
+    // copy pathname in exec_info structure (kernel space)
+    hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
+
+#if CONFIG_DEBUG_SYS_EXEC
 uint64_t      tm_start;
 uint64_t      tm_end;
 tm_start = hal_get_cycles();
-printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle = %d\n",
-__FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)tm_start );
-#endif
-
-    // get owner cluster
-    cxy_t  owner_cxy = CXY_FROM_PID( pid );
-
-    // check pathname length
-    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
-    {
-        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
-        this->errno = ENFILE;
-        return -1;
-    }
-
-    // copy pathname in exec_info structure (kernel space)
-    hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
-
-    // check args argument
-    assert( (args == NULL) , __FUNCTION__ , 
-    "args not supported yet\n" );
-
-    // check envs argument
-    assert( (envs == NULL) , __FUNCTION__ , 
-    "args not supported yet\n" );
+if( CONFIG_DEBUG_SYS_EXEC < tm_start )
+printk("\n[DBG] %s : thread %x enter / process %x / path %s / cycle = %d\n",
+__FUNCTION__, this, pid, exec_info.path, (uint32_t)tm_start );
+#endif
 
     // check and store args in exec_info structure if required
@@ -209,5 +217,8 @@
         if( process_exec_get_strings( &exec_info , true , args ) )
         {
-            printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
+
+#if CONFIG_DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
+#endif
             this->errno = error;
             return -1;
@@ -220,5 +231,8 @@
         if( process_exec_get_strings( &exec_info , false , envs ) )
         {
-            printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
+
+#if CONFIG_DEBUG_SYCALLS_ERROR
+printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
+#endif
             this->errno = error;
             return -1;
@@ -226,35 +240,32 @@
     }
 
-    // register PID in exec_info
-    exec_info.pid = pid;
-
-    // call process_make_exec (local or remote)
-    if( owner_cxy == local_cxy )
-    {
-        error = process_make_exec( &exec_info );
-    }
-    else
-    {
-        rpc_process_make_exec_client( owner_cxy,
-                                      &exec_info,
-                                      &error );
-    }
+    // call relevant kernel function
+    error = process_make_exec( &exec_info );
 
     if( error )
     {
-        printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n",
-        __FUNCTION__, pid, owner_cxy );
+
+#if CONFIG_DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : cannot create process %x in cluster %x\n",
+__FUNCTION__, pid, CXY_FROM_PID( pid );
+#endif
         this->errno = error;
         return -1;
     }
 
-#if CONFIG_SYSCALL_DEBUG
+#if CONFIG_DEBUG_SYS_EXEC
 tm_end = hal_get_cycles();
-printk("\n[DBG] %s : core[%x,%d] exit / process %x / path = %s / cost = %d / cycle %d\n",
-__FUNCTION__, local_cxy, this->core->lid, pid, exec_info.path, 
-(uint32_t)(tm_end - tm_start) , (uint32_t)tm_end );
-#endif
-
-    return 0;
+if( CONFIG_DEBUG_SYS_EXEC < tm_end )
+printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n",
+__FUNCTION__, this, pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
+#endif
+
+    // deschedule <=> old thread suicide because the BLOCKED_GLOBAL
+    // and the FLAG_REQ_DELETE have been set by process_make_exec()
+    sched_yield( "old process suicide in sys_exec()" );
+
+    assert( false , __FUNCTION__ , "This code should not be executed\n" );
+
+    return 0;  
 
 } // end sys_exec()
