From eb721ab93a70a67a9fe9c6f46f76a6aefa7418be Mon Sep 17 00:00:00 2001 From: Avril Date: Tue, 6 Jul 2021 17:03:16 +0100 Subject: [PATCH] threaded mode: madvise() map1 to `MADV_DONTNEED | MADV_COLD` after threads completed. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for fcmp's current commit: Half blessing − 半吉 --- include/fcmp.h | 2 +- include/map.h | 3 +++ src/main.c | 15 +++++++++++++++ src/map.c | 13 ++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/fcmp.h b/include/fcmp.h index a89c3c7..9ccd391 100644 --- a/include/fcmp.h +++ b/include/fcmp.h @@ -11,7 +11,7 @@ #ifdef DEBUG #define __name(d) #d -#define dprintf(fmt, ...) printf("[dbg @" __FILE__ "->%s:%d] " fmt "\n", __func__, __LINE__ __VA_OPT__(,) __VA_ARGS__) +#define dprintf(fmt, ...) printf("[dbg @" __FILE__ "->%s:%d] " fmt "\n", __func__, __LINE__, ## __VA_ARGS__) #else #define dprintf(fmt, ...) #endif diff --git a/include/map.h b/include/map.h index 79e7c7f..b9ca4fc 100644 --- a/include/map.h +++ b/include/map.h @@ -18,6 +18,9 @@ typedef struct mmap { int open_and_map(const char* file, mmap_t* restrict ptr); int unmap_and_close(mmap_t map); int set_preload_map(mmap_t* restrict map); +/// Undo a previous call to `set_preload_map()`. +/// *freeing* (1 - yes, 0, no) - If the next operation on the map will be `unmap_and_close()`, advise the kernel to drop the mapped pages whenever it wants. Do not specify this if you will use the map again after this call. +int unset_preload_map(mmap_t* restrict map, int freeing); #ifdef _cplusplus } diff --git a/src/main.c b/src/main.c index c0de377..2ec043f 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,17 @@ _FORCE_INLINE const void* die_with_usage_if_null(const void* ptr) else return ptr; } +static void unprep_map(mmap_t* restrict map, bool free) +{ + //TODO: Should we actually bother to call this before unmapping? + + if(!unset_preload_map(map, (int)free)) + fprintf(stderr, "Error: failed to unprep map %p (%d)%s, continuing anyway\n", + map->ptr, map->fd, + (free ? " before closing" : "")); + else dprintf("unprep'd %p (%d)", map->ptr, map->fd); +} + static int unmap_all(mmap_t ptrs[], size_t len) { register int rval=1; @@ -41,6 +52,7 @@ static int unmap_all(mmap_t ptrs[], size_t len) return rval; } + static int compare_then_close(const mmap_t * restrict map1, mmap_t map2) { register int rval=0; @@ -60,6 +72,7 @@ static void prep_map(mmap_t* restrict map) { if(!set_preload_map(map)) fprintf(stderr, "Error: failed to prep map %p (%d), continuing anyway\n", map->ptr, map->fd); + else dprintf("prep'd %p (%d)", map->ptr, map->fd); } #ifdef _RUN_THREADED @@ -198,6 +211,8 @@ int main(int argc, char** argv) dprintf("Children spawned"); sched_wait(&threads); + // Waited, we can now unprep map1 + unprep_map(&map1, true); for (register int i=0;i static inline int _map_advise(const mmap_t* restrict map, int adv) @@ -21,10 +23,19 @@ static inline int _map_advise(const mmap_t* restrict map, int adv) return madvise(map->ptr, map->len, adv); } +int unset_preload_map(mmap_t* restrict map, int freeing) +{ + if(_map_advise(map, UNADVICE | (freeing ? MADV_DONTNEED : 0)) != 0) { + perror("failed to advise kernel to drop mapped page(s)"); + return 0; + } + return 1; +} + int set_preload_map(mmap_t* restrict map) { if(_map_advise(map, ADVICE) != 0) { - perror("failed to advise kernel about mapped page(s)"); + perror("failed to advise kernel to preload mapped page(s)"); return 0; } return 1;