Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 561)
+++ trunk/kernel/mm/vmm.c	(revision 567)
@@ -31,5 +31,6 @@
 #include <printk.h>
 #include <memcpy.h>
-#include <rwlock.h>
+#include <remote_rwlock.h>
+#include <remote_queuelock.h>
 #include <list.h>
 #include <xlist.h>
@@ -51,6 +52,5 @@
 //////////////////////////////////////////////////////////////////////////////////
 
-extern  process_t  process_zero;   // defined in cluster.c file
-
+extern  process_t  process_zero;      // allocated in cluster.c 
 
 ///////////////////////////////////////
@@ -65,8 +65,9 @@
 
 #if DEBUG_VMM_INIT
+thread_t * this = CURRENT_THREAD;
 uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_INIT )
-printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n", 
-__FUNCTION__ , CURRENT_THREAD , process->pid , cycle );
+printk("\n[DBG] %s : thread %x in process %x enter for process %x / cycle %d\n", 
+__FUNCTION__ , this->trdid, this->process->pid, process->pid , cycle );
 #endif
 
@@ -77,15 +78,15 @@
     vmm->vsegs_nr = 0;
 	xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) );
-	remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ) );
-
-    assert( ((CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) 
-            <= CONFIG_VMM_ELF_BASE) , "UTILS zone too small\n" );
-
-    assert( (CONFIG_THREAD_MAX_PER_CLUSTER <= 32) ,
-            "no more than 32 threads per cluster for a single process\n");
-
-    assert( ((CONFIG_VMM_STACK_SIZE * CONFIG_THREAD_MAX_PER_CLUSTER) <=
-             (CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE)) ,
-             "STACK zone too small\n");
+	remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ),LOCK_VMM_VSL );
+
+assert( ((CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) 
+<= CONFIG_VMM_ELF_BASE) , "UTILS zone too small\n" );
+
+assert( (CONFIG_THREADS_MAX_PER_CLUSTER <= 32) ,
+"no more than 32 threads per cluster for a single process\n");
+
+assert( ((CONFIG_VMM_STACK_SIZE * CONFIG_THREADS_MAX_PER_CLUSTER) <=
+(CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE)) ,
+"STACK zone too small\n");
 
     // register kentry vseg in VSL
@@ -171,5 +172,5 @@
     vmm->stack_mgr.bitmap   = 0;
     vmm->stack_mgr.vpn_base = CONFIG_VMM_STACK_BASE;
-    spinlock_init( &vmm->stack_mgr.lock );
+    busylock_init( &vmm->stack_mgr.lock , LOCK_VMM_STACK );
 
     // initialize MMAP allocator
@@ -177,5 +178,5 @@
     vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_HEAP_BASE;
     vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_HEAP_BASE;
-    spinlock_init( &vmm->mmap_mgr.lock );
+    busylock_init( &vmm->mmap_mgr.lock , LOCK_VMM_MMAP );
 
     uint32_t i;
@@ -190,6 +191,6 @@
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_INIT )
-printk("\n[DBG] %s : thread %x exit for process %x / entry_point = %x / cycle %d\n", 
-__FUNCTION__ , CURRENT_THREAD , process->pid , process->vmm.entry_point , cycle );
+printk("\n[DBG] %s : thread %x in process %x exit / process %x / entry_point = %x / cycle %d\n", 
+__FUNCTION__, this->trdid, this->process->pid, process->pid , process->vmm.entry_point , cycle );
 #endif
 
@@ -209,5 +210,5 @@
 
     // get lock protecting the vseg list
-    remote_rwlock_rd_lock( XPTR( local_cxy , &vmm->vsegs_lock ) );
+    remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) );
 
     // scan the list of vsegs
@@ -243,7 +244,48 @@
 
     // release the lock
-    remote_rwlock_rd_unlock( XPTR( local_cxy , &vmm->vsegs_lock ) );
+    remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) );
 
 }  // vmm_display()
+
+///////////////////////////////////
+void vmm_vseg_attach( vmm_t  * vmm,
+                      vseg_t * vseg )
+{
+    // build extended pointer on rwlock protecting VSL
+    xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
+
+    // get rwlock in write mode
+    remote_rwlock_wr_acquire( lock_xp );
+
+    // update vseg descriptor
+    vseg->vmm = vmm;
+
+    // add vseg in vmm list
+    xlist_add_last( XPTR( local_cxy , &vmm->vsegs_root ),
+                    XPTR( local_cxy , &vseg->xlist ) );
+
+    // release rwlock in write mode
+    remote_rwlock_wr_release( lock_xp );
+}
+
+///////////////////////////////////
+void vmm_vseg_detach( vmm_t  * vmm,
+                      vseg_t * vseg )
+{
+    // build extended pointer on rwlock protecting VSL
+    xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
+
+    // get rwlock in write mode
+    remote_rwlock_wr_acquire( lock_xp );
+
+    // update vseg descriptor
+    vseg->vmm = NULL;
+
+    // remove vseg from vmm list
+    xlist_unlink( XPTR( local_cxy , &vseg->xlist ) );
+
+    // release rwlock in write mode
+    remote_rwlock_wr_release( lock_xp );
+}
 
 /////////////////////i//////////////////////////
@@ -274,7 +316,7 @@
 #endif
 
-    // check cluster is reference
-    assert( (GET_CXY( process->ref_xp ) == local_cxy) ,
-    "not called in reference cluster\n");
+// check cluster is reference
+assert( (GET_CXY( process->ref_xp ) == local_cxy) ,
+"not called in reference cluster\n");
 
     // get extended pointer on root of process copies xlist in owner cluster
@@ -346,7 +388,7 @@
 #endif
 
-    // check cluster is reference
-    assert( (GET_CXY( process->ref_xp ) == local_cxy) ,
-    "local cluster is not process reference cluster\n");
+// check cluster is reference
+assert( (GET_CXY( process->ref_xp ) == local_cxy) ,
+"local cluster is not process reference cluster\n");
 
     // get pointer on reference VMM
@@ -387,6 +429,6 @@
             vseg     = GET_PTR( vseg_xp );
 
-            assert( (GET_CXY( vseg_xp ) == local_cxy) ,
-            "all vsegs in reference VSL must be local\n" );
+assert( (GET_CXY( vseg_xp ) == local_cxy) ,
+"all vsegs in reference VSL must be local\n" );
 
             // get vseg type, base and size
@@ -444,8 +486,12 @@
                             lock_xp  = XPTR( page_cxy , &page_ptr->lock );
 
+                            // take lock protecting "forks" counter
+                            remote_busylock_acquire( lock_xp );
+
                             // increment "forks"
-                            remote_spinlock_lock( lock_xp );
                             hal_remote_atomic_add( forks_xp , 1 );
-                            remote_spinlock_unlock( lock_xp );
+
+                            // release lock protecting "forks" counter
+                            remote_busylock_release( lock_xp );
                         }
                     }   // end loop on vpn
@@ -511,5 +557,5 @@
 
     // initialize the lock protecting the child VSL
-    remote_rwlock_init( XPTR( local_cxy , &child_vmm->vsegs_lock ) );
+    remote_rwlock_init( XPTR( local_cxy , &child_vmm->vsegs_lock ), LOCK_VMM_STACK );
 
     // initialize the child VSL as empty
@@ -529,6 +575,6 @@
     parent_root_xp = XPTR( parent_cxy , &parent_vmm->vsegs_root );
 
-    // take the lock protecting the parent VSL
-    remote_rwlock_rd_lock( parent_lock_xp );
+    // take the lock protecting the parent VSL in read mode
+    remote_rwlock_rd_acquire( parent_lock_xp );
 
     // loop on parent VSL xlist
@@ -540,5 +586,5 @@
 
         // get vseg type
-        type = hal_remote_lw( XPTR( parent_cxy , &parent_vseg->type ) );
+        type = hal_remote_l32( XPTR( parent_cxy , &parent_vseg->type ) );
         
 #if DEBUG_VMM_FORK_COPY
@@ -547,5 +593,5 @@
 printk("\n[DBG] %s : thread %x found parent vseg %s / vpn_base = %x / cycle %d\n",
 __FUNCTION__ , CURRENT_THREAD, vseg_type_str(type),
-hal_remote_lw( XPTR( parent_cxy , &parent_vseg->vpn_base ) ) , cycle );
+hal_remote_l32( XPTR( parent_cxy , &parent_vseg->vpn_base ) ) , cycle );
 #endif
 
@@ -566,5 +612,5 @@
 
             // register child vseg in child VSL
-            vseg_attach( child_vmm , child_vseg );
+            vmm_vseg_attach( child_vmm , child_vseg );
 
 #if DEBUG_VMM_FORK_COPY
@@ -573,5 +619,5 @@
 printk("\n[DBG] %s : thread %x copied vseg %s / vpn_base = %x to child VSL / cycle %d\n",
 __FUNCTION__ , CURRENT_THREAD , vseg_type_str(type),
-hal_remote_lw( XPTR( parent_cxy , &parent_vseg->vpn_base ) ) , cycle );
+hal_remote_l32( XPTR( parent_cxy , &parent_vseg->vpn_base ) ) , cycle );
 #endif
 
@@ -613,8 +659,12 @@
                         lock_xp  = XPTR( page_cxy , &page_ptr->lock );
 
+                        // get lock protecting "forks" counter
+                        remote_busylock_acquire( lock_xp );
+
                         // increment "forks"
-                        remote_spinlock_lock( lock_xp );
                         hal_remote_atomic_add( forks_xp , 1 );
-                        remote_spinlock_unlock( lock_xp );
+
+                        // release lock protecting "forks" counter
+                        remote_busylock_release( lock_xp );
 
 #if DEBUG_VMM_FORK_COPY
@@ -630,6 +680,6 @@
     }   // end loop on vsegs
 
-    // release the parent vsegs lock
-    remote_rwlock_rd_unlock( parent_lock_xp );
+    // release the parent VSL lock in read mode
+    remote_rwlock_rd_release( parent_lock_xp );
 
     // initialize child GPT (architecture specic)
@@ -703,8 +753,4 @@
     // get extended pointer on VSL root and VSL lock
     xptr_t   root_xp = XPTR( local_cxy , &vmm->vsegs_root );
-	xptr_t   lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
-
-    // get lock protecting vseg list
-	remote_rwlock_wr_lock( lock_xp );
 
     // remove all user vsegs registered in VSL
@@ -712,5 +758,5 @@
 	{
         // get pointer on first vseg in VSL
-		vseg_xp = XLIST_FIRST_ELEMENT( root_xp , vseg_t , xlist );
+		vseg_xp = XLIST_FIRST( root_xp , vseg_t , xlist );
         vseg    = GET_PTR( vseg_xp );
 
@@ -719,5 +765,5 @@
 
         // remove vseg from VSL
-		vseg_detach( vseg );
+		vmm_vseg_detach( vmm , vseg );
 
         // release memory allocated to vseg descriptor
@@ -732,7 +778,4 @@
 	}
 
-    // release lock protecting VSL
-	remote_rwlock_wr_unlock( lock_xp );
-
     // remove all vsegs from zombi_lists in MMAP allocator
     uint32_t i;
@@ -748,5 +791,5 @@
 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size );
 #endif
-		    vseg_detach( vseg );
+		    vmm_vseg_detach( vmm , vseg );
             vseg_free( vseg );
 
@@ -812,5 +855,5 @@
 
     // get lock on stack allocator
-    spinlock_lock( &mgr->lock );
+    busylock_acquire( &mgr->lock );
 
     // get first free slot index in bitmap
@@ -818,6 +861,6 @@
     if( (index < 0) || (index > 31) )
     {
-        spinlock_unlock( &mgr->lock );
-        return ENOMEM;
+        busylock_release( &mgr->lock );
+        return 0xFFFFFFFF;
     }
 
@@ -826,5 +869,5 @@
 
     // release lock on stack allocator
-    spinlock_unlock( &mgr->lock );
+    busylock_release( &mgr->lock );
 
     // returns vpn_base, vpn_size (one page non allocated)
@@ -864,5 +907,5 @@
 
     // get lock on mmap allocator
-    spinlock_lock( &mgr->lock );
+    busylock_acquire( &mgr->lock );
 
     // get vseg from zombi_list or from mmap zone
@@ -892,5 +935,5 @@
 
     // release lock on mmap allocator
-    spinlock_unlock( &mgr->lock );
+    busylock_release( &mgr->lock );
 
     // returns vpn_base, vpn_size
@@ -1002,8 +1045,5 @@
 
     // attach vseg to VSL
-    xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
-	remote_rwlock_wr_lock( lock_xp );
-	vseg_attach( vmm , vseg );
-	remote_rwlock_wr_unlock( lock_xp );
+	vmm_vseg_attach( vmm , vseg );
 
 #if DEBUG_VMM_CREATE_VSEG
@@ -1027,8 +1067,5 @@
 
     // detach vseg from VSL
-    xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
-	remote_rwlock_wr_lock( lock_xp );
-	vseg_detach( vseg );
-	remote_rwlock_wr_unlock( lock_xp );
+	vmm_vseg_detach( vmm , vseg );
 
     // release the stack slot to VMM stack allocator if STACK type
@@ -1042,7 +1079,7 @@
 
         // update stacks_bitmap
-        spinlock_lock( &mgr->lock );
+        busylock_acquire( &mgr->lock );
         bitmap_clear( &mgr->bitmap , index );
-        spinlock_unlock( &mgr->lock );
+        busylock_release( &mgr->lock );
     }
 
@@ -1057,7 +1094,7 @@
 
         // update zombi_list
-        spinlock_lock( &mgr->lock );
+        busylock_acquire( &mgr->lock );
         list_add_first( &mgr->zombi_list[index] , &vseg->zlist );
-        spinlock_unlock( &mgr->lock );
+        busylock_release( &mgr->lock );
     }
 
@@ -1112,7 +1149,7 @@
 #endif
 
-            // check small page
-            assert( (attr & GPT_SMALL) ,
-            "an user vseg must use small pages" );
+// check small page
+assert( (attr & GPT_SMALL) ,
+"an user vseg must use small pages" );
 
             // unmap GPT entry in all GPT copies
@@ -1121,5 +1158,5 @@
             // handle pending forks counter if
             // 1) not identity mapped
-            // 2) running in reference cluster
+            // 2) reference cluster
             if( ((vseg->flags & VSEG_IDENT)  == 0) &&
                 (GET_CXY( process->ref_xp ) == local_cxy) )
@@ -1134,9 +1171,6 @@
                 lock_xp  = XPTR( page_cxy , &page_ptr->lock );
 
-                // get lock protecting page descriptor
-                remote_spinlock_lock( lock_xp );
-
                 // get pending forks counter
-                forks = hal_remote_lw( forks_xp );
+                forks = hal_remote_l32( forks_xp );
                 
                 if( forks )  // decrement pending forks counter
@@ -1157,7 +1191,4 @@
                     }
                 }
-
-                // release lock protecting page descriptor
-                remote_spinlock_unlock( lock_xp );
             }
         }
@@ -1194,5 +1225,5 @@
 
     // get lock protecting the VSL
-    remote_rwlock_rd_lock( lock_xp );
+    remote_rwlock_rd_acquire( lock_xp );
 
     // scan the list of vsegs in VSL
@@ -1204,5 +1235,5 @@
         {
             // return success
-            remote_rwlock_rd_unlock( lock_xp );
+            remote_rwlock_rd_release( lock_xp );
             return vseg;
         }
@@ -1210,5 +1241,5 @@
 
     // return failure
-    remote_rwlock_rd_unlock( lock_xp );
+    remote_rwlock_rd_release( lock_xp );
     return NULL;
 
@@ -1240,5 +1271,5 @@
 
     // get lock protecting VSL
-	remote_rwlock_wr_lock( lock_xp );
+	remote_rwlock_wr_acquire( lock_xp );
 
 	if( (vseg->min > addr_min) || (vseg->max < addr_max) )   // region not included in vseg
@@ -1301,5 +1332,5 @@
 
     // release VMM lock
-	remote_rwlock_wr_unlock( lock_xp );
+	remote_rwlock_wr_release( lock_xp );
 
 	return error;
@@ -1348,5 +1379,5 @@
 
         // register local vseg in local VMM
-        vseg_attach( &process->vmm , vseg );
+        vmm_vseg_attach( &process->vmm , vseg );
     }   
     
@@ -1381,5 +1412,6 @@
     uint32_t     flags = vseg->flags;
 
-    assert( ( type != VSEG_TYPE_FILE ) , "illegal vseg type\n" );
+// check vseg type
+assert( ( type != VSEG_TYPE_FILE ) , "illegal vseg type\n" );
 
     if( flags & VSEG_DISTRIB )    // distributed => cxy depends on vpn LSB
@@ -1400,4 +1432,7 @@
         }
         page_cxy = ( x << y_width ) + y;
+
+//      if ( LOCAL_CLUSTER->valid[x][y] == false ) page_cxy = cluster_random_select();
+
     }
     else                          // other cases => cxy specified in vseg
@@ -1457,6 +1492,6 @@
         xptr_t mapper_xp = vseg->mapper_xp;
 
-        assert( (mapper_xp != XPTR_NULL),
-        "mapper not defined for a FILE vseg\n" );
+assert( (mapper_xp != XPTR_NULL),
+"mapper not defined for a FILE vseg\n" );
         
         // get mapper cluster and local pointer
@@ -1495,6 +1530,6 @@
             xptr_t     mapper_xp = vseg->mapper_xp;
 
-            assert( (mapper_xp != XPTR_NULL),
-            "mapper not defined for a CODE or DATA vseg\n" );
+assert( (mapper_xp != XPTR_NULL),
+"mapper not defined for a CODE or DATA vseg\n" );
         
             // get mapper cluster and local pointer
@@ -1513,6 +1548,4 @@
 __FUNCTION__, this, vpn, elf_offset );
 #endif
-
-
             // compute extended pointer on page base 
             xptr_t base_xp  = ppm_page2base( page_xp );
@@ -1529,6 +1562,4 @@
 __FUNCTION__, this, vpn );
 #endif
-
-
                 if( GET_CXY( page_xp ) == local_cxy )
                 {
@@ -1646,7 +1677,7 @@
     error_t    error;
 
-    thread_t * this  = CURRENT_THREAD;
 
 #if DEBUG_VMM_GET_PTE
+thread_t * this  = CURRENT_THREAD;
 uint32_t   cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_GET_PTE < cycle )
@@ -1663,6 +1694,6 @@
                            &vseg );
 
-    // vseg has been checked by the vmm_handle_page_fault() function
-    assert( (vseg != NULL) , "vseg undefined / vpn %x\n");
+// vseg has been checked by the vmm_handle_page_fault() function
+assert( (vseg != NULL) , "vseg undefined / vpn %x\n");
 
     if( cow )  //////////////// copy_on_write request //////////////////////
@@ -1675,6 +1706,6 @@
         hal_gpt_get_pte( &vmm->gpt , vpn , &old_attr , &old_ppn );
 
-        assert( (old_attr & GPT_MAPPED),
-          "PTE unmapped for a COW exception / vpn %x\n" );
+assert( (old_attr & GPT_MAPPED),
+"PTE unmapped for a COW exception / vpn %x\n" );
 
 #if( DEBUG_VMM_GET_PTE & 1 )
@@ -1693,9 +1724,9 @@
         xptr_t lock_xp  = XPTR( page_cxy , &page_ptr->lock );
 
-        // take lock protecting page descriptor
-        remote_spinlock_lock( lock_xp );
+        // take lock protecting "forks" counter
+        remote_busylock_acquire( lock_xp );
 
         // get number of pending forks in page descriptor
-        uint32_t forks = hal_remote_lw( forks_xp );
+        uint32_t forks = hal_remote_l32( forks_xp );
 
         if( forks )        // pending fork => allocate a new page, copy old to new
@@ -1728,6 +1759,6 @@
         }
 
-        // release lock protecting page descriptor
-        remote_spinlock_unlock( lock_xp );
+        // release lock protecting "forks" counter
+        remote_busylock_release( lock_xp );
 
         // build new_attr : reset COW and set WRITABLE,
@@ -1840,7 +1871,7 @@
     type = vseg->type;
 
-    // get reference process cluster and local pointer
+    // get relevant process cluster and local pointer
     // for private vsegs (CODE and DATA type), 
-    // the reference is the local process descriptor.
+    // the relevant process descriptor is local.
     if( (type == VSEG_TYPE_STACK) || (type == VSEG_TYPE_CODE) )
     {
