Index: trunk/kernel/mm/kcm.h
===================================================================
--- trunk/kernel/mm/kcm.h	(revision 619)
+++ trunk/kernel/mm/kcm.h	(revision 635)
@@ -1,7 +1,6 @@
 /*
- * kcm.h - Per-cluster Kernel Cache Manager definition.
+ * kcm.h - Kernel Cache Manager definition.
  *
- * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
- *          Alain Greiner    (2016,2017,2018)
+ * Authors    Alain Greiner (2016,2017,2018,2019)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -33,30 +32,35 @@
 #include <kmem.h>
 
+
+#define KCM_PAGE_FULL     0
+#define KCM_PAGE_EMPTY    1
+#define KCM_PAGE_ACTIVE   2
+
 /****************************************************************************************
  * This structure defines a generic Kernel Cache Manager, that is a block allocator,
- * for fixed size objects. It exists a specific KCM allocator for each object type.
- * The actual allocated block size is the smallest multiple of the KCM slot, that
- * contain one single object. The KCM slot is 64 bytes, as it must be large enough
- * to store the kcm_page descriptor, defined below.
- * The various KCM allocators themselves are not statically allocated in the cluster
- * manager, but are dynamically allocated when required, using the embedded KCM
- * allocator defined in the cluster manager, to allocate the other ones...
+ * for fixed size objects. It exists in each cluster a specific KCM allocator for 
+ * the following block sizes: 64, 128, 256, 512, 1024, 2048 bytes.
+ * These six KCM allocators are initialized by the cluster_init() function.
+ *
+ * Each KCM cache is implemented as a set o 4 Kbytes pages. A kcm_page is split in slots,
+ * where each slot can contain one block. in each kcm_page, the first slot (that cannot
+ * be smaller than 64 bytes) contains the kcm page descriptor, defined below
+ * 
+ * To allow any thread running in any cluster to directly access the KCM of any cluster,
+ * ALMOS-MKH defines two sets of access functions, for local or remote access.
  ***************************************************************************************/
 
 typedef struct kcm_s
 {
-	busylock_t           lock;             /*! protect KCM ammocator                   */
-	uint32_t             block_size;       /*! rounded block size (bytes)              */
-	uint32_t             blocks_nr;        /*! max number of blocks per page           */
+	remote_busylock_t    lock;             /*! protect KCM allocator                   */
 
+	list_entry_t         full_root;        /*! root of full pages list                 */
 	list_entry_t         active_root;      /*! root of active pages list               */
-	list_entry_t         busy_root;        /*! root of busy pages list                 */
-	list_entry_t         free_root;        /*! root of free pages list                 */
 
-	uint32_t             free_pages_nr;    /*! number of free pages                    */
-	uint32_t             busy_pages_nr;    /*! number of busy pages                    */
+	uint32_t             full_pages_nr;    /*! number of busy pages                    */
 	uint32_t             active_pages_nr;  /*! number of active pages                  */
 
-	uint32_t             type;             /*! KCM type                                */
+	uint32_t             order;            /*! ln( block_size )                        */
+	uint32_t             max_blocks;       /*! max number of blocks per page           */
 }
 kcm_t;
@@ -65,31 +69,36 @@
 /****************************************************************************************
  * This structure defines a KCM-page descriptor.
- * A KCM-page contains at most (CONFIG_PPM_PAGE_SIZE / CONFIG_KCM_SLOT_SIZE) blocks.
- * This kcm page descriptor is stored in the first slot of the page.
+ * A KCM-page contains at most (CONFIG_PPM_PAGE_SIZE / CONFIG_KCM_SLOT_SIZE) slots,
+ * and each slot contains one block. The kcm page descriptor is stored in first slot.
+ * The current allocation status is defined by the 64 bits "status" bit vector: each
+ * non zero bit defines an allocated block / "counts is the number of allocated blocks. 
+ * Each kcm_page is registered in one of the two following page_list:
+ * - full   : when count == max
+ * - active : count < max 
  ***************************************************************************************/
 
 typedef struct kcm_page_s
 {
-	uint32_t        bitmap[2];             /*! at most 64 blocks in a single page      */
-	list_entry_t    list;                  /*! [active / busy / free] list member      */
-	kcm_t         * kcm;                   /*! pointer on kcm allocator                */
-	page_t        * page;                  /*! pointer on the physical page descriptor */
-	uint32_t        count;                 /*! number of allocated blocks              */
-	uint32_t        busy;                  /*! page busy if non zero                   */
-	uint32_t        active;                /*! page active if non zero                 */
+	uint64_t            status;            /*! bit vector: non-zero == allocated       */
+	uint32_t            count;             /*! number of allocated blocks in page      */
+	list_entry_t        list;              /*! [active / busy / free] list member      */
+	kcm_t             * kcm;               /*! pointer on kcm allocator                */
+	page_t            * page;              /*! pointer on the physical page descriptor */
 }
 kcm_page_t;
 
 /****************************************************************************************
- * This function initializes a generic Kernel Cache Manager.
+ * This function must be called by a local thread. 
+ * It initializes a Kernel Cache Manager, depending on block size.
  ****************************************************************************************
  * @ kcm      : pointer on KCM manager to initialize.
- * @ type     : KCM allocator type.
+ * @ order    : ln(block_size).
  ***************************************************************************************/
 void kcm_init( kcm_t    * kcm,
-               uint32_t   type );
+               uint32_t   order );
 
 /****************************************************************************************
- * This function releases all memory allocated to a generic Kernel Cache Manager.
+ * This function must be called by a local thread. 
+ * It releases all memory allocated to a Kernel Cache Manager.
  ****************************************************************************************
  * @ kcm      : pointer on KCM manager to destroy.
@@ -98,25 +107,50 @@
 
 /****************************************************************************************
- * This function allocates one single object from a Kernel Cache Manager
- * The object size must be smaller than one page size.
+ * This function must be called by a local thread. 
+ * It allocates one block from the local Kernel Cache Manager.
  ****************************************************************************************
- * @ kcm      :  pointer on the selected KCM allocator
+ * @ order     :  ln( block-size ) == KCM allocator identifier.
  * @ return pointer on allocated block if success / return NULL if failure
  ***************************************************************************************/
-void * kcm_alloc( kcm_t * kcm );
+void * kcm_alloc( uint32_t order );
 
 /****************************************************************************************
- * This function releases a previouly allocated block containing one object.
+ * This function must be called by a local thread. 
+ * It releases a previouly allocated block to the local Kernel Cache Manager.
  ****************************************************************************************
- * @ ptr   : local pointer on the allocated buffer.
+ * @ block_ptr   : local pointer on the released block.
  ***************************************************************************************/
-void kcm_free( void * ptr );
+void kcm_free( void    * block_ptr );
 
 /****************************************************************************************
- * This function prints KCM allocator state (for debug only).
+ * This function can be called by any thread running in any cluster. 
+ * It allocates one fixed size block from a remote Kernel Cache Manager.
  ****************************************************************************************
- * @ kcm   : local pointer on the selected KCM allocator.
+ * @ kcm_cxy   : remote KCM cluster identifier.
+ * @ order     :  ln( block-size ) == KCM allocator identifier.
+ * @ return a local pointer on allocated block if success / return NULL if failure
  ***************************************************************************************/
-void kcm_print( kcm_t * kcm );
+void * kcm_remote_alloc( cxy_t    kcm_cxy,
+                         uint32_t order );
+
+/****************************************************************************************
+ * This function can be called by any thread running in any cluster. 
+ * It releases a previouly allocated block to a remote Kernel Cache Manager.
+ ****************************************************************************************
+ * @ kcm_cxy     : remote KCM cluster identifier.
+ * @ block_ptr   : local pointer on the released buffer in remote cluster.
+ ***************************************************************************************/
+void kcm_remote_free( cxy_t     kcm_cxy,
+                      void    * block_ptr );
+
+/****************************************************************************************
+ * This debug function can be called by any thread running in any cluster. 
+ * It diplays on TXT0 the current state of a local KCM allocator.
+ ****************************************************************************************
+ * @ kcm_cxy : remote KCM cluster identifier.
+ * @ kcm_ptr : local pointer on remote KCM.
+ ***************************************************************************************/
+void kcm_remote_display( cxy_t   kcm_cxy,
+                         kcm_t * kcm_ptr );
 
 #endif	/* _KCM_H_ */
