Index: /soft/giet_vm/giet_libs/mwmr_channel.c
===================================================================
--- /soft/giet_vm/giet_libs/mwmr_channel.c	(revision 449)
+++ /soft/giet_vm/giet_libs/mwmr_channel.c	(revision 450)
@@ -1,45 +1,42 @@
 //////////////////////////////////////////////////////////////////////////////////
-// File     : mwmr_channel_.c         
+// File     : mwmr_channel.c         
 // Date     : 01/04/2012
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The mwmr_channel.c and mwmr_channel.h files are part of the GIET nano-kernel.
-// This  middleware implements a user level Multi-Writers / Multi-Readers
-// communication channel, that can be used by parallel multi-tasks applications
-// respecting the TCG (Tasks and Communications Graph) formalism.
-// 
-// 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,
-// if the platform does not provide hardware cache coherence.
-//
-// ALL MWMR channels must be defined in the mapping_info data structure, 
-// 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
-// an integer number of unsigned int (32 bits words).
-// The max number of words that can be stored in a MWMR channel is defined by the
-// "depth" parameter, and the "width" parameter define the minimal number of
-// word contained in an atomic item. Therefore, the "depth" parameter must be
-// a multiple of the "width" parameter.
-//
-// 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.
-///////////////////////////////////////////////////////////////////////////////////
 
 #include <mwmr_channel.h>
 #include <stdio.h>
 
-//////////////////////////////////////////////////////////////////////////////
-//  mwmr_lock_aquire()
-// This blocking function returns only when the lock has been taken.
-// If the lock is already taken a fixed delay is introduced before retry.
-//////////////////////////////////////////////////////////////////////////////
-void mwmr_lock_acquire(unsigned int * lock_address) {
-    register unsigned int * plock = lock_address;
-    register unsigned int delay = 100;
+//////////////////////////////////////
+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");
+
+    mwmr->ptw   = 0;
+    mwmr->ptr   = 0;
+    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
+}
+
+
+///////////////////////////////////////////////////
+static void mwmr_lock_acquire( unsigned int* lock ) 
+{
+    register unsigned int*  plock = lock;
+    register unsigned int   delay = 100;
     asm volatile (
             "1:                               \n"
@@ -63,15 +60,9 @@
 
 
-//////////////////////////////////////////////////////////////////////////////
-//       nb_mwmr_write()
-// This is a non-blocking function.
-// The nitems parameter is the number of items to be transfered.
-// The requested transfer is therefore (nitems * width) words.
-// It takes the lock for exclusive access before testing the channel state.
-// If there is not enough data in mwmr channel to read nitems,
-// it reads as many items as possible, releases the lock, and returns 
-// the number of read items (it can be 0).
-//////////////////////////////////////////////////////////////////////////////
-unsigned int nb_mwmr_write(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+///////////////////////////////////////////////////
+unsigned int nb_mwmr_write( mwmr_channel_t * mwmr, 
+                            unsigned int * buffer, 
+                            unsigned int nitems)
+{
     unsigned int x;
     unsigned int spaces; // number of empty slots (in words)
@@ -82,7 +73,5 @@
     unsigned int ptw;    // channel ptw
 
-    if (nitems == 0) {
-        return 0;
-    }
+    if (nitems == 0) return 0;
 
     // get the lock
@@ -97,13 +86,11 @@
     nwords = width * nitems;
 
-    if (spaces >= nwords) { // transfer nitems, release lock and return 
-        for (x = 0; x < nwords; x++) {
+    if (spaces >= nwords) // transfer nitems, release lock and return 
+    { 
+        for (x = 0; x < nwords; x++) 
+        {
             mwmr->data[ptw] = buffer[x];
-            if ((ptw + 1) == depth) {
-                ptw = 0;
-            }
-            else {
-                ptw = ptw + 1;
-            }
+            if ((ptw + 1) == depth)  ptw = 0; 
+            else                     ptw = ptw + 1;
         }
         mwmr->sts = mwmr->sts + nwords;
@@ -112,20 +99,17 @@
         return nitems;
     }
-    else if (spaces < width) {
-        // release lock and return 
+    else if (spaces < width) // release lock and return 
+    {
         mwmr->lock = 0;
         return 0;
     }
-    else {
-        // transfer as many items as possible, release lock and return 
+    else // transfer as many items as possible, release lock and return 
+    {
         nwords = (spaces / width) * width;    // integer number of items
-        for (x = 0; x < nwords; x++) {
+        for (x = 0; x < nwords; x++) 
+        {
             mwmr->data[ptw] = buffer[x];
-            if ((ptw + 1) == depth) {
-                ptw = 0;
-            }
-            else {
-                ptw = ptw + 1;
-            }
+            if ((ptw + 1) == depth) ptw = 0;
+            else                    ptw = ptw + 1;
         }
         mwmr->sts = sts + nwords;
@@ -137,15 +121,70 @@
 
 
-//////////////////////////////////////////////////////////////////////////////
-//    mwmr_write()
-// This blocking function returns only when the transfer is completed.
-// The nitems parameter is the number of items to be transfered.
-// The requested transfer is therefore (nitems * width) words.
-// It takes the lock for exclusive access before testing the channel state.
-// If there is not enough space in mwmr channel to write nitems,
-// it writes as many items as possible, releases the lock, and retry 
-// after a random delay.
-//////////////////////////////////////////////////////////////////////////////
-void mwmr_write(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+
+//////////////////////////////////////////////////
+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;
+
+    // get the lock
+    mwmr_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];
+            if ((ptr + 1) == depth)  ptr = 0;
+            else                     ptr = ptr + 1;
+        }
+        mwmr->sts = mwmr->sts - nwords;
+        mwmr->ptr = ptr;
+        mwmr->lock = 0;
+        return nitems;
+    }
+    else if (sts < width) // release lock and return 
+    {
+        mwmr->lock = 0;
+        return 0;
+    }
+    else // transfer as many items as possible, release lock and return 
+    {
+        nwords = (sts / width) * width; // integer number of items
+        for (x = 0 ; x < nwords ; x++) 
+        {
+            buffer[x] = mwmr->data[ptr];
+            if ((ptr + 1) == depth)  ptr = 0;
+            else                     ptr = ptr + 1;
+        }
+        mwmr->sts = sts - nwords;
+        mwmr->ptr = ptr;
+        mwmr->lock = 0;
+        return (nwords / width);
+    }
+} // nb_mwmr_read()
+
+
+
+////////////////////////////////////////
+void mwmr_write( mwmr_channel_t * mwmr, 
+                 unsigned int *   buffer, 
+                 unsigned int     nitems ) 
+{
     unsigned int x;
     unsigned int spaces; // number of empty slots (in words)
@@ -156,9 +195,8 @@
     unsigned int ptw;    // channel ptw
 
-    if (nitems == 0) {
-        return;
-    }
-
-    while (1) {
+    if (nitems == 0)  return;
+
+    while (1) 
+    {
         // get the lock
         mwmr_lock_acquire(&mwmr->lock);
@@ -172,14 +210,11 @@
         nwords = width * nitems;
 
-        if (spaces >= nwords) {
-            // write nwords, release lock and return
-            for (x = 0; x < nwords; x++) {
+        if (spaces >= nwords) // write nwords, release lock and return
+        {
+            for (x = 0; x < nwords; x++) 
+            {
                 mwmr->data[ptw] = buffer[x];
-                if ((ptw + 1) == depth) {
-                    ptw = 0;
-                }
-                else {
-                    ptw = ptw + 1;
-                }
+                if ((ptw + 1) == depth)  ptw = 0; 
+                else                     ptw = ptw + 1;
             }
             mwmr->ptw = ptw;
@@ -188,19 +223,16 @@
             return;
         }
-        else if (spaces < width) {
-            // release lock and retry after delay
-            mwmr->lock = 0;
-        }
-        else {
-            // write as many items as possible, release lock and retry after delay
+        else if (spaces < width) // release lock and deschedule           
+        {
+            mwmr->lock = 0;
+        }
+        else // write as many items as possible, release lock and deschedule
+        {
             nwords = (spaces / width) * width;  // integer number of items
-            for (x = 0; x < nwords; x++) {
+            for (x = 0; x < nwords; x++) 
+            {
                 mwmr->data[ptw] = buffer[x];
-                if ((ptw + 1) == depth) {
-                    ptw = 0;
-                }
-                else {
-                    ptw = ptw + 1;
-                }
+                if ((ptw + 1) == depth)  ptw = 0; 
+                else                     ptw = ptw + 1;
             }
             mwmr->sts = sts + nwords;
@@ -215,15 +247,9 @@
 
 
-//////////////////////////////////////////////////////////////////////////////
-//       nb_mwmr_read()
-// This is a non-blocking function.
-// The nitems parameter is the number of items to be transfered.
-// The requested transfer is therefore (nitems * width) words.
-// It takes the lock for exclusive access before testing the channel state.
-// If there is not enough data in mwmr channel to read nitems,
-// it reads as many items as possible, releases the lock, and returns 
-// the number of read items (it can be 0).
-//////////////////////////////////////////////////////////////////////////////
-unsigned int nb_mwmr_read(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+//////////////////////////////////////
+void mwmr_read( mwmr_channel_t * mwmr, 
+                unsigned int *   buffer, 
+                unsigned int     nitems) 
+{
     unsigned int x;
     unsigned int nwords; // requested transfer length (in words)
@@ -233,82 +259,8 @@
     unsigned int ptr;    // channel ptr
 
-    if (nitems == 0) {
-        return 0;
-    }
-
-    // get the lock
-    mwmr_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];
-            if ((ptr + 1) == depth) {
-                ptr = 0;
-            }
-            else {
-                ptr = ptr + 1;
-            }
-        }
-        mwmr->sts = mwmr->sts - nwords;
-        mwmr->ptr = ptr;
-        mwmr->lock = 0;
-        return nitems;
-    }
-    else if (sts < width) {
-        // release lock and return 
-        mwmr->lock = 0;
-        return 0;
-    }
-    else {
-        // transfer as many items as possible, release lock and return 
-        nwords = (sts / width) * width; // integer number of items
-        for (x = 0 ; x < nwords ; x++) {
-            buffer[x] = mwmr->data[ptr];
-            if ((ptr + 1) == depth) {
-                ptr = 0;
-            }
-            else {
-                ptr = ptr + 1;
-            }
-        }
-        mwmr->sts = sts - nwords;
-        mwmr->ptr = ptr;
-        mwmr->lock = 0;
-        return (nwords / width);
-    }
-} // nb_mwmr_read()
-
-
-//////////////////////////////////////////////////////////////////////////////
-//    mwmr_read()
-// This blocking function returns only when the transfer is completed.
-// The nitems parameter is the number of items to be transfered.
-// The requested transfer is therefore (nitems * width) words.
-// It takes the lock for exclusive access before testing the channel state.
-// If there is not enough data in mwmr channel to read nitems,
-// it reads as many items as possible, releases the lock, and retry 
-// after a random delay.
-//////////////////////////////////////////////////////////////////////////////
-void 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;
-    }
-
-    while (1) {
+    if (nitems == 0) return;
+
+    while (1) 
+    {
         // get the lock
         mwmr_lock_acquire(&mwmr->lock);
@@ -321,14 +273,11 @@
         nwords = width * nitems;
 
-        if (sts >= nwords) {
-            // read nwords, release lock and return
-            for (x = 0; x < nwords; x++) {
+        if (sts >= nwords) // read nwords, release lock and return
+        {
+            for (x = 0; x < nwords; x++) 
+            {
                 buffer[x] = mwmr->data[ptr];
-                if ((ptr + 1) == depth) {
-                    ptr = 0;
-                }
-                else {
-                    ptr = ptr + 1;
-                }
+                if ((ptr + 1) == depth)  ptr = 0;
+                else                     ptr = ptr + 1;
             }
             mwmr->sts = mwmr->sts - nwords;
@@ -337,18 +286,16 @@
             return;
         }
-        else if (sts < width) {
-            // release lock and retry after delay
-            mwmr->lock = 0;
-        }
-        else {   // read as many items as possible, release lock and retry after delay
+        else if (sts < width) // release lock and deschedule
+        {
+            mwmr->lock = 0;
+        }
+        else // read as many items as possible, release lock and deschedule
+        {   
             nwords = (sts / width) * width; // integer number of items
-            for (x = 0; x < nwords; x++) {
+            for (x = 0; x < nwords; x++) 
+            {
                 buffer[x] = mwmr->data[ptr];
-                if ((ptr + 1) == depth) {
-                    ptr = 0;
-                }
-                else {
-                    ptr = ptr + 1;
-                }
+                if ((ptr + 1) == depth) ptr = 0;
+                else                    ptr = ptr + 1;
             }
             mwmr->sts = sts - nwords;
Index: /soft/giet_vm/giet_libs/mwmr_channel.h
===================================================================
--- /soft/giet_vm/giet_libs/mwmr_channel.h	(revision 449)
+++ /soft/giet_vm/giet_libs/mwmr_channel.h	(revision 450)
@@ -4,4 +4,29 @@
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The mwmr_channel.c and mwmr_channel.h files are part of the GIET nano-kernel.
+// This  middleware implements a user level Multi-Writers / Multi-Readers
+// communication channel, that can be used by parallel multi-tasks applications
+// respecting the TCG (Tasks and Communications Graph) formalism.
+// 
+// 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,
+// 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
+// an integer number of unsigned int (32 bits words).
+// The max number of words that can be stored in a MWMR channel is defined by the
+// "depth" parameter, and the "width" parameter define the minimal number of
+// word contained in an atomic item. Therefore, the "depth" parameter must be
+// a multiple of the "width" parameter.
+//
+// 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.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -11,6 +36,6 @@
 ///////////////////////////////////////////////////////////////////////////////////
 //  MWMR channel structure
-// The data array size is defined to obtain sizeof(mwmr_channel_t) = 4096 bytes.
-// The actual size can be redefined in the mapping info data structure.
+// The data buffer size is defined to obtain sizeof(mwmr_channel_t) = 4096 bytes.
+// The actual buffer size cannot be larger than 4072 bytes (1018 words).
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -30,16 +55,19 @@
 //////////////////////////////////////////////////////////////////////////////
 
+void mwmr_init(  mwmr_channel_t* mwmr,
+                 unsigned int    width,     // number of words per item
+                 unsigned int    items );   // max number of items
+
 void mwmr_write( mwmr_channel_t* mwmr, 
-                 unsigned int*   buffer, 
-                 unsigned int    nitems );
+                 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    nitems );
+void mwmr_write( mwmr_channel_t* mwmr, 
+                 unsigned int*   buffer,    // user buffer vbase address
+                 unsigned int    nitems );  // number of items to transfer
 
 unsigned int nb_mwmr_read ( mwmr_channel_t * mwmr,
                             unsigned int * buffer,
                             unsigned int nitems );
-
 
 unsigned int nb_mwmr_write( mwmr_channel_t * mwmr,
Index: /soft/giet_vm/giet_libs/stdio.c
===================================================================
--- /soft/giet_vm/giet_libs/stdio.c	(revision 449)
+++ /soft/giet_vm/giet_libs/stdio.c	(revision 450)
@@ -541,26 +541,62 @@
 //////////////////////////////////////////////////////////////////////////////////
 
-/////////////////////
-void giet_nic_alloc()
-{
-    if ( sys_call( SYSCALL_NIC_ALLOC,
-                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_alloc()");
-}
-
-///////////////////////////////////////
-void giet_nic_sync_send( void* buffer )
-{
-    if ( sys_call( SYSCALL_NIC_SYNC_SEND,
+////////////////////////
+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()");
+}
+
+////////////////////////
+void giet_nic_rx_start()
+{
+    if ( sys_call( SYSCALL_NIC_RX_START,
+                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_rx_start()");
+}
+
+////////////////////////
+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,
                    (unsigned int)buffer,
-                   0, 0, 0 ) )  giet_exit("error in giet_nic_sync_send()");
-}
-
-//////////////////////////////////////////
-void giet_nic_sync_receive( void* buffer )
-{
-    if ( sys_call( SYSCALL_NIC_SYNC_RECEIVE,
+                   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,
                    (unsigned int)buffer,
-                   0, 0, 0 ) )  giet_exit("error in giet_nic_sync_receive()");
-}
+                   0, 0, 0 ) )  giet_exit("error in giet_nic_tx_move()");
+}
+
+////////////////////////
+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_tx_stop()
+{
+    if ( sys_call( SYSCALL_NIC_TX_STOP,
+                   0, 0, 0, 0 ) ) giet_exit("error in giet_nic_tx_start()");
+}
+
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_libs/stdio.h
===================================================================
--- /soft/giet_vm/giet_libs/stdio.h	(revision 449)
+++ /soft/giet_vm/giet_libs/stdio.h	(revision 450)
@@ -46,7 +46,7 @@
 #define SYSCALL_VOBJ_GET_LENGTH   0x1B
 #define SYSCALL_GET_XY            0x1C
-#define SYSCALL_NIC_ALLOC         0x1D
-#define SYSCALL_NIC_SYNC_SEND     0x1E
-#define SYSCALL_NIC_SYNC_RECEIVE  0x1F
+//                                0x1D
+//                                0x1E
+//                                0x1F
 
 #define SYSCALL_FAT_OPEN          0x20
@@ -66,4 +66,21 @@
 //                                0x2E
 //                                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
+//                                0x38
+//                                0x39
+//                                0x3A
+//                                0x3B
+//                                0x3C
+//                                0x3D
+//                                0x3E
+//                                0x3F
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -195,9 +212,19 @@
 //////////////////////////////////////////////////////////////////////////
 
-extern void giet_nic_alloc();
-
-extern void giet_nic_sync_send( void* buffer);
-
-extern void giet_nic_sync_receive( void* buffer );
+extern void giet_nic_rx_alloc();
+
+extern void giet_nic_tx_alloc();
+
+extern void giet_nic_rx_start();
+
+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_stop();
+
+extern void giet_nic_tx_stop();
 
 //////////////////////////////////////////////////////////////////////////
