From 08bfb3fb5bc536e6cb415e5f2cc9b7a63996c91e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 24 Oct 2017 23:32:58 +0200 Subject: [FUSE] Cache signalfd instances used in fuse read handler Previously, a fresh one was created and destroyed fo every read requests. This caused a lot of syscalls when reading. Now there's a simple cache of currently up to 6 signalfd. --- src/fuse/main.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'src/fuse') diff --git a/src/fuse/main.c b/src/fuse/main.c index 35acddd..1f26595 100644 --- a/src/fuse/main.c +++ b/src/fuse/main.c @@ -23,6 +23,7 @@ #include #include #include +#include #define debugf(...) do { logadd( LOG_DEBUG1, __VA_ARGS__ ); } while (0) @@ -40,6 +41,44 @@ static void (*fuse_sigIntHandler)(int) = NULL; static void (*fuse_sigTermHandler)(int) = NULL; static struct fuse_operations dnbd3_fuse_no_operations; +#define SIGPOOLSIZE 6 +static pthread_spinlock_t sigLock; +static dnbd3_signal_t *signalPool[SIGPOOLSIZE]; +static dnbd3_signal_t **sigEnd = signalPool + SIGPOOLSIZE; +static void signalInit() +{ + pthread_spin_init( &sigLock, PTHREAD_PROCESS_PRIVATE ); + for ( size_t i = 0; i < SIGPOOLSIZE; ++i ) { + signalPool[i] = NULL; + } +} +static inline dnbd3_signal_t *signalGet() +{ + pthread_spin_lock( &sigLock ); + for ( dnbd3_signal_t **it = signalPool; it < sigEnd; ++it ) { + if ( *it != NULL ) { + dnbd3_signal_t *ret = *it; + *it = NULL; + pthread_spin_unlock( &sigLock ); + return ret; + } + } + pthread_spin_unlock( &sigLock ); + return signal_newBlocking(); +} +static inline void signalPut(dnbd3_signal_t *signal) +{ + pthread_spin_lock( &sigLock ); + for ( dnbd3_signal_t **it = signalPool; it < sigEnd; ++it ) { + if ( *it == NULL ) { + *it = signal; + pthread_spin_unlock( &sigLock ); + return; + } + } + pthread_spin_unlock( &sigLock ); + signal_close( signal ); +} static int image_getattr(const char *path, struct stat *stbuf) { @@ -140,9 +179,10 @@ static int image_read(const char *path, char *buf, size_t size, off_t offset, st request.buffer = buf; request.length = (uint32_t)size; request.offset = offset; - request.signal = signal_newBlocking(); + request.signal = signalGet(); if ( !connection_read( &request ) ) { + signalPut( request.signal ); return -EINVAL; } while ( !request.finished ) { @@ -155,7 +195,7 @@ static int image_read(const char *path, char *buf, size_t size, off_t offset, st debugf( "fuse_read signal wait returned %d", ret ); } } - signal_close( request.signal ); + signalPut( request.signal ); if ( request.success ) { return request.length; } else { @@ -377,5 +417,6 @@ int main(int argc, char *argv[]) putchar('\n'); clock_gettime( CLOCK_REALTIME, &startupTime ); owner = getuid(); + signalInit(); return fuse_main( newArgc, newArgv, &image_oper, NULL ); } -- cgit v1.2.3-55-g7522