Index: trunk/kernel/kern/cluster.c
===================================================================
--- trunk/kernel/kern/cluster.c	(revision 690)
+++ trunk/kernel/kern/cluster.c	(revision 1)
@@ -1,8 +1,8 @@
 /*
  * cluster.c - Cluster-Manager related operations
- *
- * Author  Ghassan Almaless       (2008,2009,2010,2011,2012)
+ * 
+ * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
  *         Mohamed Lamine Karaoui (2015)
- *         Alain Greiner          (2016,2017,2018,2019,2020)
+ *         Alain Greiner (2016)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -24,19 +24,16 @@
  */
 
-#include <kernel_config.h>
-#include <hal_kernel_types.h>
+#include <almos_config.h>
+#include <hal_types.h>
 #include <hal_atomic.h>
 #include <hal_special.h>
-#include <hal_ppm.h>
-#include <hal_macros.h>
-#include <remote_fifo.h>
 #include <printk.h>
 #include <errno.h>
-#include <queuelock.h>
+#include <spinlock.h>
 #include <core.h>
-#include <chdev.h>
 #include <scheduler.h>
 #include <list.h>
 #include <cluster.h>
+#include <sysfs.h>
 #include <boot_info.h>
 #include <bits.h>
@@ -47,26 +44,28 @@
 #include <dqdt.h>
 
-/////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
 // Extern global variables
-/////////////////////////////////////////////////////////////////////////////////////
-
-extern process_t           process_zero;     // allocated in kernel_init.c
-extern chdev_directory_t   chdev_dir;        // allocated in kernel_init.c
-
-
-
-///////////////////////////////////////////////////
-void cluster_info_init( struct boot_info_s * info )
-{
-    boot_device_t * dev;      // pointer on external peripheral
-    uint32_t        func;     // external peripheral functionnal type
-    uint32_t        x;
-    uint32_t        y;
-    uint32_t        i;   
+///////////////////////////////////////////////////////////////////////////////////////////
+
+process_t process_zero;
+
+
+
+//////////////////////////////////
+void cluster_sysfs_register(void)
+{
+	// TODO
+}
+
+/////////////////////////////////////////////////
+error_t cluster_init( struct boot_info_s * info )
+{
+    lpid_t      lpid;     // local process_index
+    lid_t       lid;      // local core index
 
 	cluster_t * cluster = LOCAL_CLUSTER;
 
     // initialize cluster global parameters
-	cluster->paddr_width     = info->paddr_width;
+	cluster->paddr_width     = info->paddr_width; 
 	cluster->x_width         = info->x_width;
 	cluster->y_width         = info->y_width;
@@ -74,122 +73,34 @@
 	cluster->y_size          = info->y_size;
 	cluster->io_cxy          = info->io_cxy;
-	cluster->sys_clk         = info->sys_clk;
-
-    // initialize the cluster_info[][] array
-    for( x = 0 ; x < CONFIG_MAX_CLUSTERS_X ; x++ ) 
-    {
-        for( y = 0; y < CONFIG_MAX_CLUSTERS_Y ; y++ ) 
-        {
-            cluster->cluster_info[x][y] = info->cluster_info[x][y];
-        }
-    }
-
-    // initialize external peripherals channels
-    for( i = 0 ; i < info->ext_dev_nr ; i++ )
-    {
-        dev  = &info->ext_dev[i];
-        func = FUNC_FROM_TYPE( dev->type );   
-        if( func == DEV_FUNC_TXT ) cluster->nb_txt_channels = dev->channels;
-        if( func == DEV_FUNC_NIC ) cluster->nb_nic_channels = dev->channels;
-        if( func == DEV_FUNC_IOC ) cluster->nb_ioc_channels = dev->channels;
-        if( func == DEV_FUNC_FBF ) cluster->nb_fbf_channels = dev->channels;
-    }
-
-    // initialize number of local cores
-	cluster->cores_nr  = info->cores_nr;
-
-}  // end cluster_info_init()
-
-//////////////////////////////////////
-void cluster_info_display( cxy_t cxy )
-{
-    uint32_t  x;
-    uint32_t  y;
-    uint32_t  ncores;
-
-    cluster_t * cluster = LOCAL_CLUSTER;
-
-    // get x_size & y_size from target cluster
-    uint32_t  x_size = hal_remote_l32( XPTR( cxy , &cluster->x_size ) );
-    uint32_t  y_size = hal_remote_l32( XPTR( cxy , &cluster->y_size ) );
-
-    // get pointers on TXT0 chdev
-    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
-    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
-    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
-
-    // get extended pointer on remote TXT0 lock
-    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
-
-    // get TXT0 lock 
-    remote_busylock_acquire( lock_xp );
-
-    nolock_printk("\n***** cluster_info in cluster %x / x_size %d / y_size %d\n",
-    cxy, x_size, y_size );
+
+    // initialize cluster local parameters
+	cluster->cores_nr        = info->cores_nr;
+    cluster->cores_in_kernel = info->cores_nr;   // all cpus start in kernel mode
+
+    // initialize kcm lock
+	spinlock_init( &cluster->kcm_lock );
+
+    // initialize txt0 lock
+	remote_spinlock_init( XPTR( local_cxy , &cluster->txt0_lock ) );
+
+    // initialises DQDT 
+    cluster->dqdt_root_level = dqdt_init( info->x_size, 
+                                          info->y_size, 
+                                          info->y_width );
+    cluster->threads_var = 0;
+    cluster->pages_var   = 0;
+
+    // initialises embedded PPM
+	ppm_init( &cluster->ppm,
+              info->pages_nr,
+              info->pages_offset );
+
+    // initialises embedded KHM
+	khm_init( &cluster->khm );
   
-    for( x = 0 ; x < x_size ; x++ )
-    {
-        for( y = 0 ; y < y_size ; y++ )
-        {
-            ncores = (uint32_t)hal_remote_lb( XPTR( cxy , &cluster->cluster_info[x][y] ) );
-            nolock_printk(" - ncores[%d][%d] = %d\n", x, y, ncores );
-        }
-    }
-
-    // release TXT0 lock
-    remote_busylock_release( lock_xp );
-
-}  // end cluster_info_display()
-
-/////////////////////////////////////////////////////////
-error_t cluster_manager_init( struct boot_info_s * info )
-{
-    error_t         error;
-    lpid_t          lpid;     // local process_index
-    lid_t           lid;      // local core index
-
-	cluster_t * cluster = LOCAL_CLUSTER;
-
-#if DEBUG_CLUSTER_INIT
-uint32_t   cycle = (uint32_t)hal_get_cycles();
-thread_t * this  = CURRENT_THREAD;
-if( DEBUG_CLUSTER_INIT < cycle )
-printk("\n[%s] thread[%x,%x] enters for cluster %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, local_cxy , cycle );
-#endif
-
-#if (DEBUG_CLUSTER_INIT & 1)
-cluster_info_display( local_cxy );
-#endif
-
-    // initialises embedded PPM
-	error = hal_ppm_init( info );
-
-    if( error )
-    {
-        printk("\n[ERROR] in %s : cannot initialize PPM in cluster %x\n",
-               __FUNCTION__ , local_cxy );
-        return ENOMEM;
-    }
-
-#if( DEBUG_CLUSTER_INIT & 1 )
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_INIT < cycle )
-printk("\n[%s] PPM initialized in cluster %x / cycle %d\n",
-__FUNCTION__ , local_cxy , cycle );
-#endif
-
-    // initialises embedded KCM
-    uint32_t  i;
-    for( i = 0 ; i < 6 ; i++ ) kcm_init( &cluster->kcm[i] , i+6 );
-
-#if( DEBUG_CLUSTER_INIT & 1 )
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_INIT < cycle )
-printk("\n[%s] KCM[6:11] initialized in cluster %x at cycle %d\n",
-__FUNCTION__ , local_cxy , hal_get_cycles() );
-#endif
-
-    // initialises all cores descriptors 
+    // initialises embedded KCM 
+	kcm_init( &cluster->kcm , KMEM_KCM ); 
+
+    // initialises cores
 	for( lid = 0 ; lid < cluster->cores_nr; lid++ )
 	{
@@ -198,31 +109,13 @@
 	               info->core[lid].gid );      // gid from boot_info_t
 	}
-
-#if( DEBUG_CLUSTER_INIT & 1 )
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_INIT < cycle )
-printk("\n[%s] cores initialized in cluster %x / cycle %d\n",
-__FUNCTION__ , local_cxy , cycle );
-#endif
-
-    // initialises RPC FIFOs
-	for( lid = 0 ; lid < cluster->cores_nr; lid++ )
-    {
-	    remote_fifo_init( &cluster->rpc_fifo[lid] );
-        cluster->rpc_threads[lid] = 0;
-    }
-
-#if( DEBUG_CLUSTER_INIT & 1 )
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_INIT < cycle )
-printk("\n[%s] RPC fifo inialized in cluster %x at cycle %d\n",
-__FUNCTION__ , local_cxy , hal_get_cycles() );
-#endif
+	
+    // initialises RPC fifo
+	rpc_fifo_init( &cluster->rpc_fifo );
 
     // initialise pref_tbl[] in process manager
-	queuelock_init( &cluster->pmgr.pref_lock , LOCK_CLUSTER_PREFTBL );
+	spinlock_init( &cluster->pmgr.pref_lock );
     cluster->pmgr.pref_nr = 0;
-    cluster->pmgr.pref_tbl[0] = XPTR( local_cxy , &process_zero );
-    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
+    cluster->pmgr.pref_tbl[0] = XPTR( local_cxy , &process_zero );   
+    for( lpid = 1 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
     {
         cluster->pmgr.pref_tbl[lpid] = XPTR_NULL;
@@ -230,60 +123,39 @@
 
     // initialise local_list in process manager
-    xlist_root_init( XPTR( local_cxy , &cluster->pmgr.local_root ) );
+	spinlock_init( &cluster->pmgr.local_lock );
+    list_root_init( &cluster->pmgr.local_root );
     cluster->pmgr.local_nr = 0;
-	remote_queuelock_init( XPTR( local_cxy , &cluster->pmgr.local_lock ) ,
-                           LOCK_CLUSTER_LOCALS );
 
     // initialise copies_lists in process manager
-    for( lpid = 0 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
-    {
+    for( lpid = 1 ; lpid < CONFIG_MAX_PROCESS_PER_CLUSTER ; lpid++ )
+    {
+	    remote_spinlock_init( XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] ) );
         cluster->pmgr.copies_nr[lpid] = 0;
         xlist_root_init( XPTR( local_cxy , &cluster->pmgr.copies_root[lpid] ) );
-	    remote_queuelock_init( XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] ),
-                               LOCK_CLUSTER_COPIES );
-    }
-
-#if DEBUG_CLUSTER_INIT
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_INIT < cycle )
-printk("\n[%s] thread[%x,%x] exit for cluster %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
-#endif
-
-    hal_fence();
+    }    
+
+    hal_wbflush();
+
+    // wait all clusters initialised on barrier located in cluster_io
+    remote_barrier( XPTR( cluster->io_cxy , &cluster->barrier ) ,
+                    cluster->x_size * cluster->y_size );
 
 	return 0;
-} // end cluster_manager_init()
-
-///////////////////////////////////
-cxy_t cluster_random_select( void )
-{
-    uint32_t  index;
-    uint32_t  x;    
-    uint32_t  y;
-    cxy_t     cxy;
-
-    uint32_t  x_size    = LOCAL_CLUSTER->x_size;
-    uint32_t  y_size    = LOCAL_CLUSTER->y_size;
-
-    do 
-    {
-        index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
-        x         = index / y_size;
-        y         = index % y_size;
-        cxy       = HAL_CXY_FROM_XY( x , y );
-    }
-    while ( cluster_is_active( cxy ) == false );
-
-    return ( cxy );
-}
-
-/////////////////////////////////////////////
-inline bool_t cluster_is_active ( cxy_t cxy )
-{
-    uint32_t x = HAL_X_FROM_CXY( cxy );
-    uint32_t y = HAL_Y_FROM_CXY( cxy );
-
-    return ( LOCAL_CLUSTER->cluster_info[x][y] != 0 );
+} // end cluster_init()
+
+////////////////////////////////////////
+bool_t cluster_is_undefined( cxy_t cxy )
+{
+    cluster_t * cluster = LOCAL_CLUSTER;
+
+    uint32_t y_width = cluster->y_width;
+
+    uint32_t x = cxy >> y_width;
+    uint32_t y = cxy & ((1<<y_width)-1);
+
+    if( x >= cluster->x_size ) return true;  
+    if( y >= cluster->y_size ) return true;  
+
+    return false;
 }
 
@@ -292,134 +164,46 @@
 ////////////////////////////////////////////////////////////////////////////////////
 
-/////////////////////////////////////////////
-lid_t cluster_select_local_core( cxy_t  cxy )
-{
-    uint32_t      min = 1000000;
-    lid_t         sel = 0;
-    uint32_t      nthreads;
-    lid_t         lid;
-    scheduler_t * sched;
-    cluster_t   * cluster = LOCAL_CLUSTER;
-    uint32_t      ncores = hal_remote_l32( XPTR( cxy , &cluster->cores_nr ) );
-
-    for( lid = 0 ; lid < ncores ; lid++ )
-    {
-        sched  = &cluster->core_tbl[lid].scheduler;
-
-        nthreads = hal_remote_l32( XPTR( cxy , &sched->u_threads_nr ) ) +
-                   hal_remote_l32( XPTR( cxy , &sched->k_threads_nr ) );
-
-        if( nthreads < min )
+////////////////////////////////
+void cluster_core_kernel_enter()
+{
+    cluster_t * cluster = LOCAL_CLUSTER;
+	hal_atomic_inc( &cluster->cores_in_kernel );
+}
+
+///////////////////////////////
+void cluster_core_kernel_exit()
+{
+    cluster_t * cluster = LOCAL_CLUSTER;
+	hal_atomic_dec( &cluster->cores_in_kernel );
+}
+
+/////////////////////////////////
+lid_t cluster_select_local_core()
+{
+    uint32_t min = 100;
+    lid_t    sel = 0;
+    lid_t    lid;
+
+    cluster_t * cluster = LOCAL_CLUSTER;
+
+    for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
+    {
+        if( cluster->core_tbl[lid].usage < min )
         {
-            min = nthreads;
+            min = cluster->core_tbl[lid].usage;
             sel = lid;
         }
-    }
+    } 
     return sel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
-//  Process related functions
+//  Process management related functions
 ////////////////////////////////////////////////////////////////////////////////////
-
-
-//////////////////////////////////////////////////////
-xptr_t cluster_get_process_from_pid_in_cxy( cxy_t cxy,
-                                            pid_t pid )
-{
-    xptr_t      root_xp;       // xptr on root of list of processes in owner cluster
-    xptr_t      lock_xp;       // xptr on lock protecting this list
-    xptr_t      iter_xp;       // iterator
-    xptr_t      current_xp;    // xptr on current process descriptor
-    bool_t      found;
-
-    cluster_t * cluster = LOCAL_CLUSTER;
-
-    // get owner cluster and lpid
-    cxy_t   owner_cxy = CXY_FROM_PID( pid );
-    lpid_t  lpid      = LPID_FROM_PID( pid );
-
-    // get lock & root of list of copies from owner cluster
-    root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
-    lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
-
-    // take the lock protecting the list of processes
-    remote_queuelock_acquire( lock_xp );
-
-    // scan list of processes
-    found = false;
-    XLIST_FOREACH( root_xp , iter_xp )
-    {
-        current_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
-
-        if( GET_CXY( current_xp ) == cxy )
-        {
-            found = true;
-            break;
-        }
-    }
-
-    // release the lock protecting the list of processes
-    remote_queuelock_release( lock_xp );
-
-    // return extended pointer on process descriptor in owner cluster
-    if( found ) return current_xp;
-    else        return XPTR_NULL;
-
-}  // end cluster_get_process_from_pid_in_cxy()
-
-
-//////////////////////////////////////////////////////
-xptr_t cluster_get_owner_process_from_pid( pid_t pid )
-{
-    xptr_t      root_xp;       // xptr on root of list of processes in owner cluster
-    xptr_t      lock_xp;       // xptr on lock protecting this list
-    xptr_t      iter_xp;       // iterator
-    xptr_t      current_xp;    // xptr on current process descriptor
-    process_t * current_ptr;   // local pointer on current process
-    pid_t       current_pid;   // current process identifier
-    bool_t      found;
-
-    cluster_t * cluster = LOCAL_CLUSTER;
-
-    // get owner cluster and lpid
-    cxy_t  owner_cxy = CXY_FROM_PID( pid );
-
-    // get lock & root of list of process in owner cluster
-    root_xp = XPTR( owner_cxy , &cluster->pmgr.local_root );
-    lock_xp = XPTR( owner_cxy , &cluster->pmgr.local_lock );
-
-    // take the lock protecting the list of processes
-    remote_queuelock_acquire( lock_xp );
-
-    // scan list of processes in owner cluster
-    found = false;
-    XLIST_FOREACH( root_xp , iter_xp )
-    {
-        current_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
-        current_ptr = GET_PTR( current_xp );
-        current_pid = hal_remote_l32( XPTR( owner_cxy , &current_ptr->pid ) );
-
-        if( current_pid == pid )
-        {
-            found = true;
-            break;
-        }
-    }
-
-    // release the lock protecting the list of processes
-    remote_queuelock_release( lock_xp );
-
-    // return extended pointer on process descriptor in owner cluster
-    if( found ) return current_xp;
-    else        return XPTR_NULL;
-
-}  // end cluster_get_owner_process_from_pid()
-
 
 //////////////////////////////////////////////////////////
 xptr_t cluster_get_reference_process_from_pid( pid_t pid )
-{
-    xptr_t ref_xp;   // extended pointer on reference process descriptor
+{ 
+    xptr_t xp;   // extended pointer on process descriptor
 
     cluster_t * cluster = LOCAL_CLUSTER;
@@ -429,38 +213,35 @@
     lpid_t lpid      = LPID_FROM_PID( pid );
 
-    // Check valid PID
-    if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER )  return XPTR_NULL;
+    // Check valid PID 
+    if( lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER )
+    {
+        printk("\n[PANIC] in %s : illegal PID\n", __FUNCTION__ );
+        hal_core_sleep();
+    }
 
     if( local_cxy == owner_cxy )   // local cluster is owner cluster
-    {
-        ref_xp = cluster->pmgr.pref_tbl[lpid];
+    { 
+        xp = cluster->pmgr.pref_tbl[lpid];
     }
     else                              // use a remote_lwd to access owner cluster
     {
-        ref_xp = (xptr_t)hal_remote_l64( XPTR( owner_cxy , &cluster->pmgr.pref_tbl[lpid] ) );
-    }
-
-    return ref_xp;
-}
-
-///////////////////////////////////////////////
-error_t cluster_pid_alloc( process_t * process,
-                           pid_t     * pid )
-{
+        xp = (xptr_t)hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.pref_tbl[lpid] ) );
+    }
+
+    return xp;
+}
+
+////////////////////////////////////////////////
+error_t cluster_pid_alloc( xptr_t    process_xp,
+                           pid_t   * pid )
+{
+    error_t     error;
     lpid_t      lpid;
     bool_t      found;
 
-#if DEBUG_CLUSTER_PID_ALLOC
-uint32_t   cycle = (uint32_t)hal_get_cycles();
-thread_t * this  = CURRENT_THREAD;
-if( DEBUG_CLUSTER_PID_ALLOC < cycle )
-printk("\n[%s] thread[%x,%x] enters in cluster %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , local_cxy , cycle );
-#endif
-
     pmgr_t    * pm         = &LOCAL_CLUSTER->pmgr;
 
-    // get the lock protecting pref_tbl
-    queuelock_acquire( &pm->pref_lock );
+    // get the process manager lock
+    spinlock_lock( &pm->pref_lock );
 
     // search an empty slot
@@ -478,5 +259,5 @@
     {
         // register process in pref_tbl[]
-        pm->pref_tbl[lpid] = XPTR( local_cxy , process );
+        pm->pref_tbl[lpid] = process_xp;
         pm->pref_nr++;
 
@@ -484,23 +265,15 @@
         *pid = PID( local_cxy , lpid );
 
-        // release the processs_manager lock
-        queuelock_release( &pm->pref_lock );
-
-        return 0;
+        error = 0;
     }
     else
     {
-        // release the lock
-        queuelock_release( &pm->pref_lock );
-
-        return 0xFFFFFFFF;
-    }
-
-#if DEBUG_CLUSTER_PID_ALLOC
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_PID_ALLOC < cycle )
-printk("\n[%s] thread[%x,%x] exit in cluster %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , local_cxy , cycle );
-#endif
+        error = EAGAIN;
+    }   
+
+    // release the processs_manager lock
+    spinlock_unlock( &pm->pref_lock );
+
+    return error;
 
 } // end cluster_pid_alloc()
@@ -509,28 +282,18 @@
 void cluster_pid_release( pid_t pid )
 {
-
-#if DEBUG_CLUSTER_PID_RELEASE
-uint32_t   cycle = (uint32_t)hal_get_cycles();
-thread_t * this  = CURRENT_THREAD;
-if( DEBUG_CLUSTER_PID_ALLOC < cycle )
-printk("\n[%s] thread[%x,%x] enters in cluster %x / pid %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , local_cxy , pid, cycle );
-#endif
-
     cxy_t  owner_cxy  = CXY_FROM_PID( pid );
     lpid_t lpid       = LPID_FROM_PID( pid );
 
+    // check pid argument
+    if( (lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER) || (owner_cxy != local_cxy) )
+    {
+        printk("\n[PANIC] in %s : illegal PID\n", __FUNCTION__ );
+        hal_core_sleep();
+    }
+
     pmgr_t  * pm = &LOCAL_CLUSTER->pmgr;
 
-    // check lpid 
-    assert( __FUNCTION__, (lpid < CONFIG_MAX_PROCESS_PER_CLUSTER),
-    "illegal LPID = %d" , lpid );
-
-    // check owner cluster
-    assert( __FUNCTION__, (owner_cxy == local_cxy) ,
-    "local_cluster %x !=  owner_cluster %x" , local_cxy , owner_cxy );
-
-    // get the lock protecting pref_tbl
-    queuelock_acquire( &pm->pref_lock );
+    // get the process manager lock
+    spinlock_lock( &pm->pref_lock );
 
     // remove process from pref_tbl[]
@@ -539,12 +302,5 @@
 
     // release the processs_manager lock
-    queuelock_release( &pm->pref_lock );
-
-#if DEBUG_CLUSTER_PID_RELEASE
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_PID_ALLOC < cycle )
-printk("\n[%s] thread[%x,%x] exit in cluster %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , local_cxy , cycle );
-#endif
+    spinlock_unlock( &pm->pref_lock );
 
 } // end cluster_pid_release()
@@ -553,26 +309,19 @@
 process_t * cluster_get_local_process_from_pid( pid_t pid )
 {
-    xptr_t         process_xp;
-    process_t    * process_ptr;
-    xptr_t         root_xp;
-    xptr_t         iter_xp;
-    bool_t         found;
-
-    found   = false;
-    root_xp = XPTR( local_cxy , &LOCAL_CLUSTER->pmgr.local_root );
-
-    XLIST_FOREACH( root_xp , iter_xp )
-    {
-        process_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
-        process_ptr = (process_t *)GET_PTR( process_xp );
-        if( process_ptr->pid == pid )
+    process_t    * ret     = NULL;
+    list_entry_t * root    = &LOCAL_CLUSTER->pmgr.local_root;
+    list_entry_t * iter;
+    process_t    * process;
+    
+    LIST_FOREACH( root , iter )
+    {
+        process = LIST_ELEMENT( iter , process_t , local_list );
+        if( process->pid == pid )
         {
-            found = true;
+            ret = process;
             break;
         }
     }
-
-    if (found ) return process_ptr;
-    else        return NULL;
+    return ret;
 
 }  // end cluster_get_local_process_from_pid()
@@ -583,17 +332,12 @@
     pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
 
-    // get extended pointers on local process list root & lock
-    xptr_t root_xp = XPTR( local_cxy , &pm->local_root );
-    xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock );
-
-    // get lock protecting the local list
-    remote_queuelock_acquire( lock_xp );
-
-    // register process in local list
-    xlist_add_last( root_xp , XPTR( local_cxy , &process->local_list ) );
+    // get lock protecting the process manager local list
+    spinlock_lock( &pm->local_lock );
+
+    list_add_first( &pm->local_root , &process->local_list );
     pm->local_nr++;
 
-    // release lock protecting the local list
-    remote_queuelock_release( lock_xp );
+    // release lock protecting the process manager local list
+    spinlock_unlock( &pm->local_lock );
 }
 
@@ -603,16 +347,12 @@
     pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
 
-    // get extended pointers on local process list lock
-    xptr_t lock_xp = XPTR( local_cxy , &pm->local_lock );
-
-    // get lock protecting the local list
-    remote_queuelock_acquire( lock_xp );
-
-    // remove process from local list
-    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
+    // get lock protecting the process manager local list
+    spinlock_lock( &pm->local_lock );
+
+    list_unlink( &process->local_list );
     pm->local_nr--;
 
-    // release lock protecting the local list
-    remote_queuelock_release( lock_xp );
+    // release lock protecting the process manager local list
+    spinlock_unlock( &pm->local_lock );
 }
 
@@ -621,12 +361,4 @@
 {
     pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
-
-#if DEBUG_CLUSTER_PROCESS_COPIES
-uint32_t   cycle = (uint32_t)hal_get_cycles();
-thread_t * this  = CURRENT_THREAD;
-if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
-printk("\n[%s] thread[%x,%x] enters for process %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
-#endif
 
     // get owner cluster identifier CXY and process LPID
@@ -636,30 +368,21 @@
 
     // get extended pointer on lock protecting copies_list[lpid]
-    xptr_t copies_lock  = XPTR( owner_cxy , &pm->copies_lock[lpid] );
+    xptr_t copies_lock  = hal_remote_lwd( XPTR( owner_cxy , &pm->copies_lock[lpid] ) );
 
     // get extended pointer on the copies_list[lpid] root
-    xptr_t copies_root  = XPTR( owner_cxy , &pm->copies_root[lpid] );
+    xptr_t copies_root  = hal_remote_lwd( XPTR( owner_cxy , &pm->copies_root[lpid] ) );
 
     // get extended pointer on the local copies_list entry
     xptr_t copies_entry = XPTR( local_cxy , &process->copies_list );
 
-    // get lock protecting copies_list[lpid]
-    remote_queuelock_acquire( copies_lock );
-
-    // add copy to copies_list
+    // get lock protecting copies_list[lpid] 
+    remote_spinlock_lock( copies_lock );
+
     xlist_add_first( copies_root , copies_entry );
     hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , 1 );
 
-    // release lock protecting copies_list[lpid]
-    remote_queuelock_release( copies_lock );
-
-#if DEBUG_CLUSTER_PROCESS_COPIES
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
-printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
-#endif
-
-}  // end cluster_process_copies_link()
+    // release lock protecting copies_list[lpid] 
+    remote_spinlock_unlock( copies_lock );
+}
 
 /////////////////////////////////////////////////////////
@@ -667,12 +390,4 @@
 {
     pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
-
-#if DEBUG_CLUSTER_PROCESS_COPIES
-uint32_t   cycle = (uint32_t)hal_get_cycles();
-thread_t * this  = CURRENT_THREAD;
-if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
-printk("\n[%s] thread[%x,%x] enters for process %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
-#endif
 
     // get owner cluster identifier CXY and process LPID
@@ -682,104 +397,214 @@
 
     // get extended pointer on lock protecting copies_list[lpid]
-    xptr_t copies_lock  = XPTR( owner_cxy , &pm->copies_lock[lpid] );
+    xptr_t copies_lock  = hal_remote_lwd( XPTR( owner_cxy , &pm->copies_lock[lpid] ) );
 
     // get extended pointer on the local copies_list entry
     xptr_t copies_entry = XPTR( local_cxy , &process->copies_list );
 
-    // get lock protecting copies_list[lpid]
-    remote_queuelock_acquire( copies_lock );
-
-    // remove copy from copies_list
+    // get lock protecting copies_list[lpid] 
+    remote_spinlock_lock( copies_lock );
+
     xlist_unlink( copies_entry );
     hal_remote_atomic_add( XPTR( owner_cxy , &pm->copies_nr[lpid] ) , -1 );
 
-    // release lock protecting copies_list[lpid]
-    remote_queuelock_release( copies_lock );
-
-#if DEBUG_CLUSTER_PROCESS_COPIES
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_CLUSTER_PROCESS_COPIES < cycle )
-printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
-__FUNCTION__ , this->process->pid , this->trdid , process->pid , cycle );
+    // release lock protecting copies_list[lpid] 
+    remote_spinlock_unlock( copies_lock );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// TODO Il me semble que la seule chose que fait ce kernel thread à chaque réveil
+// est de mettre à jour la DQDT, et de se rendormir... A-t-on besoin d'un thread ? [AG] 
+//////////////////////////////////////////////////////////////////////////////////////////
+
+#if 0
+void * cluster_manager_thread( void * arg )
+{
+	register struct dqdt_cluster_s * root;
+	register struct cluster_s      * root_home;
+
+	register uint32_t                tm_start;
+	register uint32_t                tm_end;
+	register uint32_t                cpu_id;
+	struct cluster_s               * cluster;
+	struct thread_s                * this;
+	struct event_s                   event;
+	struct alarm_info_s              info;
+	register uint32_t                cntr;
+	register bool_t                  isRootMgr;
+	register uint32_t                period;
+
+	cpu_enable_all_irq( NULL );
+
+	cluster   = arg;
+	this      = CURRENT_THREAD;
+	cpu_id    = cpu_get_id();
+	root      = dqdt_root;
+	root_home = dqdt_root->home;
+	isRootMgr = (cluster == root_home) ? true : false;
+	cntr      = 0;
+	period    = (isRootMgr) ? 
+		CONFIG_DQDT_ROOTMGR_PERIOD * MSEC_PER_TICK : 
+		CONFIG_DQDT_MGR_PERIOD * MSEC_PER_TICK;
+
+	event_set_senderId(&event, this);
+	event_set_priority(&event, E_CHR);
+	event_set_handler(&event, &manager_alarm_event_handler);
+  
+	info.event = &event;
+	thread_preempt_disable(CURRENT_THREAD);
+
+    // infinite loop
+	while(1)
+	{
+		tm_start = cpu_time_stamp();
+		dqdt_update();
+		tm_end   = cpu_time_stamp();
+
+		if(isRootMgr)
+		{
+			if((cntr % 10) == 0)
+			{
+				printk(INFO, "INFO: cpu %d, DQDT update ended [ %u - %u ]\n", 
+				       cpu_id, 
+				       tm_end, 
+				       tm_end - tm_start);
+
+				dqdt_print_summary(root);
+			}
+		}
+
+		alarm_wait( &info , period );
+		sched_sleep(this);
+		cntr ++;
+	}
+
+	return NULL;
+} // end cluster_manager_thread()
+
+//////////////////////////////////////////
+EVENT_HANDLER(manager_alarm_event_handler)
+{
+	struct thread_s *manager;
+ 
+	manager = event_get_senderId(event);
+ 
+	thread_preempt_disable(CURRENT_THREAD);
+
+	//printk(INFO, "%s: cpu %d [%u]\n", __FUNCTION__, cpu_get_id(), cpu_time_stamp());
+
+	sched_wakeup(manager);
+  
+	thread_preempt_enable(CURRENT_THREAD);
+
+	return 0;
+}
+
+///////////////////////////////////////////////
+EVENT_HANDLER(cluster_key_create_event_handler)
+{
+	struct cluster_s *cluster;
+	struct thread_s *sender;
+	ckey_t *ckey;
+	uint32_t key;
+
+	sender  = event_get_senderId(event);
+	ckey    = event_get_argument(event);
+	cluster = current_cluster;
+	key     = cluster->next_key;
+
+	while((key < CLUSTER_TOTAL_KEYS_NR) && (cluster->keys_tbl[key] != NULL))
+		key ++;
+
+	if(key < CLUSTER_TOTAL_KEYS_NR)
+	{
+		ckey->val = key;
+		cluster->keys_tbl[key] = (void *) 0x1; // Reserved 
+		cluster->next_key = key;
+		event_set_error(event, 0);
+	}
+	else
+		event_set_error(event, ENOSPC);
+
+	sched_wakeup(sender);
+	return 0;
+}
+
+///////////////////////////////////////////////
+EVENT_HANDLER(cluster_key_delete_event_handler)
+{
+	struct cluster_s *cluster;
+	struct thread_s *sender;
+	ckey_t *ckey;
+	uint32_t key;
+
+	sender  = event_get_senderId(event);
+	ckey    = event_get_argument(event);
+	cluster = current_cluster;
+	key     = ckey->val;
+
+	if(key < cluster->next_key)
+		cluster->next_key = key;
+
+	cluster->keys_tbl[key] = NULL;
+	event_set_error(event, 0);
+
+	sched_wakeup(sender);
+	return 0;
+}
+
+#define _CKEY_CREATE  0x0
+#define _CKEY_DELETE  0x1
+
+error_t cluster_do_key_op(ckey_t *key, uint32_t op)
+{
+	struct event_s event;
+	struct thread_s *this;
+	struct cluster_s *cluster;
+	struct cpu_s *cpu;
+
+	this = CURRENT_THREAD;
+
+	event_set_priority(&event, E_FUNC);
+	event_set_senderId(&event, this);
+	event_set_argument(&event, key);
+
+	if(op == _CKEY_CREATE)
+		event_set_handler(&event, cluster_key_create_event_handler);
+	else
+		event_set_handler(&event, cluster_key_delete_event_handler);
+
+	cluster = current_cluster;
+	cpu     = cluster->bscluster->bscpu;
+	event_send(&event, &cpu->re_listner);
+
+	sched_sleep(this);
+
+	return event_get_error(&event);
+}
+
+error_t cluster_key_create(ckey_t *key)
+{
+	return cluster_do_key_op(key, _CKEY_CREATE);
+}
+
+error_t cluster_key_delete(ckey_t *key)
+{
+	return cluster_do_key_op(key, _CKEY_DELETE);
+}
+
+void* cluster_getspecific(ckey_t *key)
+{
+	struct cluster_s *cluster;
+
+	cluster = current_cluster;
+	return cluster->keys_tbl[key->val];
+}
+
+void  cluster_setspecific(ckey_t *key, void *val)
+{
+	struct cluster_s *cluster;
+
+	cluster = current_cluster;
+	cluster->keys_tbl[key->val] = val;
+}
 #endif
-
-}  // end cluster_process_copies_unlink()
-
-////////////////////////////////////////////
-void cluster_processes_display( cxy_t   cxy,
-                                bool_t  owned )
-{
-    xptr_t        root_xp;
-    xptr_t        lock_xp;
-    xptr_t        iter_xp;
-    xptr_t        process_xp;
-    process_t   * process_ptr;
-    cxy_t         process_cxy;
-    pid_t         pid;
-    cxy_t         txt0_cxy;
-    chdev_t     * txt0_ptr;
-    xptr_t        txt0_xp;
-    xptr_t        txt0_lock_xp;
-    uint32_t      pref_nr;       // number of owned processes in cluster cxy
-
-assert( __FUNCTION__, (cluster_is_active( cxy ) ), "illegal cluster index" );
-
-    // get extended pointer on root and lock for local process list in cluster
-    root_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_root );
-    lock_xp = XPTR( cxy , &LOCAL_CLUSTER->pmgr.local_lock );
-
-    // get number of owned processes in cluster cxy
-    pref_nr = hal_remote_l32( XPTR( cxy , &LOCAL_CLUSTER->pmgr.pref_nr ) );
-
-    // display nothing if no user process in cluster cxy
-    if( (owned != false) && (pref_nr < 2) ) return;
-    
-    // get pointers on TXT0 chdev
-    txt0_xp  = chdev_dir.txt_tx[0];
-    txt0_cxy = GET_CXY( txt0_xp );
-    txt0_ptr = GET_PTR( txt0_xp );
-
-    // get extended pointer on TXT0 lock
-    txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
-
-    // get lock on local process list 
-    remote_queuelock_acquire( lock_xp );
-
-    // get TXT0 lock
-    remote_busylock_acquire( txt0_lock_xp );
-     
-    nolock_printk("\n***** processes in cluster %x / cycle %d\n",
-    cxy , (uint32_t)hal_get_cycles() );
-
-    // loop on all processes in cluster cxy 
-    XLIST_FOREACH( root_xp , iter_xp )
-    {
-        process_xp  = XLIST_ELEMENT( iter_xp , process_t , local_list );
-        process_ptr = GET_PTR( process_xp );
-        process_cxy = GET_CXY( process_xp );
-
-        // get process PID
-        pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) );
-
-        if( owned )  // display only user & owned processes 
-        {
-            if( (CXY_FROM_PID( pid ) == cxy) && (LPID_FROM_PID( pid ) != 0) )
-            {
-                process_display( process_xp );
-            }
-        }
-        else         // display all local processes
-        {
-            process_display( process_xp );
-        }
-    }
-
-    // release TXT0 lock 
-    remote_busylock_release( txt0_lock_xp );
-
-    // release lock on local process list
-    remote_queuelock_release( lock_xp );
-
-}  // end cluster_processes_display() 
-
-
