Index: trunk/kernel/kern/rpc.c
===================================================================
--- trunk/kernel/kern/rpc.c	(revision 438)
+++ trunk/kernel/kern/rpc.c	(revision 440)
@@ -114,6 +114,5 @@
     client_core_lid = this->core->lid;
 
-    // select a server_core index:
-    // use client core index if possible / core 0 otherwise
+    // select a server_core : use client core index if possible / core 0 otherwise
     if( client_core_lid < hal_remote_lw( XPTR( server_cxy , &cluster->cores_nr ) ) )
     {
@@ -133,5 +132,5 @@
 
     // get local pointer on rpc_fifo in remote cluster,
-    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
+    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
 
 	// post RPC in remote fifo / deschedule and retry if fifo full
@@ -231,5 +230,5 @@
     core_t        * core     = this->core;
     scheduler_t   * sched    = &core->scheduler;
-	remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
+	remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo[core->lid];
 
 #if DEBUG_RPC_SERVER_GENERIC
@@ -243,5 +242,5 @@
 	hal_disable_irq( &sr_save );
 
-    // activate (or create) RPC thread if RPC FIFO not empty  
+    // activate (or create) RPC thread if RPC FIFO not empty and no acive RPC thread  
 	if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) )
     {
@@ -254,5 +253,5 @@
 #endif
 
-        // search one IDLE RPC thread   
+        // search one IDLE RPC thread associated to the selected core   
         list_entry_t * iter;
         LIST_FOREACH( &sched->k_root , iter )
@@ -270,5 +269,5 @@
         }
 
-        // create new RPC thread if not found    
+        // create new RPC thread for the selected core if not found    
         if( found == false )                    
         {
@@ -277,16 +276,14 @@
 			                              &rpc_thread_func, 
                                           NULL,
-			                              this->core->lid );
-	        if( error ) 
-            {
-                assert( false , __FUNCTION__ ,
-                "no memory to allocate a new RPC thread in cluster %x", local_cxy );
-            }
+			                              core->lid );
+	         
+            assert( (error == 0), __FUNCTION__ ,
+            "no memory to allocate a new RPC thread in cluster %x", local_cxy );
 
             // unblock created RPC thread
             thread->blocked = 0;
 
-            // update core descriptor counter  
-            hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
+            // update RRPC threads counter  
+            hal_atomic_add( &LOCAL_CLUSTER->rpc_threads[core->lid] , 1 );
 
 #if DEBUG_RPC_SERVER_GENERIC
@@ -325,28 +322,33 @@
 void rpc_thread_func()
 {
-    uint32_t     count;       // handled RPC requests counter
-    error_t      empty;       // local RPC fifo state
-    xptr_t       desc_xp;     // extended pointer on RPC request
-    cxy_t        desc_cxy;    // RPC request cluster (client) 
-    rpc_desc_t * desc_ptr;    // RPC request local pointer 
-    uint32_t     index;       // RPC request index 
-    thread_t   * thread_ptr;  // local pointer on client thread
-    lid_t        core_lid;    // local index of client core
-    bool_t       blocking;    // blocking RPC when true
+    error_t         empty;              // local RPC fifo state
+    xptr_t          desc_xp;            // extended pointer on RPC request
+    cxy_t           desc_cxy;           // RPC request cluster (client) 
+    rpc_desc_t    * desc_ptr;           // RPC request local pointer 
+    uint32_t        index;              // RPC request index 
+    thread_t      * client_ptr;         // local pointer on client thread
+	thread_t      * server_ptr;         // local pointer on server thread
+    xptr_t          server_xp;          // extended pointer on server thread
+    lid_t           client_core_lid;    // local index of client core
+    lid_t           server_core_lid;    // local index of server core
+    bool_t          blocking;           // blocking RPC when true
+	remote_fifo_t * rpc_fifo;           // local pointer on RPC fifo
  
     // makes RPC thread not preemptable
 	hal_disable_irq( NULL );
   
-	thread_t      * this     = CURRENT_THREAD;
-	remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
+	server_ptr      = CURRENT_THREAD;
+    server_xp       = XPTR( local_cxy , server_ptr );
+    server_core_lid = server_ptr->core->lid;
+	rpc_fifo        = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
 
     // two embedded loops:
     // - external loop : "infinite" RPC thread
-    // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests
+    // - internal loop : handle one RPC request per iteration
  
 	while(1)  // infinite loop
 	{
         // try to take RPC_FIFO ownership
-        if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
+        if( hal_atomic_test_set( &rpc_fifo->owner , server_ptr->trdid ) )
         {
 
@@ -355,18 +357,12 @@
 if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
 printk("\n[DBG] %s : RPC thread %x in cluster %x takes RPC fifo ownership / cycle %d\n",
-__FUNCTION__, this, local_cxy, cycle );
-#endif
-            // initializes RPC requests counter
-            count = 0;
-
-		    // exit internal loop in three cases:
-            // - RPC fifo is empty
-            // - ownership has been lost (because descheduling)
-            // - max number of RPCs is reached
-	        while( 1 )  // internal loop
+__FUNCTION__, server_ptr, local_cxy, cycle );
+#endif
+	        while( 1 )  //  one RPC request per iteration 
             {
   	            empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
 
-	            if ( empty == 0 ) // one RPC request found
+                // exit when FIFO empty or FIFO ownership lost (in case of descheduling)
+	            if ( (empty == 0) && (rpc_fifo->owner == server_ptr->trdid) )
                 {
                     // get client cluster and pointer on RPC descriptor
@@ -381,5 +377,5 @@
 if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
 printk("\n[DBG] %s : RPC thread %x in cluster %x got rpc[%d] / rpc_cxy %x / rpc_ptr %x\n",
-__FUNCTION__, this, local_cxy, index, desc_cxy, desc_ptr );
+__FUNCTION__, server_ptr, local_cxy, index, desc_cxy, desc_ptr );
 #endif
                     // call the relevant server function
@@ -390,9 +386,6 @@
 if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
 printk("\n[DBG] %s : RPC thread %x in cluster %x completes rpc[%d] / rpc_ptr %x / cycle %d\n",
-__FUNCTION__, this, local_cxy, index, desc_ptr, cycle );
-#endif
-                    // increment handled RPCs counter
-  	                count++;
-
+__FUNCTION__, server_ptr, local_cxy, index, desc_ptr, cycle );
+#endif
                     // decrement response counter in RPC descriptor if blocking
                     if( blocking )
@@ -402,9 +395,9 @@
 
                         // get client thread pointer and client core lid from RPC descriptor
-                        thread_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
-                        core_lid   = hal_remote_lw ( XPTR( desc_cxy , &desc_ptr->lid ) );
+                        client_ptr      = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
+                        client_core_lid = hal_remote_lw ( XPTR( desc_cxy , &desc_ptr->lid ) );
 
                         // unblock client thread
-                        thread_unblock( XPTR( desc_cxy , thread_ptr ) , THREAD_BLOCKED_RPC );
+                        thread_unblock( XPTR( desc_cxy , client_ptr ) , THREAD_BLOCKED_RPC );
 
                         hal_fence();
@@ -414,24 +407,26 @@
 if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
 printk("\n[DBG] %s : RPC thread %x (cluster %x) unblocked client thread %x (cluster %x)\n",
-__FUNCTION__, this, local_cxy, thread_ptr, desc_cxy, cycle );
+__FUNCTION__, server_ptr, local_cxy, client_ptr, desc_cxy, cycle );
 #endif
                         // send IPI to client core
-	                    dev_pic_send_ipi( desc_cxy , core_lid );
+	                    dev_pic_send_ipi( desc_cxy , client_core_lid );
                     }
 		        }
-	
-                // chek exit condition
-  		        if( local_fifo_is_empty( rpc_fifo )  || 
-                    (rpc_fifo->owner != this->trdid) || 
-                    (count >= CONFIG_RPC_PENDING_MAX) ) break;
+                else
+                {
+                    break;
+                }
          	} // end internal loop
 
             // release rpc_fifo ownership if not lost
-            if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
+            if( rpc_fifo->owner == server_ptr->trdid ) rpc_fifo->owner = 0;
 
         }  // end if RPC fifo
 
-        // sucide if too many RPC threads in cluster
-        if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
+        // RPC thread blocks on IDLE 
+        thread_block( server_xp , THREAD_BLOCKED_IDLE );
+
+        // sucide if too many RPC threads / simply deschedule otherwise
+        if( LOCAL_CLUSTER->rpc_threads[server_core_lid] >= CONFIG_RPC_THREADS_MAX )
 	    {
 
@@ -440,32 +435,29 @@
 if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
 printk("\n[DBG] %s : RPC thread %x in cluster %x suicides / cycle %d\n",
-__FUNCTION__, this, local_cxy, cycle );
+__FUNCTION__, server_ptr, local_cxy, cycle );
 #endif
             // update RPC threads counter
 	        hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
 
-            // suicide
-	        thread_kill( XPTR( local_cxy , this ),
-                         true,                      // is_exit
-                         true );                    // is forced
+            // RPC thread blocks on GLOBAL
+	        thread_block( server_xp , THREAD_BLOCKED_GLOBAL );
+
+            // RPC thread set the REQ_DELETE flag to suicide
+            hal_remote_atomic_or( server_xp , THREAD_FLAG_REQ_DELETE );
 	    }
+        else
+        {
 
 #if DEBUG_RPC_SERVER_GENERIC
 uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
-printk("\n[DBG] %s : RPC thread %x in cluster %x deschedules / cycle %d\n",
-__FUNCTION__, this, local_cxy, cycle );
-#endif
-
-        // Block and deschedule
-        thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_IDLE );
-        sched_yield("RPC fifo empty or too much work");
-
-#if DEBUG_RPC_SERVER_GENERIC
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
-printk("\n[DBG] %s : RPC thread %x in cluster %x resumes / cycle %d\n",
-__FUNCTION__, this, local_cxy, cycle );
-#endif
+printk("\n[DBG] %s : RPC thread %x in cluster %x block & deschedules / cycle %d\n",
+__FUNCTION__, server_ptr, local_cxy, cycle );
+#endif
+
+            // RPC thread deschedules
+            assert( thread_can_yield( server_ptr ) , __FUNCTION__, "illegal sched_yield\n" );
+            sched_yield("RPC fifo empty");
+        }
 
 	} // end infinite loop
@@ -646,6 +638,6 @@
 
     // set input arguments in RPC descriptor  
-    rpc.args[0] = (uint64_t)(intptr_t)ref_process_xp;
-    rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp;
+    rpc.args[0] = (uint64_t)ref_process_xp;
+    rpc.args[1] = (uint64_t)parent_thread_xp;
 
     // register RPC request in remote RPC fifo
@@ -903,12 +895,14 @@
 void rpc_process_sigaction_server( xptr_t xp )
 {
-    pid_t        pid;              // target process identifier
-    process_t  * process;          // pointer on local target process descriptor
-    uint32_t     action;           // sigaction index
-    thread_t   * client_thread;    // pointer on client thread in client cluster
-    cxy_t        client_cxy;       // client cluster identifier
-    rpc_desc_t * rpc;              // pointer on rpc descriptor in client cluster
-    xptr_t       count_xp;         // extended pointer on response counter
-    lid_t        client_lid;       // client core local index
+    pid_t        pid;             // target process identifier
+    process_t  * process;         // pointer on local target process descriptor
+    uint32_t     action;          // sigaction index
+    thread_t   * client_ptr;      // pointer on client thread in client cluster
+    xptr_t       client_xp;       // extended pointer client thread
+    cxy_t        client_cxy;      // client cluster identifier
+    rpc_desc_t * rpc;             // pointer on rpc descriptor in client cluster
+    xptr_t       count_xp;        // extended pointer on responses counter
+    uint32_t     count_value;     // responses counter value
+    lid_t        client_lid;      // client core local index
 
     // get client cluster identifier and pointer on RPC descriptor
@@ -927,10 +921,14 @@
 #endif
 
+    // get client thread pointers
+    client_ptr = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) );
+    client_xp  = XPTR( client_cxy , client_ptr );
+
     // get local process descriptor
     process = cluster_get_local_process_from_pid( pid );
 
     // call relevant kernel function
-    if      ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process ); 
-    else if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process ); 
+    if      ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp ); 
+    else if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process , client_xp ); 
     else if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process );
 
@@ -939,12 +937,16 @@
 
     // decrement the responses counter in RPC descriptor,
+    count_value = hal_remote_atomic_add( count_xp , -1 );
+
     // unblock the client thread only if it is the last response.
-    if( hal_remote_atomic_add( count_xp , -1 ) == 1 ) 
+    if( count_value == 1 )
     {
-        // get client thread pointer and client core lid
-        client_thread = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) );
+        // get client core lid
         client_lid    = (lid_t)     hal_remote_lw ( XPTR( client_cxy , &rpc->lid    ) );
 
-        thread_unblock( XPTR( client_cxy , client_thread ) , THREAD_BLOCKED_RPC );
+        // unblock client thread
+        thread_unblock( client_xp , THREAD_BLOCKED_RPC );
+
+        // send an IPI to client core
         dev_pic_send_ipi( client_cxy , client_lid );
     }
@@ -1192,4 +1194,11 @@
                                     vfs_dentry_t * dentry )
 {
+#if DEBUG_RPC_VFS_DENTRY_DESTROY
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
 
@@ -1206,4 +1215,10 @@
     rpc_send( cxy , &rpc );
 
+#if DEBUG_RPC_VFS_DENTRY_DESTROY
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
+printk("\n[DBG] %s : thread %x exit / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , cycle );
+#endif
 }
 
@@ -1211,4 +1226,11 @@
 void rpc_vfs_dentry_destroy_server( xptr_t xp )
 {
+#if DEBUG_RPC_VFS_DENTRY_DESTROY
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     vfs_dentry_t * dentry;
 
@@ -1223,4 +1245,10 @@
     vfs_dentry_destroy( dentry );
 
+#if DEBUG_RPC_VFS_DENTRY_DESTROY
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
+printk("\n[DBG] %s : thread %x exit / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , cycle );
+#endif
 }
 
@@ -1319,4 +1347,11 @@
                                   vfs_file_t * file )
 {
+#if DEBUG_RPC_VFS_FILE_DESTROY
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
 
@@ -1333,4 +1368,10 @@
     rpc_send( cxy , &rpc );
 
+#if DEBUG_RPC_VFS_FILE_DESTROY
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
+printk("\n[DBG] %s : thread %x exit / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , cycle );
+#endif
 }
 
@@ -1338,4 +1379,11 @@
 void rpc_vfs_file_destroy_server( xptr_t xp )
 {
+#if DEBUG_RPC_VFS_FILE_DESTROY
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     vfs_file_t * file;
 
@@ -1350,4 +1398,10 @@
     vfs_file_destroy( file );
 
+#if DEBUG_RPC_VFS_FILE_DESTROY
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
+printk("\n[DBG] %s : thread %x exit / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , cycle );
+#endif
 }
 
@@ -1536,4 +1590,11 @@
                               error_t   * error )      // out
 {
+#if DEBUG_RPC_VMM_GET_VSEG
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_VSEG )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
 
@@ -1555,4 +1616,10 @@
     *error   = (error_t)rpc.args[3];
 
+#if DEBUG_RPC_VMM_GET_VSEG
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_VSEG )
+printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
 }
 
@@ -1560,4 +1627,11 @@
 void rpc_vmm_get_vseg_server( xptr_t xp )
 {
+#if DEBUG_RPC_VMM_GET_VSEG
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_VSEG )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     process_t   * process;
     intptr_t      vaddr;
@@ -1582,9 +1656,15 @@
     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
 
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// [21]          Marshaling functions attached to RPC_VMM_GET_PTE  (blocking)
+#if DEBUG_RPC_VMM_GET_VSEG
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_VSEG )
+printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// [21]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
 /////////////////////////////////////////////////////////////////////////////////////////
 
@@ -1598,9 +1678,16 @@
                              error_t   * error )   // out 
 {
-    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
-
-    // initialise RPC descriptor header 
-    rpc_desc_t  rpc;
-    rpc.index    = RPC_VMM_GET_PTE;
+#if DEBUG_RPC_VMM_GET_PTE
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_PTE )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
+    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
+
+    // initialise RPC descriptor header 
+    rpc_desc_t  rpc;
+    rpc.index    = RPC_VMM_GET_VSEG;
     rpc.blocking = true;
     rpc.responses = 1;
@@ -1619,4 +1706,10 @@
     *error = (error_t)rpc.args[5];
 
+#if DEBUG_RPC_VMM_GET_PTE
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_PTE )
+printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
 }
 
@@ -1624,4 +1717,11 @@
 void rpc_vmm_get_pte_server( xptr_t xp )
 {
+#if DEBUG_RPC_VMM_GET_PTE
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_PTE )
+printk("\n[DBG] %s : thread %x enter on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
+
     process_t   * process;
     vpn_t         vpn;
@@ -1648,4 +1748,10 @@
     hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
 
+#if DEBUG_RPC_VMM_GET_PTE
+cycle = (uint32_t)hal_get_cycles();
+if( cycle > DEBUG_RPC_VMM_GET_PTE )
+printk("\n[DBG] %s : thread %x exit on core[%x,%d] / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
+#endif
 }
 
