From d9221d62706b274e64e206816c24ee3a7a8f0093 Mon Sep 17 00:00:00 2001
From: Constantin P <papizh.konstantin@demlabs.net>
Date: Mon, 16 Sep 2024 13:31:35 +0700
Subject: [PATCH] Page reclaim techniques for more lowmem-friendly behaviour

---
 dap-sdk                        |  2 +-
 modules/chain/dap_chain_cell.c | 48 ++++++++++++++++++----------------
 2 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index 16bc981375..0e77d6f809 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 16bc9813751b728c9b0ad67402198a5749a1ce86
+Subproject commit 0e77d6f8090c05c43930a6d56db77b485b881255
diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c
index 766175ec0d..badf61a9a8 100644
--- a/modules/chain/dap_chain_cell.c
+++ b/modules/chain/dap_chain_cell.c
@@ -107,6 +107,17 @@ int dap_chain_cell_init(void)
     return  0;
 }
 
+#ifndef DAP_OS_WINDOWS
+DAP_STATIC_INLINE void s_cell_reclaim_cur_volume(dap_chain_cell_t *a_cell) {
+    if ( dap_chain_net_get_load_mode( dap_chain_net_by_id(a_cell->chain->net_id) )
+#ifdef MADV_PAGEOUT
+    && madvise(a_cell->map, (size_t)(a_cell->map_end - a_cell->map), MADV_PAGEOUT)
+#endif
+    && madvise(a_cell->map, (size_t)(a_cell->map_end - a_cell->map), MADV_DONTNEED) )
+        log_it(L_ERROR, "Unable to reclaim the previous volume, errno %d: \"%s\"", errno, dap_strerror(errno));
+}
+#endif
+
 DAP_STATIC_INLINE int s_cell_file_write_header(dap_chain_cell_t *a_cell)
 {
     dap_chain_cell_file_header_t l_hdr = {
@@ -135,12 +146,9 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f
         };
         
         NTSTATUS err = pfnNtCreateSection(&hSection, SECTION_MAP_READ|SECTION_EXTEND_SIZE|SECTION_MAP_WRITE, 
-                                          NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE,
-                                          (HANDLE)_get_osfhandle(l_fildes));
-        if ( !NT_SUCCESS(err) ) {
-            log_it(L_ERROR, "NtCreateSection() failed, status %lx", err);
-            return -1;
-        }
+                                          NULL, &SectionSize, PAGE_READWRITE, SEC_RESERVE, (HANDLE)_get_osfhandle(l_fildes));
+        if ( !NT_SUCCESS(err) )
+            return log_it(L_ERROR, "NtCreateSection() failed, status %lx", err), -1;
         a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, hSection);
     }
 #endif
@@ -158,23 +166,16 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f
     LARGE_INTEGER Offset = {
         .QuadPart = l_volume_start
     };
-    if ( !NT_SUCCESS ( err = pfnNtMapViewOfSection(hSection, GetCurrentProcess(), 
-                                                   (HANDLE)&a_cell->map, 0, 0, 
-                                                   &Offset, &l_map_size,
-                                                   ViewUnmap, MEM_RESERVE,
-                                                   PAGE_WRITECOPY) ) )
-    {
-        log_it(L_ERROR, "NtMapViewOfSection() failed, status %lx", err);
-        NtClose(hSection);
-        return -1;
-    }
+    err = pfnNtMapViewOfSection(hSection, GetCurrentProcess(), (HANDLE)&a_cell->map, 0, 0, 
+                                &Offset, &l_map_size, ViewUnmap, MEM_RESERVE, PAGE_WRITECOPY);
+    if ( !NT_SUCCESS(err) )
+        return NtClose(hSection), log_it(L_ERROR, "NtMapViewOfSection() failed, status %lx", err), -1;
 #else
-    if ( MAP_FAILED == (a_cell->map = mmap(NULL, l_map_size, PROT_READ|PROT_WRITE,
-                                           MAP_PRIVATE, fileno(a_cell->file_storage), l_volume_start)) ) {
-        log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be mapped, errno %d",
-                        a_cell->file_storage_path, a_cell->id.uint64, errno);
-        return -1;
-    }
+    s_cell_reclaim_cur_volume(a_cell);
+    if (( a_cell->map = mmap(NULL, l_map_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+                             fileno(a_cell->file_storage), l_volume_start) ) == MAP_FAILED )
+        return log_it(L_ERROR, "Chain cell \"%s\" 0x%016"DAP_UINT64_FORMAT_X" cannot be mapped, errno %d",
+                                a_cell->file_storage_path, a_cell->id.uint64, errno), -1;
 #ifdef DAP_OS_DARWIN
     a_cell->cur_vol_start = l_volume_start;
 #endif
@@ -182,6 +183,8 @@ DAP_STATIC_INLINE int s_cell_map_new_volume(dap_chain_cell_t *a_cell, size_t a_f
     a_cell->map_pos = a_cell->map + l_offset;
     a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, a_cell->map);
     a_cell->map_range_bounds = dap_list_append(a_cell->map_range_bounds, a_cell->map_end = a_cell->map + l_map_size);
+    if ( dap_chain_net_get_load_mode (dap_chain_net_by_id(a_cell->chain->net_id)) )
+        madvise(a_cell->map, l_map_size, MADV_SEQUENTIAL);
     return 0;
 }
 
@@ -469,6 +472,7 @@ int dap_chain_cell_load(dap_chain_t *a_chain, dap_chain_cell_t *a_cell)
             a_cell->map_pos += l_el_size;
             a_chain->load_progress = (int)((float)l_pos/l_full_size * 100 + 0.5);
         }
+        s_cell_reclaim_cur_volume(a_cell);
     } else { 
         DAP_DELETE(l_hdr);
         size_t l_read = 0;
-- 
GitLab