threaded mode: madvise() map1 to `MADV_DONTNEED | MADV_COLD` after threads completed.

Fortune for fcmp's current commit: Half blessing − 半吉
master
Avril 3 years ago
parent 0739dc6393
commit eb721ab93a
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -11,7 +11,7 @@
#ifdef DEBUG #ifdef DEBUG
#define __name(d) #d #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 #else
#define dprintf(fmt, ...) #define dprintf(fmt, ...)
#endif #endif

@ -18,6 +18,9 @@ typedef struct mmap {
int open_and_map(const char* file, mmap_t* restrict ptr); int open_and_map(const char* file, mmap_t* restrict ptr);
int unmap_and_close(mmap_t map); int unmap_and_close(mmap_t map);
int set_preload_map(mmap_t* restrict 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 #ifdef _cplusplus
} }

@ -27,6 +27,17 @@ _FORCE_INLINE const void* die_with_usage_if_null(const void* ptr)
else return 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) static int unmap_all(mmap_t ptrs[], size_t len)
{ {
register int rval=1; register int rval=1;
@ -41,6 +52,7 @@ static int unmap_all(mmap_t ptrs[], size_t len)
return rval; return rval;
} }
static int compare_then_close(const mmap_t * restrict map1, mmap_t map2) static int compare_then_close(const mmap_t * restrict map1, mmap_t map2)
{ {
register int rval=0; register int rval=0;
@ -60,6 +72,7 @@ static void prep_map(mmap_t* restrict map)
{ {
if(!set_preload_map(map)) if(!set_preload_map(map))
fprintf(stderr, "Error: failed to prep map %p (%d), continuing anyway\n", map->ptr, map->fd); 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 #ifdef _RUN_THREADED
@ -198,6 +211,8 @@ int main(int argc, char** argv)
dprintf("Children spawned"); dprintf("Children spawned");
sched_wait(&threads); sched_wait(&threads);
// Waited, we can now unprep map1
unprep_map(&map1, true);
for (register int i=0;i<nrest;i++) { for (register int i=0;i<nrest;i++) {
if(rvals[i]) { if(rvals[i]) {

@ -14,6 +14,8 @@
#define ADVICE DEFAULT_ADVICE | MADV_WILLNEED #define ADVICE DEFAULT_ADVICE | MADV_WILLNEED
#define UNADVICE MADV_NORMAL | MADV_COLD
#include <map.h> #include <map.h>
static inline int _map_advise(const mmap_t* restrict map, int adv) 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); 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) int set_preload_map(mmap_t* restrict map)
{ {
if(_map_advise(map, ADVICE) != 0) { 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 0;
} }
return 1; return 1;

Loading…
Cancel
Save