C: added `madvise()` calls for sequential map preloading

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

@ -17,6 +17,7 @@ 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);
#ifdef _cplusplus
}

@ -56,6 +56,12 @@ static int compare_then_close(const mmap_t * restrict map1, mmap_t map2)
return rval;
}
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);
}
#ifdef _RUN_THREADED
struct t_task {
_Atomic int* _ALIAS othis;
@ -81,7 +87,10 @@ void proc_thread(vec_t* restrict v_tasks)
{
for(register int i=0;i<v_tasks->len;i++)
{
// Copy map into local buffer
mrest[i] = tasks[i].mthis;
// Prep this map
prep_map(&mrest[i]);
#ifdef DEBUG
frest[i] = tasks[i].fthis;
#endif
@ -137,6 +146,9 @@ int main(int argc, char** argv)
return -1;
}
// Prep map 1
prep_map(&map1);
for(register int i=0;i<nrest;i++) {
const char* f2 = frest[i];
dprintf("Attempting to map %d (%s)", i, f2);
@ -145,7 +157,11 @@ int main(int argc, char** argv)
unmap_and_close(map1);
unmap_all(mrest, i);
return -1;
}
}
#ifdef _RUN_THREADED
// Prep the new map immediately if single threaded.
else if(! (sched_should(nrest) || _RUN_THREADED)) prep_map(&mrest[i]);
#endif
}
dprintf("All map okay");
register int rval=0;
@ -157,7 +173,10 @@ int main(int argc, char** argv)
vec_t vtask_args = vec_new_with_cap(sizeof(struct t_task), nrest);
struct t_task* task_args = vtask_args.ptr;
for (int i=0;i<nrest;i++) {
// Set default return value for task (0).
rvals[i] = 0;
// Set task params
task_args[i] = (struct t_task){
.ithis = i,
.fthis = frest[i],

@ -10,8 +10,26 @@
#define FILEMODE S_IRWXU | S_IRGRP | S_IROTH
#define DEFAULT_ADVICE MADV_SEQUENTIAL
#define ADVICE DEFAULT_ADVICE | MADV_WILLNEED
#include <map.h>
static inline int _map_advise(const mmap_t* restrict map, int adv)
{
return madvise(map->ptr, map->len, adv);
}
int set_preload_map(mmap_t* restrict map)
{
if(_map_advise(map, ADVICE) != 0) {
perror("failed to advise kernel about mapped page(s)");
return 0;
}
return 1;
}
int open_and_map(const char* file, mmap_t* restrict ptr)
{
int fd;
@ -27,7 +45,7 @@ int open_and_map(const char* file, mmap_t* restrict ptr)
return 0;
}
register struct mmap map = { .fd = fd, .ptr = NULL, .len = st.st_size };
struct mmap map = { .fd = fd, .ptr = NULL, .len = st.st_size };
if ((map.ptr = mmap(NULL, map.len, PROT_READ, MAP_SHARED,fd, 0)) == MAP_FAILED) {
perror("mmap() failed");
@ -35,8 +53,15 @@ int open_and_map(const char* file, mmap_t* restrict ptr)
return 0;
}
if(_map_advise(&map, DEFAULT_ADVICE) != 0) {
perror("madvise(): failed to set default advice");
//XXX: Should this be a hard error, or should we return the map if this fails anyway?
unmap_and_close(map);
return 0;
}
*ptr = map;
return 1;
}

@ -28,7 +28,9 @@ static void* _spawn(void* _arg)
bool sched_should(size_t ntasks)
{
register size_t num = num_cpus();
static size_t num = 0;
// XXX: This is not thread-safe, but this function is only ever called by the main thread, so...
if(!num) num = num_cpus();
return (num > 1 && ntasks > 1);
}

Loading…
Cancel
Save