Index: trunk/kernel/mm/ppm.h
===================================================================
--- trunk/kernel/mm/ppm.h	(revision 486)
+++ trunk/kernel/mm/ppm.h	(revision 567)
@@ -1,7 +1,7 @@
 /*
- * ppm.h - Per-cluster Physical Pages Manager Interface
+ * ppm.h - Per-cluster Physical Pages Manager definition.
  *
  * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
- *          Alain Greiner    (2016)
+ *          Alain Greiner    (2016,2017,2018)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -28,5 +28,6 @@
 #include <hal_kernel_types.h>
 #include <list.h>
-#include <spinlock.h>
+#include <busylock.h>
+#include <queuelock.h>
 #include <boot_info.h>
 #include <page.h>
@@ -36,5 +37,5 @@
  * This structure defines the Physical Pages Manager in a cluster.
  * In each cluster, the physical memory bank starts at local physical address 0 and
- * contains an integer number of pages, is defined by the <pages_nr> field in the
+ * contains an integer number of pages, defined by the <pages_nr> field in the
  * boot_info structure. It is split in three parts:
  * - the "kernel_code" section contains the kernel code, loaded by the boot-loader.
@@ -43,24 +44,31 @@
  * - the "pages_tbl" section contains the physical page descriptors array. It starts
  *   at PPN = pages_offset, and it contains one entry per small physical page in cluster.
- *   It is created and initialized by the hal_ppm_create() function. "the
+ *   It is created and initialized by the hal_ppm_create() function. 
  * - The "kernel_heap" section contains all physical pages that are are not in the
- *   in the kernel_code and pages_tbl sections, and that have not been reserved by the
+ *   kernel_code and pages_tbl sections, and that have not been reserved by the
  *   architecture specific bootloader. The reserved pages are defined in the boot_info
  *   structure.
  *
  * The main service provided by the PMM is the dynamic allocation of physical pages
- * from the "kernel_heap" section.
- * This low-level allocator implements the buddy algorithm: an allocated block is
- * an integer number n of 4 small pages, and n (called order) is a power of 2.
+ * from the "kernel_heap" section. This low-level allocator implements the buddy 
+ * algorithm: an allocated block is an integer number n of small pages, where n 
+ * is a power of 2, and ln(n) is called order.
+ * This allocator being shared by the local threads, the free_page lists rooted 
+ * in the PPM descriptor are protected by a local busylock, because it is used
+ * by the idle_thread during kernel_init().
+ *
+ * Another service is to register the dirty pages in a specific dirty_list, that is
+ * also rooted in the PPM, in order to be able to save all dirty pages on disk.
+ * This dirty list is protected by a specific local queuelock.
  ****************************************************************************************/
 
 typedef struct ppm_s
 {
-	spinlock_t     free_lock;               /*! lock protecting free_pages[] lists      */
+	busylock_t     free_lock;               /*! lock protecting free_pages[] lists      */
 	list_entry_t   free_pages_root[CONFIG_PPM_MAX_ORDER];  /*! roots of free lists      */
 	uint32_t       free_pages_nr[CONFIG_PPM_MAX_ORDER];    /*! numbers of free pages    */
 	page_t       * pages_tbl;               /*! pointer on page descriptors array       */
 	uint32_t       pages_nr;                /*! total number of small physical page     */
-    spinlock_t     dirty_lock;              /*! lock protecting the dirty pages list    */
+    queuelock_t    dirty_lock;              /*! lock protecting dirty pages list        */
     list_entry_t   dirty_root;              /*! root of dirty pages list                */
     void         * vaddr_base;              /*! pointer on local physical memory base   */
@@ -68,4 +76,6 @@
 ppm_t;
 
+/************** functions to allocate / release physical pages  *************************/
+
 /*****************************************************************************************
  * This is the low-level physical pages allocation function.
@@ -107,4 +117,5 @@
 
 
+/************** functions to translate [ page <->  base <-> ppn ] ***********************/
 
 /*****************************************************************************************
@@ -175,3 +186,45 @@
 error_t ppm_assert_order( ppm_t * ppm );
 
+
+/*********** functions to handle dirty pages  *******************************************/
+
+/*****************************************************************************************
+ * This function registers a physical page as dirty. 
+ * - it takes the queuelock protecting the PPM dirty_list.
+ * - it test the PG_DIRTY flag in the page descriptor.
+ *   . if page already dirty => do nothing
+ *   . it page not dirty => set the PG_DIRTY flag and register page in PPM dirty list.
+ * - it releases the queuelock protecting the PPM dirty_list.
+ *****************************************************************************************
+ * @ page     : pointer on page descriptor.
+ * @ returns true if page was not dirty / returns false if page was dirty
+ ****************************************************************************************/
+bool_t ppm_page_do_dirty( page_t * page );
+
+/*****************************************************************************************
+ * This function unregisters a physical page as dirty. 
+ * - it takes the queuelock protecting the PPM dirty_list.
+ * - it test the PG_DIRTY flag in the page descriptor.
+ *   . if page not dirty => do nothing
+ *   . it page dirty => reset the PG_DIRTY flag and remove page from PPM dirty list.
+ * - it releases the queuelock protecting the PPM dirty_list.
+ *****************************************************************************************
+ * @ page     : pointer on page descriptor.
+ * @ returns true if page was dirty / returns false if page was not dirty
+ ****************************************************************************************/
+bool_t ppm_page_undo_dirty( page_t * page );
+
+/*****************************************************************************************
+ * This function synchronizes (i.e. update the disk) all dirty pages in a cluster.
+ * - it takes the queuelock protecting the PPM dirty_list.
+ * - it scans the PPM dirty list, and for each page:
+ *   . it takes the lock protecting the page.
+ *   . it removes the page from the PPM dirty_list.
+ *   . it reset the PG_DIRTY flag.
+ *   . it releases the lock protecting the page.
+ * - it releases the queuelock protecting the PPM dirty_list.
+ $ The PPM dirty_list is empty when the sync operation completes.
+ ****************************************************************************************/
+void ppm_sync_all_pages( void );
+
 #endif	/* _PPM_H_ */
