Index: trunk/libs/libalmosmkh/almosmkh.h
===================================================================
--- trunk/libs/libalmosmkh/almosmkh.h	(revision 629)
+++ trunk/libs/libalmosmkh/almosmkh.h	(revision 637)
@@ -2,5 +2,5 @@
  * almosmkh.h - User level ALMOS-MKH specific library definition.
  * 
- * Author     Alain Greiner (2016,2017,2018)
+ * Author     Alain Greiner (2016,2017,2018,2019)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -72,5 +72,6 @@
 
 /*************************************************************************************** 
- * This syscall returns the cluster an local index for the calling core.
+ * This syscall returns the cluster identifier and the local index
+ * for the calling core.
  ***************************************************************************************
  * @ cxy      : [out] cluster identifier.
@@ -78,9 +79,36 @@
  * @ return always 0.
  **************************************************************************************/
-int get_core( unsigned int * cxy,
-              unsigned int * lid );
+int get_core_id( unsigned int * cxy,
+                 unsigned int * lid );
+
+/*************************************************************************************** 
+ * This syscall returns the number of cores in a given cluster.
+ ***************************************************************************************
+ * @ cxy      : [in]  target cluster identifier.
+ * @ ncores   : [out] number of cores in target cluster.
+ * @ return always 0.
+ **************************************************************************************/
+int get_nb_cores( unsigned int   cxy,
+                  unsigned int * ncores );
+
+/*************************************************************************************** 
+ * This syscall uses the DQDT to search, in a macro-cluster specified by the 
+ * <cxy_base> and <level> arguments arguments, the core with the lowest load.
+ * it writes in the <cxy> and <lid> buffers the selected core cluster identifier
+ * and the local core index.
+ ***************************************************************************************
+ * @ cxy_base : [in]  any cluster identifier in macro-cluster.in clusters array.
+ * @ level    : [in]  macro-cluster level in [1,2,3,4,5].
+ * @ cxy      : [out] selected core cluster identifier.
+ * @ lid      : [out] selectod core local index.
+ * @ return 0 if success / 1 if no core in macro-cluster / -1 if illegal arguments.
+ **************************************************************************************/
+int get_best_core( unsigned int   cxy_base,
+                   unsigned int   level,
+                   unsigned int * cxy,
+                   unsigned int * lid );
 
 /***************************************************************************************
- * This function returns the calling core cycles counter,
+ * This function returns the value contained in the calling core cycles counter,
  * taking into account a possible overflow on 32 bits architectures.
  ***************************************************************************************
@@ -414,4 +442,72 @@
                       unsigned int cxy );
 
+/********* Non standard (ALMOS-MKH specific) pthread_parallel_create() syscall  *********/
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// This system call can be used to parallelize the creation and the termination
+// of a parallel multi-threaded application. It removes the loop in the main thread that
+// creates the N working threads (N  sequencial pthread_create() ). It also removes the
+// loop that waits completion of these N working threads (N sequencial pthread_join() ).
+// It creates one "work" thread (in detached mode) per core in the target architecture.
+// Each "work" thread is identified by the [cxy][lid] indexes (cluster / local core). 
+// The pthread_parallel_create() function returns only when all "work" threads completed
+// (successfully or not).
+//
+// To use this system call, the application code must define the following structures:
+// - To define the arguments to pass to the <work> function the application must allocate
+//   and initialize a first 2D array, indexed by [cxy] and [lid] indexes, where each slot
+//   contains an application specific structure, and another 2D array, indexed by the same
+//   indexes, containing pointers on these structures. This array of pointers is one
+//   argument of the pthread_parallel_create() function.
+// - To detect the completion of the <work> threads, the application must allocate a 1D
+//   array, indexed by the cluster index [cxy], where each slot contains a pthread_barrier
+//   descriptor. This barrier is initialised by the pthread_parallel_create() function,
+//   in all cluster containing at least one work thread. This array of barriers is another
+//   argument of the pthread_parallel_create() function.
+//
+// Implementation note:
+// To parallelize the "work" threads creation and termination, the pthread_parallel_create()
+// function creates a distributed quad-tree (DQT) of "build" threads covering all cores 
+// required to execute the parallel application. 
+// Depending on the hardware topology, this DQT can be truncated, (i.e. some
+// parent nodes can have less than 4 chidren), if (x_size != y_size), or if one size
+// is not a power of 2. Each "build" thread is identified by two indexes [cxy][level].
+// Each "build" thread makes the following tasks:
+// 1) It calls the pthread_create() function to create up to 4 children threads, that
+//    are are "work" threads when (level == 0), or "build" threads, when (level > 0).
+// 2) It initializes the barrier (global variable), used to block/unblock
+//    the parent thread until children completion.
+// 3) It calls the pthread_barrier_wait( self ) to wait until all children threads
+//    completed (successfully or not).
+// 4) It calls the pthread_barrier_wait( parent ) to unblock the parent thread.
+//////////////////////////////////////////////////////////////////////////////////////////
+
+/*****************************************************************************************
+ * This blocking function creates N working threads that execute the code defined
+ * by the <work_func> and <work_args> arguments.
+ * The number N of created threads is entirely defined by the <root_level> argument.
+ * This value defines an abstract quad-tree, with a square base : level in [0,1,2,3,4],
+ * side in [1,2,4,8,16], nclusters in [1,4,16,64,256]. This base is called  macro_cluster.
+ * A working thread is created on all cores contained in the specified macro-cluster.
+ * The actual number of physical clusters containing cores can be smaller than the number
+ * of clusters covered by the quad tree. The actual number of cores in a cluster can be
+ * less than the max value.
+ *
+ * In the current implementation, all threads execute the same <work_func> function,
+ * on different arguments, that are specified as a 2D array of pointers <work_args>.
+ * This can be modified in a future version, where the <work_func> argument can become
+ * a 2D array of pointers, to have one specific function for each thread.
+ *****************************************************************************************
+ * @ root_level            : [in]  DQT root level in [0,1,2,3,4].
+ * @ work_func             : [in]  pointer on start function.
+ * @ work_args_array       : [in]  pointer on a 2D array of pointers.
+ * @ parent_barriers_array : [in]  pointer on a 1D array of barriers.
+ * @ return 0 if success / return -1 if failure.
+ ****************************************************************************************/
+int pthread_parallel_create( unsigned int   root_level,
+                             void         * work_func,
+                             void         * work_args_array,
+                             void         * parent_barriers_array );
+
 #endif /* _LIBALMOSMKH_H_ */
 
