Index: trunk/kernel/libk/remote_barrier.c
===================================================================
--- trunk/kernel/libk/remote_barrier.c	(revision 632)
+++ trunk/kernel/libk/remote_barrier.c	(revision 635)
@@ -83,5 +83,4 @@
                                 pthread_barrierattr_t * attr )
 {
-    xptr_t              gen_barrier_xp;   // extended pointer on generic barrier descriptor
     generic_barrier_t * gen_barrier_ptr;  // local pointer on generic barrier descriptor
     void              * barrier;          // local pointer on implementation barrier descriptor      
@@ -97,18 +96,8 @@
 
     // allocate memory for generic barrier descriptor
-    if( ref_cxy == local_cxy )                         // reference cluster is local
-    {
-        req.type          = KMEM_GEN_BARRIER;
-        req.flags         = AF_ZERO;
-        gen_barrier_ptr   = kmem_alloc( &req );
-        gen_barrier_xp    = XPTR( local_cxy , gen_barrier_ptr );
-    }
-    else                                               // reference cluster is remote
-    {
-        rpc_kcm_alloc_client( ref_cxy,
-                              KMEM_GEN_BARRIER,
-                              &gen_barrier_xp );
-        gen_barrier_ptr = GET_PTR( gen_barrier_xp );
-    }
+    req.type   = KMEM_KCM;
+    req.order  = bits_log2( sizeof(generic_barrier_t) );
+    req.flags  = AF_ZERO | AF_KERNEL;
+    gen_barrier_ptr = kmem_remote_alloc( ref_cxy , &req );
 
     if( gen_barrier_ptr == NULL )
@@ -124,9 +113,5 @@
          barrier = simple_barrier_create( count );
 
-        if( barrier == NULL )
-        {
-            printk("\n[ERROR] in %s : cannot create simple barrier\n", __FUNCTION__);
-            return -1;
-        }
+        if( barrier == NULL ) return -1;
     }
     else                                                  // QDT barrier implementation
@@ -147,9 +132,5 @@
         barrier = dqt_barrier_create( x_size , y_size , nthreads );
 
-        if( barrier == NULL )
-        {
-            printk("\n[ERROR] in %s : cannot create DQT barrier descriptor\n", __FUNCTION__);
-            return -1;
-        }
+        if( barrier == NULL ) return -1;
     }
 
@@ -211,16 +192,8 @@
 
     // release memory allocated to barrier descriptor
-    if( gen_barrier_cxy == local_cxy )            
-    {
-        req.type          = KMEM_GEN_BARRIER;
-        req.ptr           = gen_barrier_ptr;
-        kmem_free( &req );
-    }
-    else         
-    {
-        rpc_kcm_free_client( gen_barrier_cxy,
-                             gen_barrier_ptr,
-                             KMEM_GEN_BARRIER );
-    }
+    req.type          = KMEM_KCM;
+    req.ptr           = gen_barrier_ptr;
+    kmem_remote_free( ref_cxy , &req );
+
 }  // end generic_barrier_destroy()
 
@@ -273,5 +246,5 @@
 simple_barrier_t * simple_barrier_create( uint32_t  count )
 {
-    xptr_t             barrier_xp;
+    kmem_req_t         req;
     simple_barrier_t * barrier;
 
@@ -285,21 +258,14 @@
 
     // allocate memory for simple barrier descriptor
-    if( ref_cxy == local_cxy )                        // reference is local
-    {
-        kmem_req_t req;
-        req.type      = KMEM_SMP_BARRIER;
-        req.flags     = AF_ZERO;
-        barrier       = kmem_alloc( &req );
-        barrier_xp    = XPTR( local_cxy , barrier );
-    }
-    else                                             // reference is remote
-    {
-        rpc_kcm_alloc_client( ref_cxy,
-                              KMEM_SMP_BARRIER,
-                              &barrier_xp );
-        barrier = GET_PTR( barrier_xp );
-    }
-
-    if( barrier == NULL ) return NULL;
+    req.type   = KMEM_KCM;
+    req.order  = bits_log2( sizeof(simple_barrier_t) );
+    req.flags  = AF_ZERO | AF_KERNEL;
+    barrier    = kmem_remote_alloc( ref_cxy , &req );
+
+    if( barrier == NULL )
+    {
+        printk("\n[ERROR] in %s : cannot create simple barrier\n", __FUNCTION__ );
+        return NULL;
+    }
 
     // initialise simple barrier descriptor
@@ -325,4 +291,6 @@
 void simple_barrier_destroy( xptr_t barrier_xp )
 {
+    kmem_req_t  req;
+
     // get barrier cluster and local pointer
     cxy_t              barrier_cxy = GET_CXY( barrier_xp );
@@ -330,17 +298,7 @@
 
     // release memory allocated for barrier descriptor
-    if( barrier_cxy == local_cxy ) 
-    {
-        kmem_req_t  req;
-        req.type = KMEM_SMP_BARRIER;
-        req.ptr  = barrier_ptr;
-        kmem_free( &req );
-    }
-    else  
-    {
-        rpc_kcm_free_client( barrier_cxy,
-                             barrier_ptr,
-                             KMEM_SMP_BARRIER );
-    }
+    req.type = KMEM_KCM;
+    req.ptr  = barrier_ptr;
+    kmem_remote_free( barrier_cxy , &req );
 
 #if DEBUG_BARRIER_DESTROY
@@ -498,5 +456,5 @@
 
 #if DEBUG_BARRIER_CREATE
-static void dqt_barrier_display( xptr_t  barrier_xp );
+void dqt_barrier_display( xptr_t  barrier_xp );
 #endif
 
@@ -506,15 +464,8 @@
                                     uint32_t    nthreads )
 {
-    xptr_t          dqt_page_xp;     
-    page_t        * rpc_page;
-    xptr_t          rpc_page_xp;     
     dqt_barrier_t * barrier;       // local pointer on DQT barrier descriptor
     xptr_t          barrier_xp;    // extended pointer on DQT barrier descriptor
     uint32_t        z;             // actual DQT size == max(x_size,y_size)
     uint32_t        levels;        // actual number of DQT levels
-    xptr_t          rpc_xp;        // extended pointer on RPC descriptors array
-    rpc_desc_t    * rpc;           // pointer on RPC descriptors array
-    uint32_t        responses;     // responses counter for parallel RPCs
-    reg_t           save_sr;       // for critical section
     uint32_t        x;             // X coordinate in QDT mesh
     uint32_t        y;             // Y coordinate in QDT mesh
@@ -522,5 +473,5 @@
     kmem_req_t      req;           // kmem request
 
-    // compute size and number of DQT levels
+    // compute number of DQT levels, depending on the mesh size
     z      = (x_size > y_size) ? x_size : y_size;
     levels = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 3 : (z < 9) ? 4 : 5;
@@ -529,7 +480,4 @@
 assert( (z <= 16) , "DQT mesh size larger than (16*16)\n");
 
-// check RPC descriptor size
-assert( (sizeof(rpc_desc_t) <= 128), "RPC descriptor  larger than 128 bytes\n");
-
 // check size of an array of 5 DQT nodes
 assert( (sizeof(dqt_node_t) * 5 <= 512 ), "array of DQT nodes larger than 512 bytes\n");
@@ -538,5 +486,5 @@
 assert( (sizeof(dqt_barrier_t) <= 0x4000 ), "DQT barrier descriptor larger than 4 pages\n");
 
-    // get pointer on local client process descriptor
+    // get pointer on client thread and process descriptors
     thread_t  * this    = CURRENT_THREAD;
     process_t * process = this->process;
@@ -553,12 +501,18 @@
     cxy_t          ref_cxy = GET_CXY( ref_xp );
 
-    // 1. allocate 4 4 Kbytes pages for DQT barrier descriptor in reference cluster
-    dqt_page_xp = ppm_remote_alloc_pages( ref_cxy , 2 );
-
-    if( dqt_page_xp == XPTR_NULL ) return NULL;
-
-    // get pointers on DQT barrier descriptor
-    barrier_xp = ppm_page2base( dqt_page_xp );
-    barrier    = GET_PTR( barrier_xp );
+    // 1. allocate 4 small pages for the DQT barrier descriptor in reference cluster
+    req.type   = KMEM_PPM;
+    req.order  = 2;                     // 4 small pages == 16 Kbytes                     
+    req.flags  = AF_ZERO | AF_KERNEL;
+    barrier    = kmem_remote_alloc( ref_cxy , &req );
+
+    if( barrier == NULL )
+    {
+        printk("\n[ERROR] in %s : cannot create DQT barrier\n", __FUNCTION__ );
+        return NULL;
+    }
+
+    // get pointers on DQT barrier descriptor in reference cluster
+    barrier_xp = XPTR( ref_cxy , barrier );
 
     // initialize global parameters in DQT barrier descriptor
@@ -569,120 +523,68 @@
 #if DEBUG_BARRIER_CREATE
 if( cycle > DEBUG_BARRIER_CREATE ) 
-printk("\n[%s] thread[%x,%x] created DQT barrier descriptor at (%x,%x)\n",
+printk("\n[%s] thread[%x,%x] created DQT barrier descriptor(%x,%x)\n",
 __FUNCTION__, process->pid, this->trdid, ref_cxy, barrier );
 #endif
 
-    // 2. allocate memory from local cluster for an array of 256 RPCs descriptors
-    //    cannot share the RPC descriptor, because the returned argument is not shared
-    req.type    = KMEM_PAGE;
-    req.size    = 3;            // 8 pages == 32 Kbytes 
-    req.flags   = AF_ZERO;
-    rpc_page    = kmem_alloc( &req );
-    rpc_page_xp = XPTR( local_cxy , rpc_page );
-
-    // get pointers on RPC descriptors array
-    rpc_xp    = ppm_page2base( rpc_page_xp );
-    rpc       = GET_PTR( rpc_xp );
-
-#if DEBUG_BARRIER_CREATE
-if( cycle > DEBUG_BARRIER_CREATE ) 
-printk("\n[%s] thread[%x,%x] created RPC descriptors array at (%x,%s)\n",
-__FUNCTION__, process->pid, this->trdid, local_cxy, rpc );
-#endif
-
-    // 3. send parallel RPCs to all existing clusters covered by the DQT
-    //    to allocate memory for an array of 5 DQT nodes in each cluster
+    // 2. allocate memory for an array of 5 DQT nodes  
+    //    in all existing clusters covered by the DQDT
     //    (5 nodes per cluster <= 512 bytes per cluster)
-
-    responses = 0;    // initialize RPC responses counter
-
-    // mask IRQs
-    hal_disable_irq( &save_sr);
-
-    // client thread blocks itself
-    thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
-
+    //    and complete barrier descriptor initialisation. 
     for ( x = 0 ; x < x_size ; x++ )
     {
         for ( y = 0 ; y < y_size ; y++ )
         {
-            // send RPC to existing clusters only
+            cxy_t  cxy = HAL_CXY_FROM_XY( x , y );   // target cluster identifier
+            xptr_t local_array_xp;                   // xptr of nodes array in cluster cxy
+
+            // allocate memory in existing clusters only
             if( LOCAL_CLUSTER->cluster_info[x][y] )
             {
-                cxy_t cxy = HAL_CXY_FROM_XY( x , y );   // target cluster identifier
-
-                // build a specific RPC descriptor for each target cluster
-                rpc[cxy].rsp       = &responses;
-                rpc[cxy].blocking  = false;
-                rpc[cxy].index     = RPC_KCM_ALLOC;
-                rpc[cxy].thread    = this;
-                rpc[cxy].lid       = this->core->lid;
-                rpc[cxy].args[0]   = (uint64_t)KMEM_512_BYTES;  
-
-                // atomically increment expected responses counter
-                hal_atomic_add( &responses , 1 );
-
-                // send a non-blocking RPC to allocate 512 bytes in target cluster 
-                rpc_send( cxy , &rpc[cxy] ); 
-            }
-        }
-    }
-
-#if DEBUG_BARRIER_CREATE
-if( cycle > DEBUG_BARRIER_CREATE ) 
-printk("\n[%s] thread[%x,%x] sent all RPC requests to allocate dqt_nodes array\n",
-__FUNCTION__, process->pid, this->trdid );
-#endif
-
-    // client thread deschedule
-    sched_yield("blocked on parallel rpc_kcm_alloc");
-
-    // restore IRQs
-    hal_restore_irq( save_sr);
-
-    // 4. initialize the node_xp[x][y][l] array in DQT barrier descriptor
-    //    the node_xp[x][y][0] value is available in rpc.args[1]
-
-#if DEBUG_BARRIER_CREATE
-if( cycle > DEBUG_BARRIER_CREATE ) 
-printk("\n[%s] thread[%x,%x] initialises array of pointers on dqt_nodes\n",
-__FUNCTION__, process->pid, this->trdid );
-#endif
-
-    for ( x = 0 ; x < x_size ; x++ )
-    {
-        for ( y = 0 ; y < y_size ; y++ )
-        {
-            cxy_t    cxy      = HAL_CXY_FROM_XY( x , y );   // target cluster identifier
-            xptr_t   array_xp = (xptr_t)rpc[cxy].args[1];   // x_pointer on node array 
-            uint32_t offset   = sizeof( dqt_node_t );       // size of a DQT node
-                
-            // set values into the node_xp[x][y][l] array 
-            for ( l = 0 ; l < levels ; l++ )
-            {
-                xptr_t  node_xp = array_xp + (offset * l);
-                hal_remote_s64( XPTR( ref_cxy , &barrier->node_xp[x][y][l] ), node_xp );
-
-#if DEBUG_BARRIER_CREATE
+                req.type  = KMEM_KCM;
+                req.order = 9;                    // 512 bytes
+                req.flags = AF_ZERO | AF_KERNEL;
+
+                void * ptr = kmem_remote_alloc( cxy , &req );
+
+                if( ptr == NULL )
+                {
+                    printk("\n[ERROR] in %s : cannot allocate DQT in cluster %x\n",
+                    __FUNCTION__, cxy );
+                    return NULL;
+                }
+       
+                // build extended pointer on local node array in cluster cxy         
+			    local_array_xp = XPTR( cxy , ptr );
+
+                // initialize the node_xp[x][y][l] array in barrier descriptor
+                for ( l = 0 ; l < levels ; l++ )
+                {
+                    xptr_t  node_xp = local_array_xp + ( l * sizeof(dqt_node_t) );
+                    hal_remote_s64( XPTR( ref_cxy , &barrier->node_xp[x][y][l] ), node_xp );
+
+#if (DEBUG_BARRIER_CREATE & 1)
 if( cycle > DEBUG_BARRIER_CREATE )
 printk(" - dqt_node_xp[%d,%d,%d] = (%x,%x) / &dqt_node_xp = %x\n",
 x , y , l , GET_CXY( node_xp ), GET_PTR( node_xp ), &barrier->node_xp[x][y][l] );
 #endif
+                }  
             }
-        }
-    }
-
-    // 5. release memory locally allocated for the RPCs array
-    req.type  = KMEM_PAGE;
-    req.ptr   = rpc_page;
-    kmem_free( &req );
+            else   // register XPTR_NULL for all non-existing entries
+            {
+                for ( l = 0 ; l < levels ; l++ )
+                {
+                    hal_remote_s64( XPTR( ref_cxy , &barrier->node_xp[x][y][l] ), XPTR_NULL );
+                }
+            }
+        }  // end for y 
+    }  // end for x
 
 #if DEBUG_BARRIER_CREATE
 if( cycle > DEBUG_BARRIER_CREATE ) 
-printk("\n[%s] thread[%x,%x] released memory for RPC descriptors array\n",
+printk("\n[%s] thread[%x,%x] initialized array of pointers in DQT barrier\n",
 __FUNCTION__, process->pid, this->trdid );
 #endif
 
-    // 6. initialise all distributed DQT nodes using remote accesses
+    // 3. initialise all distributed DQT nodes using remote accesses
     //    and the pointers stored in the node_xp[x][y][l] array
     for ( x = 0 ; x < x_size ; x++ )
@@ -827,12 +729,8 @@
 void dqt_barrier_destroy( xptr_t   barrier_xp )
 {
-    page_t     * rpc_page;
-    xptr_t       rpc_page_xp;
-    rpc_desc_t * rpc;                      // local pointer on RPC descriptors array
-    xptr_t       rpc_xp;                   // extended pointer on RPC descriptor array
-    reg_t        save_sr;                  // for critical section
     kmem_req_t   req;                      // kmem request
-
-    thread_t * this = CURRENT_THREAD;
+    uint32_t     x;
+    uint32_t     y;
+
 
     // get DQT barrier descriptor cluster and local pointer
@@ -841,4 +739,5 @@
 
 #if DEBUG_BARRIER_DESTROY
+thread_t * this  = CURRENT_THREAD;
 uint32_t   cycle = (uint32_t)hal_get_cycles();
 if( cycle > DEBUG_BARRIER_DESTROY ) 
@@ -851,45 +750,16 @@
     uint32_t y_size = hal_remote_l32( XPTR( barrier_cxy , &barrier_ptr->y_size ) );
 
-    // 1. allocate memory from local cluster for an array of 256 RPCs descriptors
-    //    cannot share the RPC descriptor, because the "buf" argument is not shared
-    req.type    = KMEM_PAGE;
-    req.size    = 3;            // 8 pages == 32 Kbytes 
-    req.flags   = AF_ZERO;
-    rpc_page    = kmem_alloc( &req );
-    rpc_page_xp = XPTR( local_cxy , rpc_page );
-
-    // get pointers on RPC descriptors array
-    rpc_xp    = ppm_page2base( rpc_page_xp );
-    rpc       = GET_PTR( rpc_xp );
-   
-    // 2. send parallel RPCs to all existing clusters covered by the DQT
-    //    to release memory allocated for the arrays of DQT nodes in each cluster
-
-    uint32_t responses = 0;    // initialize RPC responses counter
-
-    // mask IRQs
-    hal_disable_irq( &save_sr);
-
-    // client thread blocks itself
-    thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
-
-    uint32_t x , y;
-    
-#if DEBUG_BARRIER_DESTROY
-if( cycle > DEBUG_BARRIER_DESTROY ) 
-printk("\n[%s] thread[%x,%x] send RPCs to release the distributed dqt_node array\n",
-__FUNCTION__, this->process->pid, this->trdid );
-#endif
-
+    // 1. release memory allocated for the DQT nodes
+    //    in all clusters covered by the QDT mesh
     for ( x = 0 ; x < x_size ; x++ )
     {
         for ( y = 0 ; y < y_size ; y++ )
         {
-            // send RPC to existing cluster only
+            // compute target cluster identifier
+            cxy_t   cxy = HAL_CXY_FROM_XY( x , y ); 
+
+            // existing cluster only
             if( LOCAL_CLUSTER->cluster_info[x][y] )
             {
-                // compute target cluster identifier
-                cxy_t   cxy       = HAL_CXY_FROM_XY( x , y ); 
-
                 // get local pointer on dqt_nodes array in target cluster  
                 xptr_t  buf_xp_xp = XPTR( barrier_cxy , &barrier_ptr->node_xp[x][y][0] );
@@ -899,48 +769,28 @@
 assert( (cxy == GET_CXY(buf_xp)) , "bad extended pointer on dqt_nodes array\n" );
 
-                // build a specific RPC descriptor 
-                rpc[cxy].rsp       = &responses;
-                rpc[cxy].blocking  = false;
-                rpc[cxy].index     = RPC_KCM_FREE;
-                rpc[cxy].thread    = this;
-                rpc[cxy].lid       = this->core->lid;
-                rpc[cxy].args[0]   = (uint64_t)(intptr_t)buf;  
-                rpc[cxy].args[1]   = (uint64_t)KMEM_512_BYTES;  
-
-                // atomically increment expected responses counter
-                hal_atomic_add( &responses , 1 );
-            
+                req.type  = KMEM_KCM;
+                req.ptr   = buf;
+                kmem_remote_free( cxy , &req );
+
 #if DEBUG_BARRIER_DESTROY
+thread_t * this  = CURRENT_THREAD;
+uint32_t   cycle = (uint32_t)hal_get_cycles();
 if( cycle > DEBUG_BARRIER_DESTROY ) 
-printk(" - target cluster(%d,%d) / buffer %x\n", x, y, buf );
-#endif
-                // send a non-blocking RPC to release 512 bytes in target cluster 
-                rpc_send( cxy , &rpc[cxy] ); 
+printk("\n[%s] thread[%x,%x] released node array %x in cluster %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, buf, cxy, cycle );
+#endif
             }
         }
     }
 
-    // client thread deschedule
-    sched_yield("blocked on parallel rpc_kcm_free");
-
-    // restore IRQs
-    hal_restore_irq( save_sr);
-
-    // 3. release memory locally allocated for the RPC descriptors array
-    req.type  = KMEM_PAGE;
-    req.ptr   = rpc_page;
-    kmem_free( &req );
-
-    // 4. release memory allocated for barrier descriptor 
-    xptr_t   page_xp  = ppm_base2page( barrier_xp );
-    cxy_t    page_cxy = GET_CXY( page_xp );
-    page_t * page_ptr = GET_PTR( page_xp );
-
-    ppm_remote_free_pages( page_cxy , page_ptr );
+    // 2. release memory allocated for barrier descriptor in ref cluster
+    req.type = KMEM_PPM;
+    req.ptr  = barrier_ptr;
+    kmem_remote_free( barrier_cxy , &req );
 
 #if DEBUG_BARRIER_DESTROY
 cycle = (uint32_t)hal_get_cycles();
 if( cycle > DEBUG_BARRIER_DESTROY ) 
-printk("\n[%s] thread[%x,%x] exit for barrier (%x,%x) / cycle %d\n",
+printk("\n[%s] thread[%x,%x] release barrier descriptor (%x,%x) / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, barrier_cxy, barrier_ptr, cycle );
 #endif
@@ -1022,6 +872,4 @@
                 {
                      uint32_t level = hal_remote_l32( XPTR( node_cxy , &node_ptr->level       ));
-                     uint32_t arity = hal_remote_l32( XPTR( node_cxy , &node_ptr->arity       ));
-                     uint32_t count = hal_remote_l32( XPTR( node_cxy , &node_ptr->current     ));
                      xptr_t   pa_xp = hal_remote_l32( XPTR( node_cxy , &node_ptr->parent_xp   ));
                      xptr_t   c0_xp = hal_remote_l32( XPTR( node_cxy , &node_ptr->child_xp[0] ));
@@ -1030,7 +878,7 @@
                      xptr_t   c3_xp = hal_remote_l32( XPTR( node_cxy , &node_ptr->child_xp[3] ));
 
-                     printk("   . level %d : (%x,%x) / %d on %d / P(%x,%x) / C0(%x,%x)"
+                     printk("   . level %d : (%x,%x) / P(%x,%x) / C0(%x,%x)"
                             " C1(%x,%x) / C2(%x,%x) / C3(%x,%x)\n",
-                     level, node_cxy, node_ptr, count, arity, 
+                     level, node_cxy, node_ptr, 
                      GET_CXY(pa_xp), GET_PTR(pa_xp),
                      GET_CXY(c0_xp), GET_PTR(c0_xp),
