Index: trunk/kernel/libk/remote_barrier.h
===================================================================
--- trunk/kernel/libk/remote_barrier.h	(revision 14)
+++ trunk/kernel/libk/remote_barrier.h	(revision 23)
@@ -1,4 +1,4 @@
 /*
- * remote_barrier.h - distributed kernel barrier definition
+ * remote_barrier.h - Access a POSIX barrier.               
  * 
  * Author  Alain Greiner (2016)
@@ -10,5 +10,5 @@
  * ALMOS-MKH is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
-err* the Free Software Foundation; version 2.0 of the License.
+ * the Free Software Foundation; version 2.0 of the License.
  *
  * ALMOS-MKH is distributed in the hope that it will be useful, but
@@ -27,32 +27,106 @@
 #include <kernel_config.h>
 #include <hal_types.h>
+#include <remote_spinlock.h>
+#include <xlist.h>
+
+/***************************************************************************************
+ *          This file defines a POSIX compliant barrier.
+ *
+ * It is used by multi-threaded applications to synchronise threads running in
+ * different clusters, as all access functions uses hal_remote_lw() / hal_remote_sw()
+ * portable remote access primitives.
+ *
+ * A barrier is declared by a given user process as a "pthread_barrier_t" global variable.
+ * This user type is implemented as an unsigned long, but the value is not used by the 
+ * kernel. ALMOS-MKH uses only the barrier virtual address as an identifier.
+ * For each user barrier, ALMOS-MKH creates a kernel "remote_barrier_t" structure,
+ * dynamically allocated in the reference cluster by the remote_barrier_create() function, 
+ * and destroyed by the remote_barrier_destroy() function, using RPC if the calling thread
+ * is not running in the reference cluster.
+ *
+ * The blocking "remote_barrier_wait()" function implements a descheduling policy when
+ * the calling thread is not the last expected thread: the calling thread is registered 
+ * in a waiting queue, rooted in the barrier structure, and the the calling thread 
+ * is blocked on the THREAD_BLOCKED_USERSYNC condition. The last arrived thread
+ * unblocks all registtered waiting threads.
+ *
+ * Implementation note:
+ * This barrier is also used by the kernel in the parallel kernel_init phase, as the 
+ * remote_barrier() function does not require barrier initialisation, when the barrier
+ * is statically allocated by the compiler in the kdata segment.
+ * **************************************************************************************/
 
 /*****************************************************************************************
- * This structure defines a distributed "rendez-vous" barrier, that can be used
- * to synchronise several kernel threads running in different clusters
- * It is used in the parallel kernel_init phase.
- * It does not need to be initialised, but it must be statically allocated 
- * in the KDATA segment to be properly initialised by the compiler/loader.
+ * This structure defines the barrier descriptor.
+ * - It contains an xlist of all barriers dynamically created by a given process,
+ *   rooted in the reference process descriptor.
+ * - It contains the root of another xlist to register all arrived threads.
  ****************************************************************************************/
 
 typedef struct remote_barrier_s
 {
-    uint32_t   current;   // number of arrived threads
-    uint32_t   sense;     // barrier state (toggle)
-    uint32_t   pad[(CONFIG_CACHE_LINE_SIZE>>2)-2];
+    remote_spinlock_t  lock;          /*! lock protecting list of arrived threads       */
+    intptr_t           ident;         /*! virtual address in user space == identifier   */
+    uint32_t           current;       /*! number of arrived threads                     */
+    uint32_t           sense;         /*! barrier state (toggle)                        */
+    uint32_t           nb_threads;    /*! number of expected threads                    */ 
+    xlist_entry_t      list;          /*! member of list of barriers in same process    */
+    xlist_entry_t      root;          /*! root of list of arrived threads               */
 } 
 remote_barrier_t;
 
 /*****************************************************************************************
- * This blocking function implements a toggle barrier. It returns only when all
- * expected threads reach the barrier. It can be used several times without
- * specific initialisation. 
- * It is portable, as it uses the remote_lw() & remote_sw() access functions.
- * @ xp      : extended pointer on barrier in remote cluster
- * @ count   : number of expected thread
+ * This function is directly used by the kernel in the kernel_init phase,
+ * because it does not require barrier state initialisation.
+ * It returns only when the <count> expected threads reach the barrier.
+ *****************************************************************************************
+ * @ barrier_xp  : extended pointer on barrier descriptor.
+ * @ count       : number of expected threads.
  ****************************************************************************************/
-inline void remote_barrier( xptr_t   xp,  
+inline void remote_barrier( xptr_t   barrier_xp,  
                             uint32_t count );
 
 
+/*****************************************************************************************
+ * This function returns an extended pointer on the remote barrier identified
+ * by its virtual address in a given user process. It makes an associative search, 
+ * scanning the list of barriers rooted in the reference process descriptor.
+ *****************************************************************************************
+ * @ ident    : barrier virtual address, used as identifier.
+ * @ returns extended pointer on barrier if success / returns XPTR_NULL if not found. 
+ ****************************************************************************************/
+xptr_t remote_barrier_from_ident( intptr_t  ident );
+
+/*****************************************************************************************
+ * This function implement the pthread_barrier_init() syscall.
+ * It allocates memory for the barrier descriptor in the reference cluster for
+ * the calling process, it initializes the barrier state, and register it in the 
+ * list of barriers owned by the reference process.
+ *****************************************************************************************
+ * @ count       : number of expected threads.
+ * @ ident       : barrier identifier (virtual address in user space).
+ * @ return 0 if success / return ENOMEM if failure.
+ ****************************************************************************************/
+error_t remote_barrier_create( intptr_t ident,
+                               uint32_t count );
+
+/*****************************************************************************************
+ * This function implement the pthread_barrier_destroy() syscall.
+ * It releases thr memory allocated for the barrier descriptor, and remove the barrier 
+ * from the list of barriers owned by the reference process.
+ *****************************************************************************************
+ * @ barrier_xp  : extended pointer on barrier descriptor.
+ ****************************************************************************************/
+void remote_barrier_destroy( xptr_t   barrier_xp );
+
+/*****************************************************************************************
+ * This function implement the pthread_barrier_wait() syscall.
+ * It returns only when the number of expected threads (registered in the barrier
+ * dexcriptor) reach the barrier.
+ *****************************************************************************************
+ * @ barrier_xp   : extended pointer on barrier descriptor.
+ ****************************************************************************************/
+void remote_barrier_wait( xptr_t   barrier_xp );
+
+
 #endif	/* _REMOTE_BARRIER_H_ */
