From 371ad8abf4494837a77ab6c443c0d534652e3dbd Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 9 Nov 2020 14:47:48 -0800 Subject: cache: overload syncer thread to also pre-allocate This changes the syncer thread to always be created for writers, and makes it posix_fallocate() the cache file to the maximum size. When the syncer is disabled w/ms=0, it simply returns after the posix_fallocate. posix_fallocate errors are ignored, this is simply an opportunistic optimization. I have some concern about the glibc emulation mentioned in the man page, but writers are opened O_WRONLY which the notes say cause the emulation to fail with EBADF which is preferable, and I'm using O_WRONLY for the writers. --- src/rmd_cache.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/rmd_cache.c b/src/rmd_cache.c index 9e42be3..5b3323e 100644 --- a/src/rmd_cache.c +++ b/src/rmd_cache.c @@ -42,7 +42,10 @@ #define CACHE_FILE_SIZE_LIMIT (500 * 1024 * 1024) -/* periodic fdatasync thread for cache writers when fdatasyncing is enabled */ +/* Periodic fdatasync thread for cache writers. + * Note all writers create this thread initially to try perform a + * posix_fallocate() of CACHE_FILE_SIZE_LIMIT + */ static void * rmdCacheFileSyncer(CacheFile *file) { struct timespec delay; @@ -53,14 +56,19 @@ static void * rmdCacheFileSyncer(CacheFile *file) rmdThreadsSetName("rmdCacheSyncer"); - delay.tv_sec = file->periodic_datasync_ms / 1000; - delay.tv_nsec = (file->periodic_datasync_ms - delay.tv_sec * 1000) * 1000000; - if (file->gzfp) fd = file->gzfd; else fd = fileno(file->fp); + (void) posix_fallocate(fd, 0, CACHE_FILE_SIZE_LIMIT); + + if (!file->periodic_datasync_ms) + return NULL; + + delay.tv_sec = file->periodic_datasync_ms / 1000; + delay.tv_nsec = (file->periodic_datasync_ms - delay.tv_sec * 1000) * 1000000; + for (;;) { nanosleep(&delay, NULL); fdatasync(fd); @@ -106,7 +114,7 @@ static int _rmdCacheFileOpen(CacheFile *file, const char *path) file->chapter_n_bytes = 0; - if (file->mode == RMD_CACHE_FILE_MODE_WRITE && file->periodic_datasync_ms) + if (file->mode == RMD_CACHE_FILE_MODE_WRITE) pthread_create(&file->syncer_thread, NULL, (void *(*)(void *))rmdCacheFileSyncer, file); return 0; @@ -118,7 +126,7 @@ static int _rmdCacheFileClose(CacheFile *file) { assert(file); - if (file->mode == RMD_CACHE_FILE_MODE_WRITE && file->periodic_datasync_ms) { + if (file->mode == RMD_CACHE_FILE_MODE_WRITE) { pthread_cancel(file->syncer_thread); pthread_join(file->syncer_thread, NULL); } -- cgit v1.2.1