Index: soft/giet_vm/giet_libs/malloc.h
===================================================================
--- soft/giet_vm/giet_libs/malloc.h	(revision 460)
+++ soft/giet_vm/giet_libs/malloc.h	(revision 461)
@@ -61,7 +61,9 @@
 
 #include "giet_config.h"
-#include "spin_lock.h"
+#include "user_lock.h"
 
-// There is the magic number indicating that heap(x,y) has been initialized.
+////////////////////////////////////////////////////////////////////////////////
+//  magic number indicating that heap(x,y) has been initialized.
+////////////////////////////////////////////////////////////////////////////////
 
 #define HEAP_INITIALIZED    0xDEADBEEF
@@ -81,5 +83,5 @@
     unsigned int   alloc_base;      // alloc[] array base address
     unsigned int   alloc_size;      // alloc[] array size (bytes)
-    giet_lock_t    lock;            // lock protecting exclusive access
+    user_lock_t    lock;            // lock protecting exclusive access
     unsigned int   free[32];        // array of base addresses of free blocks 
                                     // (address of first block of a given size)
Index: soft/giet_vm/giet_libs/malloc_private.h
===================================================================
--- soft/giet_vm/giet_libs/malloc_private.h	(revision 460)
+++ 	(revision )
@@ -1,38 +1,0 @@
-////////////////////////////////////////////////////////////////////////////
-// File     : malloc_private.h
-// Date     : 05/03/2013
-// Author   : Jean-Baptiste BrÃ©jon
-// Copyright (c) UPMC-LIP6
-////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MALLOC_PRIVATE_H_
-#define _MALLOC_PRIVATE_H_
-
-
-typedef struct heap_linked_list {
-    struct heap_linked_list * next;
-    unsigned int chunk_length;
-} heap_ll;
-
-void insert_in_remote_free_list(unsigned int remote_owner_id, unsigned int block_base, unsigned int block_length);
-heap_ll * pop_remote_free_list(heap_ll ** head);
-heap_ll * pop_ptr(void);
-void update_chunk_list(unsigned int block_base, unsigned int block_length);
-
-#if MALLOC_SELECTED == 1 || MALLOC_SELECTED == 2
-    static heap_ll * get_prev_fit_chunk(unsigned int size);
-#else
-    int get_prev_fit_chunk(unsigned int size);
-#endif
-
-
-#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_libs/mwmr_channel.c
===================================================================
--- soft/giet_vm/giet_libs/mwmr_channel.c	(revision 460)
+++ soft/giet_vm/giet_libs/mwmr_channel.c	(revision 461)
@@ -6,14 +6,25 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-#include <mwmr_channel.h>
-#include <stdio.h>
+#include "mwmr_channel.h"
+#include "giet_config.h"
+#include "stdio.h"
+#include "user_lock.h"
 
 //////////////////////////////////////
 void mwmr_init( mwmr_channel_t*  mwmr,
-                unsigned int     width,      // numer of words per item
-                unsigned int     items )     // max number of items
-{
-    if ( ((items * width)) > 1018 )
-    giet_exit("[MWMR ERROR] in mwmr_init() : buffer size larger than 4072 bytes\n");
+                unsigned int*    buffer,     // buffer base address
+                unsigned int     width,      // number of words per item
+                unsigned int     nitems )    // max number of items
+{
+
+#if GIET_DEBUG_MWMR
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] initialises fifo %x / "
+                " buffer = %x / width = %d / nitems = %d\n",
+                x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, width, nitems );
+#endif
 
     mwmr->ptw   = 0;
@@ -21,49 +32,25 @@
     mwmr->sts   = 0;
     mwmr->width = width;
-    mwmr->depth = width * items;
-    mwmr->lock  = 0;
-
-#if GIET_DEBUG_MWMR
-giet_shr_printf("[MWMR DEBUG] Initialise MWMR channel\n"
-                " - vbase = %x\n"
-                " - width = %d\n"
-                " - depth = %d\n",
-                (unsigned int)mwmr, width, items );
-#endif
+    mwmr->depth = width * nitems;
+    mwmr->data  = buffer;
+
+    lock_init( &mwmr->lock );
 }
-
-
-///////////////////////////////////////////////////
-static void mwmr_lock_acquire( unsigned int* lock ) 
-{
-    register unsigned int*  plock = lock;
-    register unsigned int   delay = 100;
-    asm volatile (
-            "1:                               \n"
-            "ll   $2,    0(%0)                \n" /* $2 <= lock current value */
-            "bnez $2,    2f                   \n" /* retry after delay if lock busy */
-            "li   $3,    1                    \n" /* $3 <= argument for sc */
-            "sc   $3,    0(%0)                \n" /* try to get lock */
-            "bnez $3,    3f                   \n" /* exit if atomic */
-            "2:                               \n"
-            "move $4,    %1                   \n" /* $4 <= delay */
-            "4:                               \n"
-            "beqz $4,    4b                   \n" /* test end delay */
-            "addi $4,    $4,  -1              \n" /* $4 <= $4 - 1 */
-            "j           1b                   \n" /* retry ll */
-            "nop                              \n"
-            "3:                               \n"
-            :
-            :"r"(plock), "r"(delay)
-            :"$2", "$3", "$4");
-} 
 
 
 ///////////////////////////////////////////////////
 unsigned int nb_mwmr_write( mwmr_channel_t * mwmr, 
-                            unsigned int * buffer, 
-                            unsigned int nitems)
-{
-    unsigned int x;
+                            unsigned int *   buffer, 
+                            unsigned int     items)
+{
+
+#if GIET_DEBUG_MWMR
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+#endif
+
+    unsigned int n;
     unsigned int spaces; // number of empty slots (in words)
     unsigned int nwords; // requested transfer length (in words)
@@ -73,22 +60,22 @@
     unsigned int ptw;    // channel ptw
 
-    if (nitems == 0) return 0;
+    if (items == 0) return 0;
 
     // get the lock
-    mwmr_lock_acquire(&mwmr->lock);
+    lock_acquire( &mwmr->lock );
 
     // access fifo status
-    depth = mwmr->depth;
-    width = mwmr->width;
-    sts = mwmr->sts;
-    ptw = mwmr->ptw;
+    depth  = mwmr->depth;
+    width  = mwmr->width;
+    sts    = mwmr->sts;
+    ptw    = mwmr->ptw;
     spaces = depth - sts;
-    nwords = width * nitems;
-
-    if (spaces >= nwords) // transfer nitems, release lock and return 
+    nwords = width * items;
+
+    if (spaces >= nwords) // transfer items, release lock and return 
     { 
-        for (x = 0; x < nwords; x++) 
-        {
-            mwmr->data[ptw] = buffer[x];
+        for (n = 0; n < nwords; n++) 
+        {
+            mwmr->data[ptw] = buffer[n];
             if ((ptw + 1) == depth)  ptw = 0; 
             else                     ptw = ptw + 1;
@@ -96,10 +83,16 @@
         mwmr->sts = mwmr->sts + nwords;
         mwmr->ptw = ptw;
-        mwmr->lock = 0;
-        return nitems;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+        lock_release( &mwmr->lock );
+        return items;
     }
     else if (spaces < width) // release lock and return 
     {
-        mwmr->lock = 0;
+        lock_release( &mwmr->lock );
         return 0;
     }
@@ -107,7 +100,7 @@
     {
         nwords = (spaces / width) * width;    // integer number of items
-        for (x = 0; x < nwords; x++) 
-        {
-            mwmr->data[ptw] = buffer[x];
+        for (n = 0; n < nwords; n++) 
+        {
+            mwmr->data[ptw] = buffer[n];
             if ((ptw + 1) == depth) ptw = 0;
             else                    ptw = ptw + 1;
@@ -115,5 +108,11 @@
         mwmr->sts = sts + nwords;
         mwmr->ptw = ptw;
-        mwmr->lock = 0;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+        lock_release( &mwmr->lock );
         return (nwords / width);
     }
@@ -125,30 +124,38 @@
 unsigned int nb_mwmr_read( mwmr_channel_t * mwmr, 
                            unsigned int *   buffer,
-                           unsigned int     nitems) 
-{
-    unsigned int x;
-    unsigned int nwords; // requested transfer length (in words)
-    unsigned int depth;  // channel depth (in words)
-    unsigned int width;  // channel width (in words)
-    unsigned int sts;    // channel sts
-    unsigned int ptr;    // channel ptr
-
-    if (nitems == 0) return 0;
+                           unsigned int     items) 
+{
+
+#if GIET_DEBUG_MWMR
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+#endif
+
+    unsigned int n;
+    unsigned int nwords; // requested transfer length (words)
+    unsigned int depth;  // channel depth (words)
+    unsigned int width;  // channel width (words)
+    unsigned int sts;    // channel sts   (words)
+    unsigned int ptr;    // channel ptr   (words)
+
+    if (items == 0) return 0;
 
     // get the lock
-    mwmr_lock_acquire(&mwmr->lock);
+    lock_acquire( &mwmr->lock );
 
     // access fifo status
-    depth = mwmr->depth;
-    width = mwmr->width;
-    sts = mwmr->sts;
-    ptr = mwmr->ptr;
-    nwords = width * nitems;
-
-    if (sts >= nwords) // transfer nitems, release lock and return 
-    {
-        for (x = 0; x < nwords; x++) 
-        {
-            buffer[x] = mwmr->data[ptr];
+    depth  = mwmr->depth;
+    width  = mwmr->width;
+    sts    = mwmr->sts;
+    ptr    = mwmr->ptr;
+    nwords = width * items;
+
+    if (sts >= nwords) // transfer items, release lock and return 
+    {
+        for (n = 0; n < nwords; n++) 
+        {
+            buffer[n] = mwmr->data[ptr];
             if ((ptr + 1) == depth)  ptr = 0;
             else                     ptr = ptr + 1;
@@ -156,10 +163,22 @@
         mwmr->sts = mwmr->sts - nwords;
         mwmr->ptr = ptr;
-        mwmr->lock = 0;
-        return nitems;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+        lock_release( &mwmr->lock );
+        return items;
     }
     else if (sts < width) // release lock and return 
     {
-        mwmr->lock = 0;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read nothing in fifo %x : sts = %d\n",
+                x, y, lpid, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+        lock_release( &mwmr->lock );
         return 0;
     }
@@ -167,7 +186,7 @@
     {
         nwords = (sts / width) * width; // integer number of items
-        for (x = 0 ; x < nwords ; x++) 
-        {
-            buffer[x] = mwmr->data[ptr];
+        for (n = 0 ; n < nwords ; n++) 
+        {
+            buffer[n] = mwmr->data[ptr];
             if ((ptr + 1) == depth)  ptr = 0;
             else                     ptr = ptr + 1;
@@ -175,5 +194,11 @@
         mwmr->sts = sts - nwords;
         mwmr->ptr = ptr;
-        mwmr->lock = 0;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+        lock_release( &mwmr->lock );
         return (nwords / width);
     }
@@ -185,7 +210,15 @@
 void mwmr_write( mwmr_channel_t * mwmr, 
                  unsigned int *   buffer, 
-                 unsigned int     nitems ) 
-{
-    unsigned int x;
+                 unsigned int     items ) 
+{
+
+#if GIET_DEBUG_MWMR
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+#endif
+
+    unsigned int n;
     unsigned int spaces; // number of empty slots (in words)
     unsigned int nwords; // requested transfer length (in words)
@@ -195,10 +228,10 @@
     unsigned int ptw;    // channel ptw
 
-    if (nitems == 0)  return;
+    if (items == 0)  return;
 
     while (1) 
     {
         // get the lock
-        mwmr_lock_acquire(&mwmr->lock);
+        lock_acquire( &mwmr->lock );
 
         // compute spaces and nwords
@@ -208,11 +241,11 @@
         ptw  = mwmr->ptw;
         spaces = depth - sts;
-        nwords = width * nitems;
+        nwords = width * items;
 
         if (spaces >= nwords) // write nwords, release lock and return
         {
-            for (x = 0; x < nwords; x++) 
+            for (n = 0; n < nwords; n++) 
             {
-                mwmr->data[ptw] = buffer[x];
+                mwmr->data[ptw] = buffer[n];
                 if ((ptw + 1) == depth)  ptw = 0; 
                 else                     ptw = ptw + 1;
@@ -220,17 +253,23 @@
             mwmr->ptw = ptw;
             mwmr->sts = sts + nwords;
-            mwmr->lock = 0;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+            lock_release( &mwmr->lock );
             return;
         }
-        else if (spaces < width) // release lock and deschedule           
-        {
-            mwmr->lock = 0;
-        }
-        else // write as many items as possible, release lock and deschedule
+        else if (spaces < width) // release lock and retry           
+        {
+            lock_release( &mwmr->lock );
+        }
+        else // write as many items as possible, release lock and retry
         {
             nwords = (spaces / width) * width;  // integer number of items
-            for (x = 0; x < nwords; x++) 
+            for (n = 0; n < nwords; n++) 
             {
-                mwmr->data[ptw] = buffer[x];
+                mwmr->data[ptw] = buffer[n];
                 if ((ptw + 1) == depth)  ptw = 0; 
                 else                     ptw = ptw + 1;
@@ -239,8 +278,16 @@
             mwmr->ptw = ptw;
             buffer = buffer + nwords;
-            nitems = nitems - (nwords/width);
-            mwmr->lock = 0;
-        }
-        giet_context_switch();
+            items = items - (nwords/width);
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+            lock_release( &mwmr->lock );
+        }
+
+        // we could deschedule before retry...
+        // giet_context_switch();
     }
 } // end mwmr_write()
@@ -250,7 +297,15 @@
 void mwmr_read( mwmr_channel_t * mwmr, 
                 unsigned int *   buffer, 
-                unsigned int     nitems) 
-{
-    unsigned int x;
+                unsigned int     items) 
+{
+
+#if GIET_DEBUG_MWMR
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+#endif
+
+    unsigned int n;
     unsigned int nwords; // requested transfer length (in words)
     unsigned int depth;  // channel depth (in words)
@@ -259,23 +314,23 @@
     unsigned int ptr;    // channel ptr
 
-    if (nitems == 0) return;
+    if (items == 0) return;
 
     while (1) 
     {
         // get the lock
-        mwmr_lock_acquire(&mwmr->lock);
+        lock_acquire( &mwmr->lock );
 
         // compute nwords
-        depth = mwmr->depth;
-        width = mwmr->width;
-        sts = mwmr->sts;
-        ptr = mwmr->ptr;
-        nwords = width * nitems;
+        depth  = mwmr->depth;
+        width  = mwmr->width;
+        sts    = mwmr->sts;
+        ptr    = mwmr->ptr;
+        nwords = width * items;
 
         if (sts >= nwords) // read nwords, release lock and return
         {
-            for (x = 0; x < nwords; x++) 
+            for (n = 0; n < nwords; n++) 
             {
-                buffer[x] = mwmr->data[ptr];
+                buffer[n] = mwmr->data[ptr];
                 if ((ptr + 1) == depth)  ptr = 0;
                 else                     ptr = ptr + 1;
@@ -283,17 +338,23 @@
             mwmr->sts = mwmr->sts - nwords;
             mwmr->ptr = ptr;
-            mwmr->lock = 0;
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+            lock_release( &mwmr->lock );
             return;
         }
-        else if (sts < width) // release lock and deschedule
-        {
-            mwmr->lock = 0;
-        }
-        else // read as many items as possible, release lock and deschedule
+        else if (sts < width) // release lock and retry
+        {
+            lock_release( &mwmr->lock );
+        }
+        else // read as many items as possible, release lock and retry
         {   
             nwords = (sts / width) * width; // integer number of items
-            for (x = 0; x < nwords; x++) 
+            for (n = 0; n < nwords; n++) 
             {
-                buffer[x] = mwmr->data[ptr];
+                buffer[n] = mwmr->data[ptr];
                 if ((ptr + 1) == depth) ptr = 0;
                 else                    ptr = ptr + 1;
@@ -302,8 +363,16 @@
             mwmr->ptr = ptr;
             buffer = buffer + nwords;
-            nitems = nitems - (nwords/width);
-            mwmr->lock = 0;
-        }
-        giet_context_switch();
+            items = items - (nwords/width);
+
+#if GIET_DEBUG_MWMR
+giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
+                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
+#endif
+
+            lock_release( &mwmr->lock );
+        }
+
+        // we could deschedule before retry...
+        // giet_context_switch();
     }
 } // end mwmr_read() 
Index: soft/giet_vm/giet_libs/mwmr_channel.h
===================================================================
--- soft/giet_vm/giet_libs/mwmr_channel.h	(revision 460)
+++ soft/giet_vm/giet_libs/mwmr_channel.h	(revision 461)
@@ -11,11 +11,6 @@
 // 
 // The mwmr_read() and mwmr_write() functions do not require a system call.
-// The channel itself must have been allocated in a non cacheable segment,
+// The channel must have been allocated in a non cacheable segment,
 // if the platform does not provide hardware cache coherence.
-//
-// WARNING : ALL MWMR channels must be defined in the mapping, 
-// to be initialised by the GIET in the boot phase.
-// The vobj_get_vbase() system call (defined in stdio.c and stdio.h files)
-// can be used to get the virtual base address of the channel from it's name.
 //
 // An MWMR transaction transfer an integer number of items, and an item is
@@ -27,10 +22,11 @@
 //
 // Both the mwmr_read() and mwmr_write() functions are blocking functions. 
-// A private lock provides exclusive access to the MWMR channel, that can have
-// a variable number of producers and a variable number of consumers.
+// A private file_lock provides exclusive access to the MWMR channel.
 ///////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _MWMR_CHANNEL_H_
 #define _MWMR_CHANNEL_H_
+
+#include "user_lock.h"
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -42,11 +38,11 @@
 typedef struct mwmr_channel_s 
 {
-    unsigned int ptr;        // index of the first valid data word
-    unsigned int ptw;        // index of the first empty slot 
-    unsigned int sts;        // number of words available
-    unsigned int lock;       // exclusive access lock
-    unsigned int depth;      // max number of words in the channel
-    unsigned int width;      // number of words in an item      
-    unsigned int data[1018]; // circular buffer
+    user_lock_t    lock;       // exclusive access lock
+    unsigned int   ptr;        // index of the first valid data word
+    unsigned int   ptw;        // index of the first empty slot 
+    unsigned int   sts;        // number of words available
+    unsigned int   depth;      // max number of words in the channel
+    unsigned int   width;      // number of words in an item      
+    unsigned int*  data;       // circular buffer base address
 } mwmr_channel_t;
 
@@ -56,22 +52,23 @@
 
 void mwmr_init(  mwmr_channel_t* mwmr,
+                 unsigned int*   buffer,    // data buffer base address
                  unsigned int    width,     // number of words per item
-                 unsigned int    items );   // max number of items
+                 unsigned int    nitems );  // max number of items
 
-void mwmr_write( mwmr_channel_t* mwmr, 
-                 unsigned int*   buffer,    // user buffer vbase address
-                 unsigned int    nitems );  // number of items to transfer
+void mwmr_read(  mwmr_channel_t* mwmr,
+                 unsigned int*   buffer,
+                 unsigned int    items );
 
-void mwmr_write( mwmr_channel_t* mwmr, 
-                 unsigned int*   buffer,    // user buffer vbase address
-                 unsigned int    nitems );  // number of items to transfer
+void mwmr_write( mwmr_channel_t* mwmr,
+                 unsigned int*   buffer,
+                 unsigned int    items );
 
 unsigned int nb_mwmr_read ( mwmr_channel_t * mwmr,
                             unsigned int * buffer,
-                            unsigned int nitems );
+                            unsigned int items );
 
 unsigned int nb_mwmr_write( mwmr_channel_t * mwmr,
                             unsigned int * buffer,
-                            unsigned int nitems );
+                            unsigned int items );
 
 #endif
Index: soft/giet_vm/giet_libs/remote_malloc.c
===================================================================
--- soft/giet_vm/giet_libs/remote_malloc.c	(revision 460)
+++ 	(revision )
@@ -1,162 +1,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// File     : remote_malloc.c         
-// Date     : 01/08/2014
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-
-#include "giet_config.h"
-#include "hard_config.h"
-#include "remote_malloc.h"
-#include "stdio.h"
-#include "spin_lock.h"
-
-///////////////////////////////////////////////////////////////////////////////////
-// Global variables describing allocators: one heap per cluster.
-// For each cluster, cur[x][y] is the virtual adrress of first free byte 
-// in heap, max[x][y] is the virtual address of first forbidden byte on top
-// of heap, and lock[x][y] protect exclusive access to heap[x][y].
-///////////////////////////////////////////////////////////////////////////////////
-
-unsigned int remote_malloc_cur[X_SIZE][Y_SIZE] = {[0 ... X_SIZE-1][0 ... Y_SIZE-1] = 0};
-
-unsigned int remote_malloc_max[X_SIZE][Y_SIZE] = {[0 ... X_SIZE-1][0 ... Y_SIZE-1] = 0};
-
-giet_lock_t  remote_malloc_lock[X_SIZE][Y_SIZE] __attribute__((aligned(512)));
-
-///////////////////////////////////////////////////////////////////////////////////
-// This function returne the virtual base address of the allocated block.
-// - length is the block length (number of bytes)
-// - align is the alignment constrain (vbase multiple of Ox1 << align).
-// - If (x < X_SIZE) and (y < Y_SIZE), it uses the heap defined in cluster(x,y).
-// - It uses the heap in cluster running the calling task if x oy y too large.
-// The calling task exit with an error message if the request cannot be satisfied.
-///////////////////////////////////////////////////////////////////////////////////
-void* remote_malloc( unsigned int length,
-                     unsigned int align,
-                     unsigned int x,
-                     unsigned int y )
-{
-    // checking alignment constraint
-    if ( align > 31  ) 
-    {
-        giet_exit(" in remote_malloc(), align constraint > 31\n");
-    }
-
-    // checking requested length
-    if ( length == 0 ) 
-    {
-        giet_exit(" in remote_malloc(), requested length = 0\n");
-    }
-
-unsigned int gpid    = giet_procid();
-unsigned int cluster = gpid >> P_WIDTH;
-unsigned int proc_x  = cluster >> Y_WIDTH;
-unsigned int proc_y  = cluster & ((1<<Y_WIDTH)-1);
-unsigned int lpid    = gpid & ((1<<P_WIDTH)-1);
-
-#if GIET_DEBUG_MALLOC
-giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] enters remote_malloc()"
-                " : length = %x / align = %x for heap(%d,%d)\n",
-                proc_x, proc_y, lpid, length, (1<<align), x, y );
-#endif
-
-
-    unsigned int heap_x;        // heap x coordinate
-    unsigned int heap_y;        // heap y coordibnate
-    unsigned int heap_base;     // heap base address
-    unsigned int heap_length;   // heap length
-    unsigned int vbase;         // virtual address to be returned
-
-    unsigned int quantum = 1 << align;
-
-    // compute cluster coordinates
-    if ( (x < X_SIZE) && (y < Y_SIZE) )
-    {
-        heap_x = x;
-        heap_y = y;
-    }
-    else
-    {
-        heap_x = proc_x;
-        heap_y = proc_y;
-    }
-
-    // get heap vbase and length if allocator[x][y] not initialised yet
-    if ( remote_malloc_max[heap_x][heap_y] == 0 )
-    {
-        giet_heap_info( &heap_base,
-                        &heap_length,
-                        heap_x, 
-                        heap_y );
-
-        if ( heap_length == 0 ) 
-        {
-            giet_exit("in remote_malloc(): heap length = 0\n");
-        }
-
-        remote_malloc_cur[heap_x][heap_y] = heap_base;
-        remote_malloc_max[heap_x][heap_y] = heap_base + heap_length;
-
-        // initialise lock
-        lock_release( &remote_malloc_lock[heap_x][heap_y] );
-
-#if GIET_DEBUG_MALLOC
-giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] initializes heap(%d,%d)\n"
-                " - heap_base        = %x\n"
-                " - heap_size        = %x\n",
-                proc_x, proc_y, lpid, heap_x, heap_y,
-                heap_base, heap_length );
-#endif
-
-    }
-
-    // take the lock
-    lock_acquire( &remote_malloc_lock[heap_x][heap_y] );
-
-#if GIET_DEBUG_MALLOC
-giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] takes lock for heap(%d,%d)\n",
-                proc_x, proc_y, lpid, heap_x, heap_y );
-#endif
-
-    // compute vbase
-    vbase = remote_malloc_cur[heap_x][heap_y];
-    if ( vbase % quantum )  vbase = ((vbase / quantum) + 1 ) * quantum; 
-
-#if GIET_DEBUG_MALLOC
-giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] allocate vaddr = %x in heap(%d,%d)\n",
-                proc_x, proc_y, lpid, vbase, heap_x, heap_y );
-#endif
-
-    // check overflow
-    if ( (vbase + length) > remote_malloc_max[heap_x][heap_y] )
-    {
-        giet_exit("in remote_malloc(), heap overflow\n");
-    }
-
-    // update heap pointer
-    remote_malloc_cur[heap_x][heap_y] = vbase + length;
-
-    // release the lock
-    lock_release( &remote_malloc_lock[heap_x][heap_y] );
-
-#if GIET_DEBUG_MALLOC
-giet_shr_printf("\n[DEBUG MALLOC] Processor[%d,%d,%d] releases lock for heap(%d,%d)\n",
-                proc_x, proc_y, lpid, heap_x, heap_y );
-#endif
-
-    return (void*)vbase;
-}  // end remote_malloc()
-
-
-
-// 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_libs/remote_malloc.h
===================================================================
--- soft/giet_vm/giet_libs/remote_malloc.h	(revision 460)
+++ 	(revision )
@@ -1,51 +1,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// File     : remote_malloc.h         
-// Date     : 01/08/2014
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The remote_malloc.c and remote_malloc.h files are part of the GIET nano-kernel.
-// These files define a very simple user-level memory allocator:
-// - There is no free() : an allocated memory block is never released.
-// - For each vspace, it can exist one heap[(x,y) per cluster, and the user
-//   can explicitely select the target cluster(x,y).
-// - Each heap(x,y) must be declared as a specific vobj in the mapping.
-// - There is no constraint on the requested block size as long as it fit
-//   in the selected heap.
-// - For each requested block, the user can specify an alignment constraint.
-///////////////////////////////////////////////////////////////////////////////////
-// IMPLEMENTATION NOTE
-// As the distributed heap(x,y) are global variables that can be accessed 
-// concurrently by all tasks of a given vspace, each heap(x,y) is protected
-// by a specific lock (defined in remote_malloc.c file. 
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef _REMOTE_MALLOC_H
-#define _REMOTE_MALLOC_H
-
-///////////////////////////////////////////////////////////////////////////////////
-// This function returne the virtual base address of the allocated block.
-// - length is the block length (number of bytes).
-// - align is the alignment constrain (vbase multiple of Ox1 << align).
-// - If (x < X_SIZE) and (y < Y_SIZE), it uses the heap in cluster(x,y).
-// - It uses the heap in cluster running the calling task, if x or y are too large.
-// The calling task exit with an error message if the request cannot be satisfied.
-///////////////////////////////////////////////////////////////////////////////////
-extern void* remote_malloc( unsigned int length,
-                            unsigned int align,
-                            unsigned int x,
-                            unsigned int y );
-
-#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_libs/spin_lock.c
===================================================================
--- soft/giet_vm/giet_libs/spin_lock.c	(revision 460)
+++ 	(revision )
@@ -1,67 +1,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// File     : spin_lock.c         
-// Date     : 01/04/2012
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-
-#include <spin_lock.h>
-#include <stdio.h>
-
-///////////////////////////////////////////////////////////////////////////////////
-// lock_acquire()
-// This blocking function returns only when the lock has been taken.
-// If the lock is already taken a random delay is introduced before retry.
-///////////////////////////////////////////////////////////////////////////////////
-void lock_acquire(giet_lock_t * lock) 
-{
-    unsigned int * plock = &lock->value;
-    unsigned int delay = giet_rand();
-
-    if (delay == 0) delay++;
-
-    asm volatile (
-            "giet_lock_try:              \n"
-            "ll   $2,    0(%0)           \n" /* $2 <= _ioc_lock current value */
-            "bnez $2,    giet_lock_delay \n" /* delay if _ioc_lock already taken */
-            "li   $3,    1               \n" /* $3 <= argument for sc */
-            "sc   $3,    0(%0)           \n" /* try to set _ioc_lock */
-            "bnez $3,    giet_lock_ok    \n" /* exit if atomic */
-
-            "giet_lock_delay:            \n"
-            "move $4,    %1              \n" /* $4 <= delay */
-
-            "giet_lock_loop:             \n"
-            "addi $4,    $4,    -1       \n" /* $4 <= $4 - 1 */
-            "bnez $4,    giet_lock_loop  \n" /* test end delay */
-            "nop                         \n"
-            "j           giet_lock_try   \n" /* retry */
-            "nop                         \n"
-
-            "giet_lock_ok:               \n"
-            :
-            :"r"(plock), "r"(delay)
-            :"$2", "$3", "$4");
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// lock_release()
-//////////////////////////////////////////////////////////////////////////////
-void lock_release(giet_lock_t * lock) 
-{
-    unsigned int * plock = &lock->value;
-
-    asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model 
-    *plock = 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_libs/spin_lock.h
===================================================================
--- soft/giet_vm/giet_libs/spin_lock.h	(revision 460)
+++ 	(revision )
@@ -1,49 +1,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// File     : spin_lock.h         
-// Date     : 01/04/2012
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The spin_lock.c and spin_lock.h files are part of the GIET-VM nano-kernel.
-// This  library implements a user-level lock.
-// It is a simple binary lock, without waiting queue.
-// The lock_acquire() and lock_release() functions do not require a system call.
-// If the platform does not provide hardware cache coherence, the lock must be 
-// declared in a non cacheable segment,
-//
-// When a lock is defined in the mapping, it has not to be declared in the
-// application code: it will be initialised in the boot phase,
-// and the vobj_get_vbase() system call (defined in stdio.c and stdio.h files)
-// can be used to get the virtual base address of the lock from it's name.
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef _GIET_SPIN_LOCK_H_
-#define _GIET_SPIN_LOCK_H_
-
-///////////////////////////////////////////////////////////////////////////////////
-//  lock structure
-///////////////////////////////////////////////////////////////////////////////////
-
-typedef struct giet_lock_s 
-{
-    char name[60];      // lock name
-    unsigned int value; // taken if value != 0
-} giet_lock_t;
-
-//////////////////////////////////////////////////////////////////////////////
-//  access functions
-//////////////////////////////////////////////////////////////////////////////
-
-extern void lock_acquire(giet_lock_t * lock);
-extern void lock_release(giet_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_libs/stdio.c
===================================================================
--- soft/giet_vm/giet_libs/stdio.c	(revision 460)
+++ soft/giet_vm/giet_libs/stdio.c	(revision 461)
@@ -542,15 +542,23 @@
 
 ////////////////////////
-void giet_nic_rx_alloc()
-{
-    if ( sys_call( SYSCALL_NIC_RX_ALLOC,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_rx_alloc()");
-}
-
-////////////////////////
-void giet_nic_tx_alloc()
-{
-    if ( sys_call( SYSCALL_NIC_TX_ALLOC,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_tx_alloc()");
+int giet_nic_rx_alloc()
+{
+    int channel = sys_call( SYSCALL_NIC_ALLOC,
+                            1, 
+                            0, 0, 0 );
+    if ( channel < 0 ) giet_exit("error in giet_nic_tx_alloc()");
+
+    return channel;
+}
+
+///////////////////////
+int giet_nic_tx_alloc()
+{
+    int channel = sys_call( SYSCALL_NIC_ALLOC,
+                            0, 
+                            0, 0, 0 );
+    if ( channel < 0 ) giet_exit("error in giet_nic_tx_alloc()");
+
+    return channel;
 }
 
@@ -558,6 +566,7 @@
 void giet_nic_rx_start()
 {
-    if ( sys_call( SYSCALL_NIC_RX_START,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_rx_start()");
+    if ( sys_call( SYSCALL_NIC_START,
+                   1,
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_rx_start()");
 }
 
@@ -565,37 +574,77 @@
 void giet_nic_tx_start()
 {
-    if ( sys_call( SYSCALL_NIC_TX_START,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_tx_start()");
-}
-
-/////////////////////////////////////
-void giet_nic_rx_move( void* buffer )
-{
-    if ( sys_call( SYSCALL_NIC_RX_MOVE,
+    if ( sys_call( SYSCALL_NIC_START,
+                   0, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_tx_start()");
+}
+
+///////////////////////////////////////////////////////////
+void giet_nic_rx_move( unsigned int channel, void* buffer )
+{
+    if ( sys_call( SYSCALL_NIC_MOVE,
+                   1,
+                   channel, 
                    (unsigned int)buffer,
-                   0, 0, 0 ) )  giet_exit("error in giet_nic_rx_move()");
-}
-
-/////////////////////////////////////
-void giet_nic_tx_move( void* buffer )
-{
-    if ( sys_call( SYSCALL_NIC_TX_MOVE,
+                   0 ) )  giet_exit("error in giet_nic_rx_move()");
+}
+
+///////////////////////////////////////////////////////////
+void giet_nic_tx_move( unsigned int channel, void* buffer )
+{
+    if ( sys_call( SYSCALL_NIC_MOVE,
+                   0,
+                   channel, 
                    (unsigned int)buffer,
-                   0, 0, 0 ) )  giet_exit("error in giet_nic_tx_move()");
+                   0 ) )  giet_exit("error in giet_nic_tx_move()");
+}
+
+///////////////////////
+void giet_nic_rx_stop()
+{
+    if ( sys_call( SYSCALL_NIC_STOP,
+                   1, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_rx_stop()");
+}
+
+///////////////////////
+void giet_nic_tx_stop()
+{
+    if ( sys_call( SYSCALL_NIC_STOP,
+                   0, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_tx_stop()");
 }
 
 ////////////////////////
-void giet_nic_rx_stop()
-{
-    if ( sys_call( SYSCALL_NIC_RX_STOP,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_rx_start()");
+void giet_nic_rx_stats()
+{
+    if ( sys_call( SYSCALL_NIC_STATS,
+                   1, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_rx_stats()");
 }
 
 ////////////////////////
-void giet_nic_tx_stop()
-{
-    if ( sys_call( SYSCALL_NIC_TX_STOP,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_tx_start()");
-}
+void giet_nic_tx_stats()
+{
+    if ( sys_call( SYSCALL_NIC_STATS,
+                   0, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_tx_stats()");
+}
+
+////////////////////////
+void giet_nic_rx_clear()
+{
+    if ( sys_call( SYSCALL_NIC_CLEAR,
+                   1, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_rx_clear()");
+}
+
+////////////////////////
+void giet_nic_tx_clear()
+{
+    if ( sys_call( SYSCALL_NIC_CLEAR,
+                   0, 
+                   0, 0, 0 ) ) giet_exit("error in giet_nic_tx_clear()");
+}
+
 
 
Index: soft/giet_vm/giet_libs/stdio.h
===================================================================
--- soft/giet_vm/giet_libs/stdio.h	(revision 460)
+++ soft/giet_vm/giet_libs/stdio.h	(revision 461)
@@ -67,12 +67,12 @@
 //                                0x2F
 
-#define SYSCALL_NIC_RX_ALLOC      0x30
-#define SYSCALL_NIC_TX_ALLOC      0x31
-#define SYSCALL_NIC_RX_START      0x32
-#define SYSCALL_NIC_TX_START      0x33
-#define SYSCALL_NIC_RX_MOVE       0x34
-#define SYSCALL_NIC_TX_MOVE       0x35
-#define SYSCALL_NIC_RX_STOP       0x36
-#define SYSCALL_NIC_TX_STOP       0x37
+#define SYSCALL_NIC_ALLOC         0x30
+#define SYSCALL_NIC_START         0x31
+#define SYSCALL_NIC_MOVE          0x32
+#define SYSCALL_NIC_STOP          0x33
+#define SYSCALL_NIC_STATS         0x34
+#define SYSCALL_NIC_CLEAR         0x35
+//                                0x36
+//                                0x37
 //                                0x38
 //                                0x39
@@ -212,7 +212,7 @@
 //////////////////////////////////////////////////////////////////////////
 
-extern void giet_nic_rx_alloc();
-
-extern void giet_nic_tx_alloc();
+extern int giet_nic_rx_alloc();
+
+extern int giet_nic_tx_alloc();
 
 extern void giet_nic_rx_start();
@@ -220,11 +220,15 @@
 extern void giet_nic_tx_start();
 
-extern void giet_nic_rx_move( void* buffer);
-
-extern void giet_nic_tx_move( void* buffer );
+extern void giet_nic_rx_move( unsigned int channel, void* buffer );
+
+extern void giet_nic_tx_move( unsigned int channel, void* buffer );
 
 extern void giet_nic_rx_stop();
 
 extern void giet_nic_tx_stop();
+
+extern void giet_nic_rx_stats();
+
+extern void giet_nic_tx_stats();
 
 //////////////////////////////////////////////////////////////////////////
Index: soft/giet_vm/giet_libs/user_lock.c
===================================================================
--- soft/giet_vm/giet_libs/user_lock.c	(revision 461)
+++ soft/giet_vm/giet_libs/user_lock.c	(revision 461)
@@ -0,0 +1,127 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : user_lock.c         
+// Date     : 01/12/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The user_lock.c and user_lock.h files are part of the GIET-VM nano-kernel.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "user_lock.h"
+#include "giet_config.h"
+#include "stdio.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function uses LL/SC to make an atomic increment. 
+//////////////////////////////////////////////////////////////////////////////////
+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;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// This blocking function returns only when the lock has been taken.
+///////////////////////////////////////////////////////////////////////////////////
+void lock_acquire( user_lock_t* lock ) 
+{
+    // get next free slot index from user_lock
+    unsigned int ticket = atomic_increment( &lock->free, 1 );
+
+#if GIET_DEBUG_USER_LOCK
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get ticket = %d"
+                " for lock %x at cycle %d (current = %d / free = %d)\n",
+                x, y, lpid, ticket, 
+                (unsigned int)lock, giet_proctime(), lock->current, lock->free );
+#endif
+
+    // poll the current slot index
+    asm volatile("1793:                       \n"
+                 "lw   $10,  0(%0)            \n"
+                 "move $11,  %1               \n"
+                 "bne  $10,  $11,  1793b      \n"
+                 :
+                 : "r"(lock), "r"(ticket)
+                 : "$10", "$11" );
+               
+#if GIET_DEBUG_USER_LOCK
+giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get lock %x"
+                " at cycle %d (current = %d / free = %d)\n",
+                x, y, lpid, (unsigned int)lock, 
+                giet_proctime(), lock->current, lock->free );
+#endif
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function releases the lock.
+//////////////////////////////////////////////////////////////////////////////
+void lock_release( user_lock_t* lock ) 
+{
+    unsigned int current = lock->current;
+
+    if ( current == (GIET_LOCK_MAX_TICKET - 1) ) lock->current = 0;
+    else                                         lock->current = current + 1;
+
+#if GIET_DEBUG_USER_LOCK
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] release lock %x"
+                " at cycle %d (current = %d / free = %d)\n",
+                x, y, lpid, (unsigned int)lock, 
+                giet_proctime(), lock->current, lock->free );
+#endif
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function initializes the lock.
+//////////////////////////////////////////////////////////////////////////////
+void lock_init( user_lock_t* lock )
+{
+    lock->current = 0;
+    lock->free    = 0;
+
+#if GIET_DEBUG_USER_LOCK
+unsigned int    x;
+unsigned int    y;
+unsigned int    lpid;
+giet_proc_xyp( &x, &y, &lpid );
+giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] init lock %x"
+                " at cycle %d (current = %d / free = %d)\n",
+                x, y, lpid, (unsigned int)lock,
+                giet_proctime(), lock->current, lock->free );
+#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_libs/user_lock.h
===================================================================
--- soft/giet_vm/giet_libs/user_lock.h	(revision 461)
+++ soft/giet_vm/giet_libs/user_lock.h	(revision 461)
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : user_lock.h         
+// Date     : 01/12/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The file_lock.c and file_lock.h files are part of the GIET-VM nano-kernel.
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_FILE_LOCK_H_
+#define _GIET_FILE_LOCK_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+//  lock structure
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct user_lock_s 
+{
+    unsigned int current;        // current slot index
+    unsigned int free;           // next free slot index
+    unsigned int padding[14];    // for 64 bytes alignment
+} user_lock_t;
+
+///////////////////////////////////////////////////////////////////////////////////
+//  access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int atomic_increment( unsigned int* ptr,
+                                      unsigned int  increment );
+
+extern void lock_acquire( user_lock_t * lock );
+
+extern void lock_release( user_lock_t * lock );
+
+extern void lock_init( user_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
+
