Index: /soft/giet_vm/giet_common/io.h
===================================================================
--- /soft/giet_vm/giet_common/io.h	(revision 494)
+++ /soft/giet_vm/giet_common/io.h	(revision 495)
@@ -6,4 +6,6 @@
 ///////////////////////////////////////////////////////////////////////////////////
 // Utility functions to write or read memory mapped hardware registers
+// The main service provided by those functions is to force an actual
+// read (volatile attribute) or write (sync operation) to memory.
 ///////////////////////////////////////////////////////////////////////////////////
 
Index: /soft/giet_vm/giet_common/kernel_barriers.c
===================================================================
--- /soft/giet_vm/giet_common/kernel_barriers.c	(revision 495)
+++ /soft/giet_vm/giet_common/kernel_barriers.c	(revision 495)
@@ -0,0 +1,381 @@
+//////////////////////////////////////////////////////////////////////////////
+// File     : kernel_barriers.c
+// Date     : 19/01/2015
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+//////////////////////////////////////////////////////////////////////////////
+
+#include "kernel_barriers.h"
+#include "giet_config.h"
+#include "hard_config.h"
+#include "utils.h"
+#include "tty0.h"
+#include "kernel_malloc.h"
+#include "io.h"
+
+///////////////////////////////////////////////////////////////////////////////
+//      Simple barrier access functions
+///////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////
+void _simple_barrier_init( simple_barrier_t*  barrier,
+                           unsigned int       ntasks )
+{
+
+#if GIET_DEBUG_SIMPLE_BARRIER
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+_printf("[DEBUG SIMPLE_BARRIER] proc[%d,%d,%d] enters _simple_barrier_init()"
+               " / vaddr = %x / ntasks = %d\n",
+               px, py, pl, (unsigned int)barrier , ntasks );
+#endif
+
+    barrier->ntasks = ntasks;
+    barrier->count  = ntasks;
+    barrier->sense  = 0;
+
+    asm volatile ("sync" ::: "memory");
+
+}  // end simple_barrier_init()
+
+//////////////////////////////////////////////////////
+void _simple_barrier_wait( simple_barrier_t*  barrier )
+{
+
+#if GIET_DEBUG_SIMPLE_BARRIER
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+_printf("[DEBUG SIMPLE_BARRIER] proc[%d,%d,%d] enters _simple_barrier_wait()"
+               " / vaddr = %x / ntasks = %d / count = %d / sense = %d\n",
+               px, py, pl , (unsigned int)barrier , barrier->ntasks ,
+               barrier->count , barrier->sense );
+#endif
+
+    // compute expected sense value 
+    unsigned int expected;
+    if ( barrier->sense == 0 ) expected = 1;
+    else                       expected = 0;
+
+    // decrement local "count"
+    unsigned int count = _atomic_increment( &barrier->count, -1 );
+
+    // the last task re-initializes count and toggle sense,
+    // waking up all other waiting tasks
+    if (count == 1)   // last task
+    {
+        barrier->count = barrier->ntasks;
+        barrier->sense = expected;
+    }
+    else              // other tasks poll the sense flag
+    {
+        while ( ioread32( &barrier->sense ) != expected ) asm volatile ("nop");
+    }
+
+    asm volatile ("sync" ::: "memory");
+
+#if GIET_DEBUG_SIMPLE_BARRIER
+_printf("[DEBUG SIMPLE_BARRIER] proc[%d,%d,%d] exit simple barrier_wait()\n",
+               px, py, pl );
+#endif
+
+} // end _simple_barrier_wait()
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//      SQT barrier access functions
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+// This recursive function is called by the _sqt_barrier_init() function
+// to initializes the SQT nodes (mainly the parent and child pointers).
+// It traverses the SQT from top to bottom.
+// The SQT can be uncomplete (when xmax or ymax are not power of 2),
+// and the recursion stops when the (x,y) coordinates exceed the footprint.
+////////////////////////////////////////////////////////////////////////////////
+static 
+void _sqt_barrier_build( sqt_barrier_t*      barrier,   // barrier pointer
+                         unsigned int        x,         // node x coordinate
+                         unsigned int        y,         // node y coordinate
+                         unsigned int        level,     // node level
+                         sqt_barrier_node_t* parent,    // parent node
+                         unsigned int        xmax,     // SQT X size
+                         unsigned int        ymax )   // SQT Y size
+{
+
+#if GIET_DEBUG_SQT_BARRIER
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+#endif
+
+    // get target node pointer
+    sqt_barrier_node_t* node = barrier->node[x][y][level];
+    
+    if (level == 0 )        // terminal case
+    {
+        // initializes target node
+        node->arity    = NB_PROCS_MAX;   
+        node->count    = NB_PROCS_MAX;
+        node->sense    = 0;
+        node->level    = 0;
+        node->parent   = parent;
+        node->child[0] = NULL;
+        node->child[1] = NULL;
+        node->child[2] = NULL;
+        node->child[3] = NULL;
+
+#if GIET_DEBUG_SQT_BARRIER
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] initialises SQT node[%d,%d,%d] :\n"
+      " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
+      px , py , pl , x , y , level , 
+      (unsigned int)node->parent , 
+      (unsigned int)node->child[0] , 
+      (unsigned int)node->child[1] , 
+      (unsigned int)node->child[2] , 
+      (unsigned int)node->child[3] );
+#endif
+
+    }
+    else                  // non terminal case
+    {
+        unsigned int cx[4];      // x coordinate for children
+        unsigned int cy[4];      // y coordinate for children
+        unsigned int arity = 0;  // number of children
+        unsigned int i;          // child index
+
+        // the child0 coordinates are equal to the parent coordinates
+        // other child coordinates are incremented depending on the level value
+        cx[0] = x;
+        cy[0] = y;
+
+        cx[1] = x + (1 << (level-1));
+        cy[1] = y;
+
+        cx[2] = x;
+        cy[2] = y + (1 << (level-1));
+
+        cx[3] = x + (1 << (level-1));
+        cy[3] = y + (1 << (level-1));
+
+        // initializes target node
+        for ( i = 0 ; i < 4 ; i++ )
+        {
+            if ( (cx[i] < xmax) && (cy[i] < ymax) ) 
+            {
+                node->child[i] = barrier->node[cx[i]][cy[i]][level-1];
+                arity++;
+            }
+            else  node->child[i] = NULL;
+        }
+        node->arity    = arity;  
+        node->count    = arity;
+        node->sense    = 0;
+        node->level    = level;
+        node->parent   = parent;
+
+#if GIET_DEBUG_SQT_BARRIER
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n"
+      " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
+      px , py , pl , x , y , level , 
+      (unsigned int)node->parent ,
+      (unsigned int)node->child[0] , 
+      (unsigned int)node->child[1] , 
+      (unsigned int)node->child[2] , 
+      (unsigned int)node->child[3] );
+#endif
+
+        // recursive calls for children nodes
+        for ( i = 0 ; i < 4 ; i++ )
+        {
+            if ( (cx[i] < xmax) && (cy[i] < ymax) ) 
+                _sqt_barrier_build( barrier, 
+                                    cx[i], 
+                                    cy[i], 
+                                    level-1, 
+                                    node, 
+                                    xmax, 
+                                    ymax );
+        }
+    }
+}  // end _sqt_barrier_build()
+
+///////////////////////////////////////////////////////////////////////////////
+// This external function initialises the distributed SQT barrier.
+// It allocates memory for the distributed SQT nodes in clusters,
+// and initializes the SQT nodes pointers array (stored in cluster[0][0].
+// The SQT can be "uncomplete" as SQT barrier nodes are only build in clusters
+// containing processors, and contained in the mesh (X_SIZE/Y_SIZE). 
+// The actual number of SQT barriers nodes in a cluster[x][y] depends on (x,y): 
+// At least 1 node / at most 5 nodes per cluster:
+// - barrier arbitrating between all processors of   1 cluster  has level 0,
+// - barrier arbitrating between all processors of   4 clusters has level 1,
+// - barrier arbitrating between all processors of  16 clusters has level 2,
+// - barrier arbitrating between all processors of  64 clusters has level 3,
+// - barrier arbitrating between all processors of 256 clusters has level 4,
+///////////////////////////////////////////////////////////////////////////////
+void _sqt_barrier_init( sqt_barrier_t*  barrier )
+{
+    unsigned int levels;
+    unsigned int xmax;
+    unsigned int ymax;
+
+    // compute the smallest covering SQT
+    _get_sqt_footprint( &xmax, &ymax, &levels );
+
+#if GIET_DEBUG_SQT_BARRIER
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] initialises SQT barrier %x : \n"
+               " xmax = %d / ymax = %d / levels = %d\n",
+               px , py , pl , (unsigned int)barrier , 
+               xmax , ymax , levels );
+#endif
+
+    unsigned int x;              // x coordinate for one SQT node
+    unsigned int y;              // y coordinate for one SQT node
+    unsigned int l;              // level for one SQT node
+
+    for ( x = 0 ; x < xmax ; x++ )
+    {
+        for ( y = 0 ; y < ymax ; y++ )
+        {
+            for ( l = 0 ; l < levels ; l++ )            
+            {
+                
+                if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) ||
+                     ( (l == 1) && ((x&0x01) == 0) && ((y&0x01) == 0) ) ||
+                     ( (l == 2) && ((x&0x03) == 0) && ((y&0x03) == 0) ) ||
+                     ( (l == 3) && ((x&0x07) == 0) && ((y&0x07) == 0) ) ||
+                     ( (l == 4) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) )
+                 {
+                     barrier->node[x][y][l] = 
+                     (sqt_barrier_node_t*)_remote_malloc( sizeof(sqt_barrier_node_t),
+                                                          x, y );
+
+#if GIET_DEBUG_SQT_BARRIER
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] allocates SQT node[%d,%d,%d]"
+               " : vaddr = %x\n",
+               px , py , pl , x , y , l , (unsigned int)barrier->node[x][y][l] );
+#endif
+                 }
+            }
+        }
+    }
+            
+    // recursively initialize SQT nodes from root to bottom
+    _sqt_barrier_build( barrier,       // pointer on the SQT barrier descriptor
+                        0,             // cluster X coordinate
+                        0,             // cluster Y coordinate
+                        levels-1,      // level in SQT
+                        NULL,          // pointer on the parent node
+                        xmax,          // SQT footprint X size
+                        ymax );        // SQT footprint Y size
+
+    asm volatile ("sync" ::: "memory");
+
+} // end _sqt_barrier_init()
+
+///////////////////////////////////////////////////////////////////////////////
+// This recursive function is called by the _sqt_barrier_wait().
+// It decrements the distributed count variables, 
+// traversing the SQT from bottom to root.
+// The last arrived task reset the local node before returning.
+///////////////////////////////////////////////////////////////////////////////
+static 
+void _sqt_barrier_decrement( sqt_barrier_node_t* node )
+{
+
+#if GIET_DEBUG_SQT_BARRIER
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] decrement SQT barrier node %x :\n"
+        " level = %d / arity = %d / sense = %d / count = %d\n",
+        px , py , pl , (unsigned int)node , 
+        node->level , node->arity , node->sense , node->count );
+#endif
+
+    // compute expected sense value
+    unsigned int expected;
+    if ( node->sense == 0 ) expected = 1;
+    else                    expected = 0;
+
+    // decrement local "count"
+    unsigned int count = _atomic_increment( &node->count, -1 );
+
+    if ( count == 1 )    // last task
+    {
+        // decrement the parent node if the current node is not the root
+        if ( node->parent != NULL )      
+            _sqt_barrier_decrement( node->parent );
+
+        // reset the current node
+        node->sense = expected;
+        node->count = node->arity;
+
+#if GIET_DEBUG_SQT_BARRIER
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] reset SQT barrier node %x :\n"
+        " level = %d / arity = %d / sense = %d / count = %d\n",
+        px , py , pl , (unsigned int)node , 
+        node->level , node->arity , node->sense , node->count );
+#endif
+        return;
+    }
+    else                 // not the last task
+    {
+        // poll the local "sense" flag
+        while ( ioread32( &node->sense ) != expected ) asm volatile ("nop");
+
+        return;
+    }
+}  // end _sqt_barrier_decrement()
+
+////////////////////// initialises NIC & CMA RX channel, and /////////////////////////////////////////////////////////
+// This external blocking function waits until all procesors reach the barrier.
+// Returns only when the barrier has been taken.
+///////////////////////////////////////////////////////////////////////////////
+void _sqt_barrier_wait( sqt_barrier_t*  barrier )
+{
+    // get cluster coordinates
+    unsigned int gpid = _get_procid();
+    unsigned int px   = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
+    unsigned int py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+
+#if GIET_DEBUG_SQT_BARRIER
+unsigned int pl = gpid & ((1<<P_WIDTH)-1);
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] enters SQT barrier %x at cycle %d\n",
+        px , py , pl , (unsigned int)barrier , _get_proctime() ); 
+#endif
+
+   // decrement the barrier counters
+    _sqt_barrier_decrement( barrier->node[px][py][0] );
+
+#if GIET_DEBUG_SQT_BARRIER
+_printf("\n[DEBUG SQT_BARRIER] P[%d,%d,%d] exit SQT barrier %x at cycle %d\n",
+        px , py , pl , (unsigned int)barrier , _get_proctime() ); 
+#endif
+
+    asm volatile ("sync" ::: "memory");
+
+}  // end _sqt_barrier_wait()
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_common/kernel_barriers.h
===================================================================
--- /soft/giet_vm/giet_common/kernel_barriers.h	(revision 495)
+++ /soft/giet_vm/giet_common/kernel_barriers.h	(revision 495)
@@ -0,0 +1,71 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : kernel_barrier.h
+// Date     : 19/01/2015
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The kernel_barrier.c and kernel_barrier.h files are part of the GIET-VM kernel.
+// They define both a simple barrier and a scalable, distributed barrier,
+// based on Synchronisation Quad Tree (SQT).
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef GIET_KERNEL_BARRIERS_H
+#define GIET_KERNEL_BARRIERS_H
+
+#include "hard_config.h"
+
+#define SBT_MAX_LEVELS 5
+
+///////////////////////////////////////////////////////////////////////////////////
+//      Simple barrier structure and access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct simple_barrier_s
+{
+    unsigned int sense;          // barrier state (toggle)
+    unsigned int ntasks;         // total numer of expected tasks
+    unsigned int count;          // number of not arrived tasks
+    unsigned int padding[13];    // for 64 bytes alignment
+} simple_barrier_t;
+
+extern void _simple_barrier_init( simple_barrier_t*  barrier,
+                                  unsigned int       ntasks );
+
+extern void _simple_barrier_wait( simple_barrier_t*  barrier );
+
+//////////////////////////////////////////////////////////////////////////////////
+//      SQT barrier structures and access functions
+//////////////////////////////////////////////////////////////////////////////////
+
+typedef struct sqt_barrier_node_s 
+{
+    unsigned int                arity;        // number of children (4 max)
+    unsigned int                count;        // number of not arrived children
+    unsigned int                sense;        // barrier state (toggle)      
+    unsigned int                level;        // hierarchical level (0 is bottom)
+    struct sqt_barrier_node_s*  parent;       // parent node (NULL for root)
+    struct sqt_barrier_node_s*  child[4];     // children node
+    unsigned int                padding[7];   // for 64 bytes alignment         
+} sqt_barrier_node_t;
+
+typedef struct sqt_barrier_s 
+{
+    unsigned int          ntasks;
+    sqt_barrier_node_t*   node[X_SIZE][Y_SIZE][SBT_MAX_LEVELS];
+} sqt_barrier_t;
+
+extern void _sqt_barrier_init( sqt_barrier_t*  barrier );
+
+extern void _sqt_barrier_wait( sqt_barrier_t*  barrier );
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_common/kernel_locks.c
===================================================================
--- /soft/giet_vm/giet_common/kernel_locks.c	(revision 495)
+++ /soft/giet_vm/giet_common/kernel_locks.c	(revision 495)
@@ -0,0 +1,467 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : kernel_locks.c
+// Date     : 01/12/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "kernel_locks.h"
+#include "giet_config.h"
+#include "hard_config.h"
+#include "utils.h"
+#include "tty0.h"
+#include "kernel_malloc.h"
+#include "io.h"
+
+///////////////////////////////////////////////////
+unsigned int _atomic_increment( unsigned int* ptr,
+                                int           increment )
+{
+    unsigned int value;
+
+    asm volatile (
+        "1234:                         \n"
+        "move $10,   %1                \n"   /* $10 <= ptr               */
+        "move $11,   %2                \n"   /* $11 <= increment         */
+        "ll   $12,   0($10)            \n"   /* $12 <= *ptr              */
+        "addu $13,   $11,    $12       \n"   /* $13 <= *ptr + increment  */
+        "sc   $13,   0($10)            \n"   /* M[ptr] <= new            */ 
+        "beqz $13,   1234b             \n"   /* retry if failure         */
+        "move %0,    $12               \n"   /* value <= *ptr if success */
+        : "=r" (value) 
+        : "r" (ptr), "r" (increment)
+        : "$10", "$11", "$12", "$13", "memory" );
+
+    return value;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//      Simple lock access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////
+void _simple_lock_acquire( simple_lock_t* lock )
+{
+
+#if GIET_DEBUG_SIMPLE_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] enters acquire() at cycle %d\n",
+               x , y , l , _get_proctime() );
+#endif
+
+    asm volatile ( "1515:                   \n"
+	               "lw   $2,    0(%0)       \n"
+	               "bnez $2,    1515b       \n"
+                   "ll   $2,    0(%0)       \n"
+                   "bnez $2,    1515b       \n"
+                   "li   $3,    1           \n"
+                   "sc   $3,    0(%0)       \n"
+                   "beqz $3,    1515b       \n"
+                   :
+                   : "r"(lock)
+                   : "$2", "$3", "memory" );
+
+#if GIET_DEBUG_SIMPLE_LOCK
+_nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] exit acquire() at cycle %d\n",
+               x , y , l , _get_proctime() );
+#endif
+
+}
+
+////////////////////////////////////////////////
+void _simple_lock_release( simple_lock_t* lock )
+{
+    asm volatile ( "sync" );   // for consistency
+
+    lock->value = 0;
+
+#if GIET_DEBUG_SIMPLE_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] release() at cycle %d\n",
+               x , y , l , _get_proctime() );
+#endif
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//      Queuing Lock access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////
+void _spin_lock_init( spin_lock_t* lock )
+{
+    lock->current = 0;
+    lock->free    = 0;
+
+#if GIET_DEBUG_SPIN_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] initializes lock %x at cycle %d\n",
+               x, y, l, (unsigned int)lock, _get_proctime() );
+#endif
+
+}
+
+
+////////////////////////////////////////////
+void _spin_lock_acquire( spin_lock_t* lock )
+{
+    // get next free slot index fromlock
+    unsigned int ticket = _atomic_increment( &lock->free, 1 );
+
+#if GIET_DEBUG_SPIN_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] get ticket %d for lock %x at cycle %d"
+               " / current = %d / free = %d\n",
+               x, y, l, ticket, (unsigned int)lock, _get_proctime(),
+               lock->current, lock->free );
+#endif
+
+    // poll the spin_lock current slot index
+    while ( ioread32( &lock->current ) != ticket ) asm volatile ("nop");
+
+#if GIET_DEBUG_SPIN_LOCK
+_nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] get lock %x at cycle %d"
+               " / current = %d / free = %d\n",
+               x, y, l, (unsigned int)lock, _get_proctime(),
+               lock->current, lock->free );
+#endif
+
+}
+
+////////////////////////////////////////////
+void _spin_lock_release( spin_lock_t* lock )
+{
+    asm volatile ( "sync" );   // for consistency
+
+    lock->current = lock->current + 1;
+
+#if GIET_DEBUG_SPIN_LOCK
+_nolock_printf("\n[DEBUG SPIN_LOCK] P[%d,%d,%d] release lock %x at cycle %d"
+               " / current = %d / free = %d\n",
+               x, y, l, (unsigned int)lock, _get_proctime(),
+               lock->current, lock->free );
+#endif
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//      SQT lock access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// This recursive function is used by the _sqt_lock_init() function
+// to initializes the SQT nodes (mainly the parent and child pointers).
+// It traverses the SQT from top to bottom.
+// The SQT can be uncomplete (when xmax or ymax are not power of 2),
+// and the recursion stops when the (x,y) coordinates exceed the footprint.
+///////////////////////////////////////////////////////////////////////////////////
+static 
+void _sqt_lock_build( sqt_lock_t*      lock,      // pointer on the SQT lock
+                      unsigned int     x,         // node X coordinate
+                      unsigned int     y,         // node Y coordinate
+                      unsigned int     level,     // node level
+                      sqt_lock_node_t* parent,    // pointer on parent node
+                      unsigned int     xmax,      // SQT X size
+                      unsigned int     ymax )     // SQT Y size
+{
+
+#if GIET_DEBUG_SQT_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+#endif
+
+    // get target node pointer
+    sqt_lock_node_t* node = lock->node[x][y][level];
+    
+    if (level == 0 )        // terminal case
+    {
+        // initializes target node
+        node->current  = 0;   
+        node->free     = 0;
+        node->level    = 0;
+        node->parent   = parent;
+        node->child[0] = NULL;
+        node->child[1] = NULL;
+        node->child[2] = NULL;
+        node->child[3] = NULL;
+
+#if GIET_DEBUG_SQT_LOCK
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n"
+      " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
+      px , py , pl , x , y , level , 
+      (unsigned int)node->parent , 
+      (unsigned int)node->child[0] , 
+      (unsigned int)node->child[1] , 
+      (unsigned int)node->child[2] , 
+      (unsigned int)node->child[3] );
+#endif
+
+    }
+    else                   // non terminal case
+    {
+        unsigned int cx[4];      // x coordinate for children
+        unsigned int cy[4];      // y coordinate for children
+        unsigned int i;          // child index
+
+        // the child0 coordinates are equal to the parent coordinates
+        // other childs coordinates are incremented depending on the level value
+        cx[0] = x;
+        cy[0] = y;
+
+        cx[1] = x + (1 << (level-1));
+        cy[1] = y;
+
+        cx[2] = x;
+        cy[2] = y + (1 << (level-1));
+
+        cx[3] = x + (1 << (level-1));
+        cy[3] = y + (1 << (level-1));
+
+        // initializes target node
+        for ( i = 0 ; i < 4 ; i++ )
+        {
+            if ( (cx[i] < xmax) && (cy[i] < ymax) ) 
+                node->child[i] = lock->node[cx[i]][cy[i]][level-1];
+            else  
+                node->child[i] = NULL;
+        }
+        node->current  = 0;
+        node->free     = 0;
+        node->level    = level;
+        node->parent   = parent;
+
+#if GIET_DEBUG_SQT_LOCK
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n"
+      " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
+      px , py , pl , x , y , level , 
+      (unsigned int)node->parent , 
+      (unsigned int)node->child[0] , 
+      (unsigned int)node->child[1] , 
+      (unsigned int)node->child[2] , 
+      (unsigned int)node->child[3] );
+#endif
+
+       // recursive calls for children nodes
+        for ( i = 0 ; i < 4 ; i++ )
+        {
+            if ( (cx[i] < xmax) && (cy[i] < ymax) ) 
+                _sqt_lock_build( lock, 
+                                 cx[i], 
+                                 cy[i], 
+                                 level-1, 
+                                 node, 
+                                 xmax, 
+                                 ymax );
+        }
+    }
+}  // end _sqt_lock_build()
+
+/////////////////////////////////////////////////////////////////////////////////
+// This external function initialises the distributed SQT lock.
+// It allocates memory for the distributed SQT nodes in clusters,
+// and initializes the SQT nodes pointers array (stored in cluster[0][0].
+// The SQT can be "uncomplete" as SQT lock nodes are only build in clusters
+// containing processors.
+// The actual number of SQT locks nodes in a cluster[x][y] depends on (x,y): 
+// At least 1 node / at most 5 nodes per cluster:
+// - lock arbitrating between all processors of   1 cluster  has level 0,
+// - lock arbitrating between all processors of   4 clusters has level 1,
+// - lock arbitrating between all processors of  16 clusters has level 2,
+// - lock arbitrating between all processors of  64 clusters has level 3,
+// - lock arbitrating between all processors of 256 clusters has level 4,
+/////////////////////////////////////////////////////////////////////////////////
+void _sqt_lock_init( sqt_lock_t*  lock )
+{
+    unsigned int levels;
+    unsigned int xmax;
+    unsigned int ymax;
+
+    // compute the smallest SQT covering all processors
+    _get_sqt_footprint( &xmax, &ymax, &levels );
+
+
+#if GIET_DEBUG_SQT_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] initialises SQT lock %x : \n"
+               " xmax = %d / ymax = %d / levels = %d\n",
+               px , py , pl , (unsigned int)lock , 
+               xmax , ymax , levels );
+#endif
+
+    
+    unsigned int x;              // x coordinate for one SQT node
+    unsigned int y;              // y coordinate for one SQT node
+    unsigned int l;              // level for one SQT node
+
+    for ( x = 0 ; x < xmax ; x++ )
+    {
+        for ( y = 0 ; y < ymax ; y++ )
+        {
+            for ( l = 0 ; l < levels ; l++ )             // level 0 nodes
+            {
+                
+                if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) ||
+                     ( (l == 1) && ((x&0x01) == 0) && ((y&0x01) == 0) ) ||
+                     ( (l == 2) && ((x&0x03) == 0) && ((y&0x03) == 0) ) ||
+                     ( (l == 3) && ((x&0x07) == 0) && ((y&0x07) == 0) ) ||
+                     ( (l == 4) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) )
+                 {
+                     lock->node[x][y][l] = 
+                     (sqt_lock_node_t*)_remote_malloc( sizeof(sqt_lock_node_t),
+                                                       x, y );
+
+#if GIET_DEBUG_SQT_LOCK
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] allocates SQT node[%d,%d,%d]"
+               " : vaddr = %x\n",
+               px , py , pl , x , y , l , (unsigned int)lock->node[x][y][l] );
+#endif
+                 }
+            }
+        }
+    }
+            
+    // recursively initialize all SQT nodes from root to bottom
+    _sqt_lock_build( lock,       // pointer on the SQT lock descriptor
+                     0,          // x coordinate
+                     0,          // y coordinate
+                     levels-1,   // level in SQT
+                     NULL,       // pointer on the parent node
+                     xmax,       // SQT footprint X size
+                     ymax );     // SQT footprint X size
+
+    asm volatile ("sync" ::: "memory");
+
+#if GIET_DEBUG_SQT_LOCK
+_nolock_printf("\n[DEBUG SQT_LOCK] SQT nodes initialisation completed\n"); 
+#endif
+
+} // end _sqt_lock_init()
+
+//////////////////////////////////////////////////////////////////////////////////
+// This recursive function is used by the sqt_lock_acquire() function to get
+// a distributed SQT lock: It tries to get each local queuing lock on the path
+// from bottom to top, and starting from bottom.
+// It is blocking : it polls each "partial lock until it can be taken. 
+// The lock is finally obtained when all locks, at all levels are taken.
+//////////////////////////////////////////////////////////////////////////////////
+static 
+void _sqt_lock_take( sqt_lock_node_t* node )
+{
+    // get next free ticket from local lock
+    unsigned int ticket = _atomic_increment( &node->free, 1 );
+
+#if GIET_DEBUG_SQT_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] get ticket %d for SQT lock %x"
+               " / level = %d / current = %d / free = %d\n",
+               x , y , l , ticket , (unsigned int)node ,
+               node->level , node->current , node->free );
+#endif
+
+    // poll the local lock current index
+    while ( ioread32( &node->current ) != ticket ) asm volatile( "nop" );
+
+#if GIET_DEBUG_SQT_LOCK
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] get SQT lock %x"
+               " / level = %d / current = %d / free = %d\n",
+               x , y , l , (unsigned int)node ,
+               node->level , node->current , node->free );
+#endif
+
+    // try to take the parent node lock until top is reached
+    if ( node->parent != NULL ) _sqt_lock_take( node->parent );
+
+} // end _sqt_lock_take()
+    
+//////////////////////////////////////////////////////////////////////////////////
+// This external function get thes SQT lock.
+// Returns only when the lock has been taken. 
+/////////////////////////////////////////////////////////////////////////////////
+void _sqt_lock_acquire( sqt_lock_t*  lock )
+{
+    // get cluster coordinates
+    unsigned int gpid = _get_procid();
+    unsigned int x    = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
+    unsigned int y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+
+    // try to recursively take the distributed locks (from bottom to top)
+    _sqt_lock_take( lock->node[x][y][0] );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// This recursive function is used by the sqt_lock_release() function to
+// release distributed SQT lock: It releases all local locks on the path from 
+// bottom to top, using a normal read/write, and starting from bottom.
+/////////////////////////////////////////////////////////////////////////////////
+static 
+void _sqt_lock_give( sqt_lock_node_t* node )
+{
+    // release the local lock
+    node->current = node->current + 1;
+
+#if GIET_DEBUG_SQT_LOCK
+unsigned int    gpid = _get_procid();
+unsigned int    x   = gpid >> (Y_WIDTH + P_WIDTH);
+unsigned int    y   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int    l   = gpid & ((1<<P_WIDTH)-1);
+_nolock_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] release SQT lock %x"
+               " / level = %d / current = %d / free = %d\n",
+               x , y , l , (unsigned int)node, 
+               node->level , node->current , node->free );
+#endif
+
+    // reset parent node until top is reached
+    if ( node->parent != NULL ) _sqt_lock_give( node->parent );
+
+} // end _sqt_lock_give()
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// This external function releases the SQT lock.
+/////////////////////////////////////////////////////////////////////////////////
+void _sqt_lock_release( sqt_lock_t*  lock )
+{
+    asm volatile ( "sync" );   // for consistency
+
+    // get cluster coordinates
+    unsigned int gpid = _get_procid();
+    unsigned int x    = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
+    unsigned int y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+
+    // recursively reset the distributed locks (from bottom to top)
+    _sqt_lock_give( lock->node[x][y][0] );
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_common/kernel_locks.h
===================================================================
--- /soft/giet_vm/giet_common/kernel_locks.h	(revision 495)
+++ /soft/giet_vm/giet_common/kernel_locks.h	(revision 495)
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : kernel_locks.h
+// Date     : 01/12/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The locks.c and locks.h files are part of the GIET-VM nano-kernel.
+// They define both atomic increment operations and three types of locks.
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef GIET_LOCKS_H
+#define GIET_LOCKS_H
+
+#include "hard_config.h"
+
+///////////////////////////////////////////////////////////////////////////////////
+//      Simple lock structure and access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct simple_lock_s
+{
+    unsigned int value;          // lock taken if non zero
+    unsigned int padding[15];    // for 64 bytes alignment
+} simple_lock_t;
+
+extern void _simple_lock_acquire( simple_lock_t* lock );
+
+extern void _simple_lock_release( simple_lock_t* lock );
+
+///////////////////////////////////////////////////////////////////////////////////
+//      Queuing lock structure and access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct spin_lock_s 
+{
+    unsigned int current;        // current slot index:
+    unsigned int free;           // next free tiket index
+    unsigned int padding[14];    // for 64 bytes alignment
+} spin_lock_t;
+
+extern unsigned int _atomic_increment( unsigned int* ptr,
+                                       int  increment );
+
+extern void _spin_lock_init( spin_lock_t* lock );
+
+extern void _spin_lock_acquire( spin_lock_t* lock );
+
+extern void _spin_lock_release( spin_lock_t* lock );
+
+
+//////////////////////////////////////////////////////////////////////////////////
+//      SQT lock structures and access functions
+//////////////////////////////////////////////////////////////////////////////////
+
+typedef struct sqt_lock_node_s 
+{
+    unsigned int            current;         // current ticket index
+    unsigned int            free;            // next free ticket index
+    unsigned int            level;           // hierarchical level (0 is bottom)
+    struct sqt_lock_node_s* parent;          // parent node (NULL for root)
+    struct sqt_lock_node_s* child[4];        // children node
+    unsigned int            padding[8];      // for 64 bytes alignment         
+} sqt_lock_node_t;
+
+typedef struct sqt_lock_s 
+{
+    sqt_lock_node_t* node[X_SIZE][Y_SIZE][5];  // array of pointers on SBT nodes 
+} sqt_lock_t;
+
+extern void _sqt_lock_init( sqt_lock_t*   lock );
+
+extern void _sqt_lock_acquire( sqt_lock_t*  lock );
+
+extern void _sqt_lock_release( sqt_lock_t*  lock );
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_common/kernel_malloc.c
===================================================================
--- /soft/giet_vm/giet_common/kernel_malloc.c	(revision 494)
+++ /soft/giet_vm/giet_common/kernel_malloc.c	(revision 495)
@@ -6,5 +6,5 @@
 ////////////////////////////////////////////////////////////////////////////////
 //   Implementation note:
-// - As this code is used to implement the SBT lock ptotecting TTY0,
+// - As this code is used to implement the SQT lock ptotecting TTY0,
 //   all functions here use the kernel _nolock_printf() function.
 // - It must exist one vseg with the HEAP type in each cluster. The length
@@ -37,5 +37,5 @@
 #include "mapping_info.h"
 #include "kernel_malloc.h"
-#include "locks.h"
+#include "kernel_locks.h"
 #include "tty0.h"
 #include "utils.h"
@@ -45,5 +45,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
-extern kernel_heap_t kernel_heap[X_SIZE][Y_SIZE];
+__attribute__((section(".kdata")))
+kernel_heap_t kernel_heap[X_SIZE][Y_SIZE];
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -83,4 +84,5 @@
                                             (size <= 0x80000000) ? 31 :\
                                                                    32
+
 #if GIET_DEBUG_SYS_MALLOC
 ////////////////////////////////////////////////
@@ -115,5 +117,5 @@
                    " - free[22]    = %x\n"
                    " - free[23]    = %x\n",
-                   kernel_heap[x][y].x, kernel_heap[x][y].y, 
+                   x, y, 
                    kernel_heap[x][y].heap_base, kernel_heap[x][y].heap_size, 
                    kernel_heap[x][y].free[0] , kernel_heap[x][y].free[1], 
@@ -135,9 +137,9 @@
 
 
-/////////////////////////////////////////////
-void _get_heap_info( unsigned int* heap_base,
-                     unsigned int* heap_size,
-                     unsigned int  x,
-                     unsigned int  y )
+/////////////////////////////////////////////////////
+unsigned int _get_heap_info( unsigned int* heap_base,
+                             unsigned int* heap_size,
+                             unsigned int  x,
+                             unsigned int  y )
 {
     mapping_header_t  * header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
@@ -155,6 +157,6 @@
     if ( (x >= X_SIZE) || (y >= Y_SIZE) )
     {
-        _nolock_printf("[GIET ERROR] _get_heap_info() illegal (%d,%d) coordinates\n",
-                       x , y );
+        _nolock_printf("\n[GIET ERROR] _get_heap_info()"
+                       " illegal (%d,%d) coordinates\n", x , y );
         _exit();
     }
@@ -172,13 +174,9 @@
             *heap_base = vsegs[vseg_id].vbase;
             *heap_size = vobjs[vobj_id].length;
-            return;
+            return 0;
         }
     }
 
-    // exit if not found
-    _nolock_printf("[GIET ERROR] _get_heap_info() heap[%d][%d] vseg not found\n",
-                   x , y );
-    _exit();
-
+    return 1;
 } // end _get_heap_info()
 
@@ -191,8 +189,8 @@
     unsigned int heap_size;
     unsigned int heap_index;
-
     unsigned int index;
     unsigned int x;
     unsigned int y;
+    unsigned int ko;
 
     for ( x = 0 ; x < X_SIZE ; x++ )
@@ -201,41 +199,47 @@
         {
             // get heap_base, heap size, and heap index
-            _get_heap_info( &heap_base, &heap_size, x, y );
-            heap_index = GET_SIZE_INDEX( heap_size );
-
-            // checking heap segment constraints
-            if ( heap_size != (1<<heap_index) )
+            ko = _get_heap_info( &heap_base, &heap_size, x, y );
+       
+            if ( ko )  // no kernel heap found in cluster[x][y]
             {
-                _nolock_printf("[GIET ERROR] in _heap_init()"
-                        " kernel_heap[â°d,â°d] not power of 2\n", x , y );
-                _exit();
+                // initialise kernel_heap[x][y] descriptor
+                kernel_heap[x][y].heap_base  = 0;
+                kernel_heap[x][y].heap_size  = 0;
+                _spin_lock_init( &kernel_heap[x][y].lock );
             }
-            if ( heap_base % heap_size ) 
+            else       // kernel heap found in cluster[x][y]
             {
-                _nolock_printf("[GIET ERROR] in _heap_init()"
-                        " kernel_heap[â°d,â°d] not aligned\n", x , y );
-                _exit();
+                heap_index = GET_SIZE_INDEX( heap_size );
+
+                // check heap[x][y] constraints
+                if ( heap_size != (1<<heap_index) )
+                {
+                    _nolock_printf("\n[GIET ERROR] in _heap_init()"
+                                   " kernel_heap[â°d,â°d] not power of 2\n", x , y );
+                    _exit();
+                }
+                if ( heap_base % heap_size ) 
+                {
+                    _nolock_printf("\n[GIET ERROR] in _heap_init()"
+                                   " kernel_heap[â°d,â°d] not aligned\n", x , y );
+                    _exit();
+                }
+
+                // initialise the free[] array 
+                for ( index = 0 ; index < 32 ; index++ ) 
+                {
+                    if (index == heap_index) kernel_heap[x][y].free[index] = heap_base;
+                    else                     kernel_heap[x][y].free[index] = 0;
+                }
+
+                // initialise kernel_heap[x][y] descriptor
+                kernel_heap[x][y].heap_base  = heap_base;
+                kernel_heap[x][y].heap_size  = heap_size;
+                _spin_lock_init( &kernel_heap[x][y].lock );
             }
 
-            // initialise the free[] array 
-            for ( index = 0 ; index < 32 ; index++ ) 
-            {
-                if (index == heap_index) kernel_heap[x][y].free[index] = heap_base;
-                else                     kernel_heap[x][y].free[index] = 0;
-            }
-            unsigned int* ptr = (unsigned int*)heap_base;
-            *ptr = 0;
-
-            // initialise kernel_heap[x][y] descriptor
-            kernel_heap[x][y].x          = x;
-            kernel_heap[x][y].y          = y;
-            kernel_heap[x][y].heap_base  = heap_base;
-            kernel_heap[x][y].heap_size  = heap_size;
-
-            _spin_lock_init( &kernel_heap[x][y].lock );
-
 #if GIET_DEBUG_SYS_MALLOC
-_nolock_printf("\n[DEBUG KERNEL_MALLOC] Completing kernel_heap[%d][%d] initialisation\n",
-               x, y );
+_nolock_printf("\n[DEBUG KERNEL_MALLOC] Completing kernel_heap[%d][%d]"
+               " initialisation\n", x, y );
 _display_free_array(x,y);
 #endif
@@ -248,8 +252,8 @@
 
 //////////////////////////////////////////////
-unsigned int split_block( kernel_heap_t* heap,
-                          unsigned int   vaddr, 
-                          unsigned int   searched_index,
-                          unsigned int   requested_index )
+unsigned int _split_block( kernel_heap_t* heap,
+                           unsigned int   vaddr, 
+                           unsigned int   searched_index,
+                           unsigned int   requested_index )
 {
     // push the upper half block into free[searched_index-1]
@@ -258,5 +262,5 @@
     heap->free[searched_index-1] = (unsigned int)new;
         
-    if ( searched_index == requested_index + 1 )  // terminal case: return lower half block 
+    if ( searched_index == requested_index + 1 )  //  return lower half block 
     {
         return vaddr;
@@ -264,14 +268,14 @@
     else            // non terminal case : lower half block must be split again
     {                               
-        return split_block( heap, vaddr, searched_index-1, requested_index );
-    }
-} // end split_block()
+        return _split_block( heap, vaddr, searched_index-1, requested_index );
+    }
+} // end _split_block()
 
 
 
 /////////////////////////////////////////////
-unsigned int get_block( kernel_heap_t* heap,
-                        unsigned int   searched_index,
-                        unsigned int   requested_index )
+unsigned int _get_block( kernel_heap_t* heap,
+                         unsigned int   searched_index,
+                         unsigned int   requested_index )
 {
     // test terminal case
@@ -285,5 +289,5 @@
         if ( vaddr == 0 )     // block not found : search in free[searched_index+1]
         {
-            return get_block( heap, searched_index+1, requested_index );
+            return _get_block( heap, searched_index+1, requested_index );
         }
         else                // block found : pop it from free[searched_index] 
@@ -300,9 +304,9 @@
             else                                      // split is required
             {
-                return split_block( heap, vaddr, searched_index, requested_index );
+                return _split_block( heap, vaddr, searched_index, requested_index );
             }
         } 
     }
-} // end get_block()
+} // end _get_block()
 
 
@@ -314,18 +318,19 @@
 {
     // checking arguments
-    if (size == 0) 
-    {
-        _nolock_printf("[GIET ERROR] _remote_malloc() : requested size = 0 \n");
+    if ( x >= X_SIZE )
+    {
+        _nolock_printf("\n[GIET ERROR] _remote_malloc() : x coordinate too large\n");
         _exit();
     }
-    if ( x >= X_SIZE )
-    {
-        _nolock_printf("[GIET ERROR] _remote_malloc() : x coordinate too large\n");
+    if ( y >= Y_SIZE )
+    {
+        _nolock_printf("\n[GIET ERROR] _remote_malloc() : y coordinate too large\n");
         _exit();
     }
-    if ( y >= Y_SIZE )
-    {
-        _nolock_printf("[GIET ERROR] _remote_malloc() : y coordinate too large\n");
+    if ( kernel_heap[x][y].heap_size == 0 )
+    {
+        _nolock_printf("\n[GIET ERROR] _remote_malloc() : No heap[%d][%d]\n", x, y );
         _exit();
+     
     }
 
@@ -340,10 +345,16 @@
 
     // call the recursive function get_block
-    unsigned int base = get_block( &kernel_heap[x][y], 
-                                   requested_index, 
-                                   requested_index );
+    unsigned int base = _get_block( &kernel_heap[x][y], 
+                                    requested_index, 
+                                    requested_index );
     // release the lock
     _spin_lock_release( &kernel_heap[x][y].lock );
  
+    if ( base == 0 )
+    {
+        _nolock_printf("\n[GIET ERROR] _remote_malloc() : no more space "
+                       "in heap[%d][%d]", x, y );
+    }
+
 #if GIET_DEBUG_SYS_MALLOC
 _nolock_printf("\n[DEBUG KERNEL_MALLOC] malloc vaddr %x from kernel_heap[%d][%d]\n", 
@@ -354,5 +365,5 @@
     return (void*)base;
 
-} // end remote_malloc()
+} // end _remote_malloc()
 
 
Index: /soft/giet_vm/giet_common/kernel_malloc.h
===================================================================
--- /soft/giet_vm/giet_common/kernel_malloc.h	(revision 494)
+++ /soft/giet_vm/giet_common/kernel_malloc.h	(revision 495)
@@ -11,5 +11,5 @@
 #define KERNEL_MALLOC_H_
 
-#include "locks.h"
+#include "kernel_locks.h"
 #include "hard_config.h"
 
@@ -25,6 +25,4 @@
 {
     spin_lock_t    lock;            // lock protecting exclusive access
-    unsigned int   x;               // cluster X coordinate
-    unsigned int   y;               // cluster Y coordinate
     unsigned int   heap_base;       // heap base address
     unsigned int   heap_size;       // heap size (bytes)
Index: ft/giet_vm/giet_common/locks.c
===================================================================
--- /soft/giet_vm/giet_common/locks.c	(revision 494)
+++ 	(revision )
@@ -1,496 +1,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : locks.c
-// Date     : 01/12/2014
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-
-#include "locks.h"
-#include "giet_config.h"
-#include "hard_config.h"
-#include "utils.h"
-#include "tty0.h"
-#include "kernel_malloc.h"
-
-///////////////////////////////////////////////////
-unsigned int _atomic_increment( unsigned int* ptr,
-                                unsigned int  increment )
-{
-    unsigned int value;
-
-    asm volatile (
-        "1234:                         \n"
-        "move $10,   %1                \n"   /* $10 <= ptr               */
-        "move $11,   %2                \n"   /* $11 <= increment         */
-        "ll   $12,   0($10)            \n"   /* $12 <= *ptr              */
-        "addu $13,   $11,    $12       \n"   /* $13 <= *ptr + increment  */
-        "sc   $13,   0($10)            \n"   /* M[ptr] <= new            */ 
-        "beqz $13,   1234b             \n"   /* retry if failure         */
-        "move %0,    $12               \n"   /* value <= *ptr if success */
-        : "=r" (value) 
-        : "r" (ptr), "r" (increment)
-        : "$10", "$11", "$12", "$13", "memory" );
-
-    return value;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-//      Simple lock access functions
-///////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////
-void _simple_lock_acquire( simple_lock_t* lock )
-{
-
-#if GIET_DEBUG_SIMPLE_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
-_nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] enters acquire() at cycle %d\n",
-               x , y , l , _get_proctime() );
-#endif
-
-    asm volatile ( "1515:                   \n"
-	               "lw   $2,    0(%0)       \n"   /* $2 <= lock current value         */
-	               "bnez $2,    1515b       \n"   /* retry if lock already taken      */
-                   "ll   $2,    0(%0)       \n"   /* ll_buffer <= lock current value  */
-                   "bnez $2,    1515b       \n"   /* retry if lock already taken      */
-                   "li   $3,    1           \n"   /* $3 <= argument for sc            */
-                   "sc   $3,    0(%0)       \n"   /* try to set lock                  */
-                   "beqz $3,    1515b       \n"   /* retry if sc failure              */
-                   :
-                   : "r"(lock)
-                   : "$2", "$3", "memory" );
-
-#if GIET_DEBUG_SIMPLE_LOCK
-_nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] exit acquire() at cycle %d\n",
-               x , y , l , _get_proctime() );
-#endif
-
-}
-
-////////////////////////////////////////////////
-void _simple_lock_release( simple_lock_t* lock )
-{
-    asm volatile ( "sync                    \n"   /* for consistency                  */
-                   "sw   $0,    0(%0)       \n"   /* release lock                     */
-                   :
-                   : "r"(lock)
-                   : "memory" );
-
-#if GIET_DEBUG_SIMPLE_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
-_nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] release() at cycle %d\n",
-               x , y , l , _get_proctime() );
-#endif
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////
-//      Queuing Lock access functions
-///////////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////
-void _spin_lock_init( spin_lock_t* lock )
-{
-    lock->current = 0;
-    lock->free    = 0;
-
-#if GIET_DEBUG_SPIN_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
-_puts("\n[DEBUG SPIN_LOCK] P[");
-_putd( x );
-_puts(",");
-_putd( y );
-_puts(",");
-_putd( l );
-_puts("] init lock ");
-_putx( (unsigned int)lock );
-_puts(" (current = ");
-_putd( lock->current );
-_puts(" / free = ");
-_putd( lock->free );
-_puts(" )\n");
-#endif
-
-}
-
-
-////////////////////////////////////////////
-void _spin_lock_acquire( spin_lock_t* lock )
-{
-    // get next free slot index fromlock
-    unsigned int ticket = _atomic_increment( &lock->free, 1 );
-
-#if GIET_DEBUG_SPIN_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
-_puts("\n[DEBUG SPIN_LOCK] P[");
-_putd( x );
-_puts(",");
-_putd( y );
-_puts(",");
-_putd( l );
-_puts("] get ticket ");
-_putx( ticket );
-_puts(" for lock ");
-_putx( (unsigned int)lock );
-_puts(" (current = ");
-_putd( lock->current );
-_puts(" / free = ");
-_putd( lock->free );
-_puts(" )\n");
-#endif
-
-
-    // poll the spin_lock current slot index
-    asm volatile("5678:                   \n"
-                 "lw   $10,  0(%0)        \n"
-                 "move $11,  %1           \n"
-                 "bne  $10,  $11,  5678b  \n"
-                 :
-                 : "r"(lock), "r"(ticket)
-                 : "$10", "$11" );
-
-#if GIET_DEBUG_SPIN_LOCK
-_puts("\n[DEBUG SPIN_LOCK] P[");
-_putd( x );
-_puts(",");
-_putd( y );
-_puts(",");
-_putd( l );
-_puts("] get lock ");
-_putx( (unsigned int)lock );
-_puts(" (current = ");
-_putd( lock->current );
-_puts(" / free = ");
-_putd( lock->free );
-_puts(" )\n");
-#endif
-
-}
-
-////////////////////////////////////////////
-void _spin_lock_release( spin_lock_t* lock )
-{
-    unsigned int current = lock->current;
-
-    if ( current == (GIET_LOCK_MAX_TICKET - 1) ) current = 0;
-    else                                         current = current + 1;
-
-    asm volatile ( "sync                    \n"   /* for consistency                  */
-                   "sw   %1,    0(%0)       \n"   /* release lock                     */
-                   :
-                   : "r"(lock), "r"(current)
-                   : "memory" );
-    
-
-#if GIET_DEBUG_SPIN_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
-_puts("\n[DEBUG SPIN_LOCK] P[");
-_putd( x );
-_puts(",");
-_putd( y );
-_puts(",");
-_putd( l );
-_puts("] release lock ");
-_putx( (unsigned int)lock );
-_puts(" (current = ");
-_putd( lock->current );
-_puts(" / free = ");
-_putd( lock->free );
-_puts(" )\n");
-#endif
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-//      SBT lock access functions
-///////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////
-// This recursive function is used by the _sbt_lock_init() function
-// to initializes the SBT nodes (mainly the parent and child pointers).
-// It traverses the SBT from top to bottom.
-///////////////////////////////////////////////////////////////////////////////////
-static void _sbt_lock_build( sbt_lock_t*     lock,      // pointer on the SBT lock
-                             unsigned int    x,         // SBT node x coordinate
-                             unsigned int    y,         // SBT node y coordinate
-                             unsigned int    level,     // SBT node level
-                             lock_node_t*    parent )   // pointer on parent node
-{
-
-#if GIET_DEBUG_SBT_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
-#endif
-
-    // get target node pointer
-    lock_node_t* node = lock->node[x][y][level];
-    
-    if (level == 0 )        // terminal case
-    {
-        // initializes target node
-        node->taken    = 0;   
-        node->level    = level;
-        node->parent   = parent;
-        node->child0   = NULL;
-        node->child1   = NULL;
-        node->x        = x;
-        node->y        = y;
-
-#if GIET_DEBUG_SBT_LOCK
-_nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT node[%d,%d,%d] : "
-      "parent = %x / childO = %x / child1 = %x\n",
-      px , py , pl , node->x , node->y , node->level , 
-      (unsigned int)node->parent , (unsigned int)node->child0 , (unsigned int)node->child1 );
-#endif
-
-    }
-    else                   // non terminal case
-    {
-        unsigned int x0;   // x coordinate for child0
-        unsigned int y0;   // y coordinate for child0;
-        unsigned int x1;   // x coordinate for child1;
-        unsigned int y1;   // y coordinate for child1;
-
-        // the child0 coordinates are equal to the parent coordinates
-        // the child1 coordinates are incremented depending on the level value
-        if ( level & 0x1 ) // odd level => X binary tree
-        {
-            x0 = x;
-            y0 = y;
-            x1 = x + (1 << ((level-1)>>1));
-            y1 = y;
-        }    
-        else               // even level => Y binary tree
-        {
-            x0 = x;
-            y0 = y;
-            x1 = x;
-            y1 = y + (1 << ((level-1)>>1));
-        }
-
-        // initializes target node
-        node->taken    = 0;
-        node->level    = level;
-        node->parent   = parent;
-        node->child0   = lock->node[x0][y0][level-1];
-        node->child1   = lock->node[x1][y1][level-1];
-
-#if GIET_DEBUG_SBT_LOCK
-_nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT node[%d,%d,%d] : "
-      "parent = %x / childO = %x / child1 = %x\n",
-      px , py , pl , x , y , level , 
-      (unsigned int)node->parent , (unsigned int)node->child0 , (unsigned int)node->child1 );
-#endif
-
-        // recursive calls for children nodes
-        _sbt_lock_build( lock , x0 , y0 , level-1 , node );
-        _sbt_lock_build( lock , x1 , y1 , level-1 , node );
-    }
-
-}  // end _sbt_lock_build()
-
-//////////////////////////////////////////////////////////////////////////////////
-// This recursive function is used by the sbt_lock_acquire() function to
-// get the SBT lock: It tries to get each "partial" lock on the path from bottom
-// to top, using an atomic LL/SC, and starting from bottom.
-// It is blocking : it poll each "partial lock until it can be taken. 
-// The lock is finally obtained when all "partial" locks, at all levels are taken.
-//////////////////////////////////////////////////////////////////////////////////
-static void _sbt_lock_take( lock_node_t* node )
-{
-    // try to take "partial" lock
-    unsigned int* taken = &node->taken;
-
-    asm volatile ( "1945:                   \n"
-	               "lw   $2,    0(%0)       \n"   /* $2 <= lock current value         */
-	               "bnez $2,    1945b       \n"   /* retry if lock already taken      */
-                   "ll   $2,    0(%0)       \n"   /* ll_buffer <= lock current value  */
-                   "bnez $2,    1945b       \n"   /* retry if lock already taken      */
-                   "li   $3,    1           \n"   /* $3 <= argument for sc            */
-                   "sc   $3,    0(%0)       \n"   /* try to set lock                  */
-                   "beqz $3,    1945b       \n"   /* retry if sc failure              */
-                   :
-                   : "r"(taken)
-                   : "$2", "$3", "memory" );
-
-#if GIET_DEBUG_SBT_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
-_nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] get partial SBT lock[%d,%d,%d] : vaddr = %x\n",
-      px , py , pl , node->x , node->y , node->level , (unsigned int)node );
-#endif
-
-    // try to take the parent node lock until top is reached
-    if ( node->parent != NULL ) _sbt_lock_take( node->parent );
-
-} // end _sbt_lock_take()
-    
-
-/////////////////////////////////////////////////////////////////////////////////
-// This recursive function is used by the sbt_lock_release() function to
-// release the SBT lock: It reset all "partial" locks on the path from bottom 
-// to top, using a normal write, and starting from bottom.
-/////////////////////////////////////////////////////////////////////////////////
-static void _sbt_lock_free( lock_node_t* node )
-{
-    // reset "partial" lock
-    node->taken = 0;
-
-#if GIET_DEBUG_SBT_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
-_nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] release partial SBT lock[%d,%d,%d] : vaddr = %x\n",
-      px , py , pl , node->x , node->y , node->level , (unsigned int)node );
-#endif
-
-    // reset parent node until top is reached
-    if ( node->parent != NULL ) _sbt_lock_free( node->parent );
-
-} // end _sbt_lock_free()
-
-//////////////////////////////////////////////////////////////////////////////////
-// This external function initialises the distributed SBT lock.
-//////////////////////////////////////////////////////////////////////////////////
-void _sbt_lock_init( sbt_lock_t*  lock )
-{
-    unsigned int levels = 0;     // depth of the SBT (number of levels)
-
-    // compute SBT levels
-    if      ((X_SIZE == 1 ) && (Y_SIZE == 1 ))  levels = 1;
-    else if ((X_SIZE == 2 ) && (Y_SIZE == 1 ))  levels = 2;
-    else if ((X_SIZE == 2 ) && (Y_SIZE == 2 ))  levels = 3;
-    else if ((X_SIZE == 4 ) && (Y_SIZE == 2 ))  levels = 4;
-    else if ((X_SIZE == 4 ) && (Y_SIZE == 4 ))  levels = 5;
-    else if ((X_SIZE == 8 ) && (Y_SIZE == 4 ))  levels = 6;
-    else if ((X_SIZE == 8 ) && (Y_SIZE == 8 ))  levels = 7;
-    else if ((X_SIZE == 16) && (Y_SIZE == 8 ))  levels = 8;
-    else if ((X_SIZE == 16) && (Y_SIZE == 16))  levels = 9;
-    else
-    {
-        _nolock_printf("\n[GIET ERROR] _sbt_lock_init() :illegal X_SIZE/Y_SIZE \n");
-        _exit();
-    }
-
-#if GIET_DEBUG_SBT_LOCK
-unsigned int    gpid = _get_procid();
-unsigned int    px   = gpid >> (Y_WIDTH + P_WIDTH);
-unsigned int    py   = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int    pl   = gpid & ((1<<P_WIDTH)-1);
-_nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT lock %x : %d levels\n",
-               px , py , pl , (unsigned int)lock , levels );
-#endif
-
-    // allocates memory for the SBT nodes and initializes SBT nodes pointers array
-    // the actual number of SBT nodes in a cluster(x,y) depends on (x,y): 
-    // At least 1 node / at most 9 nodes per cluster.
-    unsigned int x;              // x coordinate for one SBT node
-    unsigned int y;              // y coordinate for one SBT node
-    unsigned int l;              // level for one SBT node
-    for ( x = 0 ; x < X_SIZE ; x++ )
-    {
-        for ( y = 0 ; y < Y_SIZE ; y++ )
-        {
-            for ( l = 0 ; l < levels ; l++ )             // level 0 nodes
-            {
-                
-                if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) ||
-                     ( (l == 1) && ((x&0x01) == 0) && ((y&0x00) == 0) ) ||
-                     ( (l == 2) && ((x&0x01) == 0) && ((y&0x01) == 0) ) ||
-                     ( (l == 3) && ((x&0x03) == 0) && ((y&0x01) == 0) ) ||
-                     ( (l == 4) && ((x&0x03) == 0) && ((y&0x03) == 0) ) ||
-                     ( (l == 5) && ((x&0x07) == 0) && ((y&0x03) == 0) ) ||
-                     ( (l == 6) && ((x&0x07) == 0) && ((y&0x07) == 0) ) ||
-                     ( (l == 7) && ((x&0x0F) == 0) && ((y&0x07) == 0) ) ||
-                     ( (l == 8) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) )
-                 {
-                     lock->node[x][y][l] = (lock_node_t*)_remote_malloc( sizeof(lock_node_t),
-                                                                         x, y );
-
-#if GIET_DEBUG_SBT_LOCK
-_nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] allocates SBT node[%d,%d,%d] : vaddr = %x\n",
-               px , py , pl , x , y , l , (unsigned int)lock->node[x][y][l] );
-#endif
-                 }
-            }
-        }
-    }
-            
-#if GIET_DEBUG_SBT_LOCK
-_nolock_printf("\n[DEBUG SBT_LOCK] SBT nodes initialisation starts\n"); 
-#endif
-
-    // recursively initialize all SBT nodes from root to bottom
-    _sbt_lock_build( lock,       // pointer on the SBT lock descriptor
-                     0,          // x coordinate
-                     0,          // y coordinate
-                     levels-1,   // level in SBT
-                     NULL );     // pointer on the parent node
-
-    asm volatile ("sync" ::: "memory");
-
-#if GIET_DEBUG_SBT_LOCK
-_nolock_printf("\n[DEBUG SBT_LOCK] SBT nodes initialisation completed\n"); 
-#endif
-
-} // end _sbt_lock_init()
-
-//////////////////////////////////////////////////////////////////////////////////
-// This external function get thes SBT lock.
-// Returns only when the lock has been taken. 
-/////////////////////////////////////////////////////////////////////////////////
-void _sbt_lock_acquire( sbt_lock_t*  lock )
-{
-    // get cluster coordinates
-    unsigned int gpid = _get_procid();
-    unsigned int x    = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
-    unsigned int y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-
-    // try to recursively take the "partial" locks (from bottom to top)
-    _sbt_lock_take( lock->node[x][y][0] );
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////
-// This external function releases the SBT lock.
-/////////////////////////////////////////////////////////////////////////////////
-void _sbt_lock_release( sbt_lock_t*  lock )
-{
-    // get cluster coordinates
-    unsigned int gpid = _get_procid();
-    unsigned int x    = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
-    unsigned int y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-
-    // recursively reset the "partial" locks (from bottom to top)
-    _sbt_lock_free( lock->node[x][y][0] );
-}
-
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// c-file-offsets:((innamespace . 0)(inline-open . 0))
-// indent-tabs-mode: nil
-// End:
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
-
Index: ft/giet_vm/giet_common/locks.h
===================================================================
--- /soft/giet_vm/giet_common/locks.h	(revision 494)
+++ 	(revision )
@@ -1,87 +1,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : locks.h
-// Date     : 01/12/2014
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The locks.c and locks.h files are part of the GIET-VM nano-kernel.
-// They define both atomic increment operations and three types of locks.
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef GIET_LOCKS_H
-#define GIET_LOCKS_H
-
-#include "hard_config.h"
-
-///////////////////////////////////////////////////////////////////////////////////
-//      Simple lock structure and access functions
-///////////////////////////////////////////////////////////////////////////////////
-
-typedef struct simple_lock_s
-{
-    unsigned int value;          // lock taken if non zero
-    unsigned int padding[15];    // for 64 bytes alignment
-} simple_lock_t;
-
-extern void _simple_lock_acquire( simple_lock_t* lock );
-
-extern void _simple_lock_release( simple_lock_t* lock );
-
-///////////////////////////////////////////////////////////////////////////////////
-//      Queuing lock structure and access functions
-///////////////////////////////////////////////////////////////////////////////////
-
-typedef struct spin_lock_s 
-{
-    unsigned int current;        // current slot index
-    unsigned int free;           // next free tiket index
-    unsigned int padding[14];    // for 64 bytes alignment
-} spin_lock_t;
-
-extern unsigned int _atomic_increment( unsigned int* ptr,
-                                       unsigned int  increment );
-
-extern void _spin_lock_init( spin_lock_t* lock );
-
-extern void _spin_lock_acquire( spin_lock_t* lock );
-
-extern void _spin_lock_release( spin_lock_t* lock );
-
-//////////////////////////////////////////////////////////////////////////////////
-//      SBT lock structures and access functions
-//////////////////////////////////////////////////////////////////////////////////
-
-typedef struct lock_node_s 
-{
-    unsigned int            taken;           // lock taken if non zero
-    unsigned int            level;           // hierarchical level (0 is bottom)
-    struct lock_node_s*     parent;          // pointer on parent node (NULL for root)
-    struct lock_node_s*     child0;          // pointer on children node
-    struct lock_node_s*     child1;          // pointer on children node
-    unsigned int            x;               // cluster x coordinate        
-    unsigned int            y;               // cluster y coordinate           
-    unsigned int            padding[9];      // for 64 bytes alignment         
-} lock_node_t;
-
-typedef struct sbt_lock_s 
-{
-    unsigned int    ntasks;                   // total number of expected tasks
-    lock_node_t*    node[X_SIZE][Y_SIZE][9];  // array of pointers on SBT nodes 
-} sbt_lock_t;
-
-extern void _sbt_lock_init( sbt_lock_t*   lock );
-
-extern void _sbt_lock_acquire( sbt_lock_t*  lock );
-
-extern void _sbt_lock_release( sbt_lock_t*  lock );
-
-#endif
-
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// c-file-offsets:((innamespace . 0)(inline-open . 0))
-// indent-tabs-mode: nil
-// End:
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
-
Index: /soft/giet_vm/giet_common/tty0.c
===================================================================
--- /soft/giet_vm/giet_common/tty0.c	(revision 494)
+++ /soft/giet_vm/giet_common/tty0.c	(revision 495)
@@ -13,5 +13,20 @@
 #include <tty_driver.h>
 #include <utils.h>
-#include <locks.h>
+#include <kernel_locks.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// The global variable tty0_boot_mode define the type of lock used,
+// and must be defined in both kernel_init.c and boot.c files.
+// - the boot code must use a spin_lock because the kernel heap is not set.
+// - the kernel code can use a sqt_lock when the kernel heap is set. 
+/////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int  _tty0_boot_mode;
+
+__attribute__((section(".kdata")))
+sqt_lock_t           _tty0_sqt_lock  __attribute__((aligned(64)));  
+
+__attribute__((section(".kdata")))
+spin_lock_t          _tty0_spin_lock  __attribute__((aligned(64)));
 
 //////////////////////////////////////////////
@@ -20,9 +35,19 @@
 {
     unsigned int n;
+    unsigned int k;
 
     for ( n = 0 ; n < nbytes ; n++ ) 
     {
-        // return error if TTY_TX buffer full 
-        if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) return 1;
+        // test TTY_TX buffer full 
+        if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) // buffer full
+        {
+            // retry if full 
+            for( k = 0 ; k < 10000 ; k++ )
+            {
+                if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) == 0) break;
+            }
+            // return error if full after 10000 retry
+            return 1;
+        }
 
         // write one byte
@@ -240,5 +265,5 @@
         unsigned int lpid       = procid & ((1<<P_WIDTH)-1);
         _puts("\n\n[GIET ERROR] in _printf() for processor[");
-        _putd( x );
+        _putd( x );  
         _puts(",");
         _putd( y );
@@ -268,5 +293,6 @@
     // get TTY0 lock
     _it_disable( &save_sr );
-    _sbt_lock_acquire( &_tty_tx_lock[0] );
+    if ( _tty0_boot_mode ) _spin_lock_acquire( &_tty0_spin_lock );
+    else                   _sqt_lock_acquire( &_tty0_sqt_lock );
 
     va_start( args , format );
@@ -275,5 +301,6 @@
 
     // release TTY0 lock
-    _sbt_lock_release( &_tty_tx_lock[0] );
+    if ( _tty0_boot_mode ) _spin_lock_release( &_tty0_spin_lock );
+    else                   _sqt_lock_release( &_tty0_sqt_lock );
     _it_restore( &save_sr );
 }
Index: /soft/giet_vm/giet_common/utils.c
===================================================================
--- /soft/giet_vm/giet_common/utils.c	(revision 494)
+++ /soft/giet_vm/giet_common/utils.c	(revision 495)
@@ -814,4 +814,41 @@
 
 
+/////////////////////////////////////////////
+void _get_sqt_footprint( unsigned int* width,
+                         unsigned int* heigth,
+                         unsigned int* levels )
+{
+    mapping_header_t*   header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
+    mapping_cluster_t*  cluster = _get_cluster_base(header);
+
+    unsigned int x;
+    unsigned int y;
+    unsigned int cid;
+    unsigned int w = 0;
+    unsigned int h = 0;
+
+    // scan all clusters to compute SQT footprint (w,h)
+    for ( x = 0 ; x < X_SIZE ; x++ )
+    {
+        for ( y = 0 ; y < Y_SIZE ; y++ )
+        {
+            cid = x * Y_SIZE + y;
+            if ( cluster[cid].procs )  // cluster contains processors
+            {
+                if ( x > w ) w = x;
+                if ( y > h ) h = y;
+            }
+        }
+    }           
+    *width  = w + 1;
+    *heigth = h + 1;
+    
+    // compute SQT levels
+    unsigned int z = (h > w) ? h : w;
+    *levels = (z < 1) ? 1 : (z < 2) ? 2 : (z < 4) ? 3 : (z < 8) ? 4 : 5;
+}
+     
+
+
 ///////////////////////////////////////////////////////////////////////////////////
 //   Required by GCC
Index: /soft/giet_vm/giet_common/utils.h
===================================================================
--- /soft/giet_vm/giet_common/utils.h	(revision 494)
+++ /soft/giet_vm/giet_common/utils.h	(revision 495)
@@ -191,4 +191,8 @@
                                             unsigned int buf_size );
 
+extern void         _get_sqt_footprint( unsigned int* width,
+                                        unsigned int* heigth,
+                                        unsigned int* levels );
+
 ///////////////////////////////////////////////////////////////////////////////////
 //     Required by GCC
Index: /soft/giet_vm/giet_common/vmem.c
===================================================================
--- /soft/giet_vm/giet_common/vmem.c	(revision 494)
+++ /soft/giet_vm/giet_common/vmem.c	(revision 495)
@@ -11,5 +11,5 @@
 #include <giet_config.h>
 
-//////////////////////////////////////////////////
+/////////////////////////////////////////
 void _v2p_translate( page_table_t*  ptab,
                      unsigned int   vpn,
@@ -36,5 +36,7 @@
     if ( (pte1 & PTE_V) == 0 )
     {
-        _puts("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n");
+        _printf("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n"
+                "  vpn = %x / ptab = %x / pte1_vaddr = %x / pte1_value = %x\n",
+                vpn , (unsigned int)ptab, &(ptab->pt1[ix1]) , pte1 );
         _exit();
     }
@@ -50,7 +52,9 @@
     {
 
-        // get physical addresses of pte2 (two 32 bits words)
-        ptba       = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12;
+        // get physical addresses of pte2
+        ptba       = ((unsigned long long)(pte1 & 0x0FFFFFFF)) << 12;
         pte2_paddr = ptba + 8*ix2;
+
+        // split physical address in two 32 bits words
         pte2_lsb   = (unsigned int) pte2_paddr;
         pte2_msb   = (unsigned int) (pte2_paddr >> 32);
@@ -87,5 +91,8 @@
         if ( (flags_value & PTE_V) == 0 )
         {
-            _puts("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n");
+            _printf("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n"
+                    "  vpn = %x / ptab = %x / pte1_value = %x\n"
+                    "  pte2_paddr = %l / ppn = %x / flags = %x\n",
+                    vpn , ptab , pte1 , pte2_paddr ,  ppn_value , flags_value );
             _exit();
         }
