Index: /soft/giet_vm/applications/gameoflife/main.c
===================================================================
--- /soft/giet_vm/applications/gameoflife/main.c	(revision 508)
+++ /soft/giet_vm/applications/gameoflife/main.c	(revision 509)
@@ -1,10 +1,15 @@
 //////////////////////////////////////////////////////////////////////////////////
-// File : main.c  (for gameoflife)
-// Date : November 2013
-// Author :  Alexandre Joannou <alexandre.joannou@lip6.fr>
+// File    : main.c  (for gameoflife)
+// Date    : November 2013 / February 2015
+// Authors :  Alexandre Joannou <alexandre.joannou@lip6.fr> november 2013
+//            Alain Greiner <alain.greiner@lip6.fr> february 2015
 //
-// This application is an emulation of the game of life automaton.
+// This application is an emulation of the Game of Life automaton.
 // The world size is defined by the HEIGHT and WIDTH parameters.
-// There is one task per processor, and each task compute HEIGHT/nbprocs lines.
+// There is one task per processor.
+// Each task compute HEIGHT/nbprocs lines.
+// Task running on processor P(0,0,0) initialises the barrier, and
+// control the chained buffer DMA controler, when it is used.
+//
 // The number of processors must be a power of 2 not larger than HEIGHT.
 //////////////////////////////////////////////////////////////////////////////////
@@ -21,102 +26,93 @@
 #define PRINTF(...) ({ if ( proc_id==0) { giet_shr_printf(__VA_ARGS__); } })
 
+typedef unsigned char uint8_t;
+
+uint8_t WORLD[2][HEIGHT][WIDTH] __attribute__((aligned(64)));
+
+uint8_t DISPLAY[2][HEIGHT][WIDTH] __attribute__((aligned(64)));
+
 giet_sqt_barrier_t barrier;
 
 volatile unsigned int init_ok;
 
-#define OLD 0
-#define NEW 1
-#define DSP 2
-
-typedef unsigned char uint8_t;
-typedef unsigned int size_t;
-
-uint8_t world[3][HEIGHT][WIDTH];
-
-/////////////////////////////////////////////////
-void init_world(size_t base_line, size_t nb_line)
-{
-   size_t x,y;
-   for (y = base_line ; y < base_line + nb_line; y++)
+////////////////////////////////////
+void init_world( unsigned int phase,
+                 unsigned int base_line,
+                 unsigned int nb_line )
+{
+   unsigned int x,y;
+   for (y = base_line ; y < base_line + nb_line ; y++)
+   {
+      for(x = 0 ; x < WIDTH ; x++) 
+      {
+         WORLD[phase][y][x] = (giet_rand() >> (x % 8)) & 0x1;
+      }
+   }
+}
+
+//////////////////////////////////////////////////////
+uint8_t number_of_alive_neighbour( unsigned int phase,
+                                   unsigned int x, 
+                                   unsigned int y )
+{
+   uint8_t nb = 0;
+
+   nb += WORLD[phase][(y - 1) % HEIGHT][(x - 1) % WIDTH];
+   nb += WORLD[phase][ y              ][(x - 1) % WIDTH];
+   nb += WORLD[phase][(y + 1) % HEIGHT][(x - 1) % WIDTH];
+   nb += WORLD[phase][(y - 1) % HEIGHT][ x             ];
+   nb += WORLD[phase][(y + 1) % HEIGHT][ x             ];
+   nb += WORLD[phase][(y - 1) % HEIGHT][(x + 1) % WIDTH];
+   nb += WORLD[phase][ y              ][(x + 1) % WIDTH];
+   nb += WORLD[phase][(y + 1) % HEIGHT][(x + 1) % WIDTH];
+
+   return nb;
+}
+
+/////////////////////////////////////////
+uint8_t compute_cell( unsigned int phase,
+                      unsigned int x, 
+                      unsigned int y )
+{
+   uint8_t nb_neighbours_alive = number_of_alive_neighbour( phase, x , y );
+
+   if (WORLD[phase][y][x] == 1) 
+   {
+      if (nb_neighbours_alive == 2 || nb_neighbours_alive == 3)  return 1;
+   }
+   else 
+   {
+      if (nb_neighbours_alive == 3) return 1;
+      else                          return WORLD[phase][y][x];
+   }
+   return 0;
+}
+
+/////////////////////////////////////////
+void compute_new_gen( unsigned int phase,
+                      unsigned int base_line, 
+                      unsigned int nb_line )
+{
+   unsigned int x,y;
+   for (y = base_line; y < base_line + nb_line; y++)
    {
       for(x = 0; x < WIDTH ; x++) 
       {
-         world[OLD][y][x] = (giet_rand() >> (x % 8)) & 0x1;
+         WORLD[phase][y][x] = compute_cell( 1 - phase , x , y );  
       }
    }
 }
 
-/////////////////////////////////////////////////
-uint8_t number_of_alive_neigh(size_t x, size_t y)
-{
-   uint8_t nb = 0;
-
-   nb += world[OLD][(y - 1) % HEIGHT][(x - 1) % WIDTH];
-   nb += world[OLD][ y              ][(x - 1) % WIDTH];
-   nb += world[OLD][(y + 1) % HEIGHT][(x - 1) % WIDTH];
-   nb += world[OLD][(y - 1) % HEIGHT][ x             ];
-   nb += world[OLD][(y + 1) % HEIGHT][ x             ];
-   nb += world[OLD][(y - 1) % HEIGHT][(x + 1) % WIDTH];
-   nb += world[OLD][ y              ][(x + 1) % WIDTH];
-   nb += world[OLD][(y + 1) % HEIGHT][(x + 1) % WIDTH];
-
-   return nb;
-}
-
-/////////////////////////////////////////////////
-uint8_t compute_cell(size_t x, size_t y)
-{
-   uint8_t nb_neighbours_alive = number_of_alive_neigh(x,y);
-   if (world[OLD][y][x] == 1) 
-   {
-      if (nb_neighbours_alive == 2 || nb_neighbours_alive == 3)  return 1;
-   }
-   else 
-   {
-      if (nb_neighbours_alive == 3) return 1;
-      else                          return world[OLD][y][x];
-   }
-   return 0;
-}
-
-//////////////////////////////////////////////////////
-void compute_new_gen(size_t base_line, size_t nb_line)
-{
-   size_t x,y;
+////////////////////////////////////
+void copy_world( unsigned int phase,
+                 unsigned int base_line,
+                 unsigned int nb_line )
+{
+   unsigned int x,y;
    for (y = base_line; y < base_line + nb_line; y++)
    {
       for(x = 0; x < WIDTH ; x++) 
       {
-         world[NEW][y][x] = compute_cell(x,y);  
-      }
-   }
-}
-
-////////////////////////////////////////////////////
-void display_world(size_t base_line, size_t nb_line)
-{
-   size_t x,y;
-   for (y = base_line; y < base_line + nb_line; y++)
-   {
-      for(x = 0; x < WIDTH ; x++) 
-      {
-         world[DSP][y][x] = world[OLD][y][x]*255;  
-      }
-   }
-
-   giet_fbf_sync_write( base_line * WIDTH , 
-                        &world[DSP][base_line][0], 
-                        nb_line * WIDTH );
-}
-
-/////////////////////////////////////////////////////
-void grow_old_world(size_t base_line, size_t nb_line)
-{
-   size_t x,y;
-   for (y = base_line; y < base_line + nb_line; y++)
-   {
-      for(x = 0; x < WIDTH ; x++) 
-      {
-         world[OLD][y][x] = world[NEW][y][x];  
+         DISPLAY[phase][y][x] = WORLD[phase][y][x]*255;  
       }
    }
@@ -138,10 +134,9 @@
    giet_procs_number( &x_size, &y_size, &n_local_procs );
 
-   // compute continuous processor index
+   // compute continuous processor index & number of procs
    unsigned int proc_id = (((x * y_size) + y) * n_local_procs) + p;  
-
-   unsigned int n_clusters     = x_size * y_size;            // number of clusters
-   unsigned int n_global_procs = n_clusters * n_local_procs; // number of processors
-   size_t i;
+   unsigned int n_global_procs = x_size * y_size * n_local_procs; 
+
+   unsigned int i;
 
    if ( n_global_procs > HEIGHT )
@@ -152,15 +147,25 @@
    }
 
-   size_t       nb_line       = HEIGHT / n_global_procs;
-   size_t       base_line     = nb_line * proc_id; 
-   
-   PRINTF("\n*** Starting barrier initialisation at cycle %d ***\n"
+   unsigned int nb_line       = HEIGHT / n_global_procs;
+   unsigned int base_line     = nb_line * proc_id; 
+   
+   PRINTF("\n*** Starting barrier and CMA initialisation at cycle %d ***\n"
           " nprocs = %d / nlines = %d\n", 
           giet_proctime() , n_global_procs, HEIGHT );
 
-   // barrier initialization
+   //////////// barrier & CMA initialization ( P(0,0,0) )
+
    if ( proc_id == 0 )
    {
+      // initialises CMA component
+      giet_fbf_cma_alloc();
+      giet_fbf_cma_start( &DISPLAY[0][0][0] , 
+                          &DISPLAY[1][0][0] , 
+                          HEIGHT * WIDTH );
+
+      // initialises barrier
       sqt_barrier_init( &barrier , x_size , y_size , n_local_procs );
+
+      // activates all other processors
       init_ok = 1;
    }
@@ -173,23 +178,52 @@
           giet_proctime() );
 
-   //  parallel world  initialization
-   init_world( base_line , nb_line );
-   display_world( base_line , nb_line );
-
+   ///////////// world  initialization ( All processors )
+
+   // initialises WORLD[0]
+   init_world( 0 , base_line , nb_line );
+
+   // copy WORLD[0] to DISPLAY[0]
+   copy_world( 0 , base_line , nb_line );
+
+   // synchronise with other procs
    sqt_barrier_wait( &barrier );
 
-   PRINTF("\n*** Starting life at cycle %d ***\n", 
-          giet_proctime() );
-   
-   for (i = 0; i < NB_ITERATION; i++)
-   {
-      compute_new_gen( base_line, nb_line );
-      grow_old_world( base_line, nb_line );
-      display_world( base_line, nb_line );
-
+   // P(0,0,0) displays DISPLAY[0]
+   if ( proc_id == 0 ) giet_fbf_cma_display ( 0 );
+
+   PRINTF("\n*** Starting evolution at cycle %d ***\n", giet_proctime() );
+   
+   //////////// evolution : 2 steps per iteration 
+
+   for (i = 0 ; i < NB_ITERATION ; i++)
+   {
+      // compute WORLD[1] from WORLD[0]
+      compute_new_gen( 1 , base_line , nb_line );
+
+      // copy WORLD[1] to DISPLAY[1]
+      copy_world( 1 , base_line , nb_line );
+
+      // synchronise with other procs
       sqt_barrier_wait( &barrier );
 
-      PRINTF(" - iteration %d completed\n", i );
-   }
+      // P(0,0,0) displays DISPLAY[1]
+      if ( proc_id == 0 ) giet_fbf_cma_display ( 1 );
+   
+      PRINTF(" - step %d completed\n", 2*i );
+   
+      // compute WORLD[0] from WORLD[1]
+      compute_new_gen( 0 , base_line , nb_line );
+
+      // copy WORLD[0] to DISPLAY[0]
+      copy_world( 0 , base_line , nb_line );
+
+      // synchronise with other procs
+      sqt_barrier_wait( &barrier );
+
+      // P(0,0,0) displays DISPLAY[0]
+      if ( proc_id == 0 ) giet_fbf_cma_display ( 0 );
+
+      PRINTF(" - step %d completed\n", 2*i + 1 );
+   } // end main loop
 
    PRINTF("\n*** End of main at cycle %d ***\n", giet_proctime());
