From d5f220877c98e0dc1ee57d56a194bd609fd82723 Mon Sep 17 00:00:00 2001 From: chao an Date: Tue, 7 Nov 2023 22:04:36 +0800 Subject: [PATCH] fs/inode: improve the performance of get file pointer After entering the critical section, we can access the file pointer without locking the file list directly. This is safe since the array access will not cause scheduling switching. Signed-off-by: chao an --- fs/inode/fs_files.c | 52 +++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 9f04b2197c134..63312f7d02048 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -68,6 +68,7 @@ static FAR struct file *files_fget(int fd, FAR struct filelist *list) static int files_extend(FAR struct filelist *list, size_t row) { FAR struct file **tmp; + irqstate_t flags; int i; if (row <= list->fl_rows) @@ -80,7 +81,7 @@ static int files_extend(FAR struct filelist *list, size_t row) return -EMFILE; } - tmp = kmm_realloc(list->fl_files, sizeof(FAR struct file *) * row); + tmp = kmm_malloc(sizeof(FAR struct file *) * row); DEBUGASSERT(tmp); if (tmp == NULL) { @@ -105,9 +106,16 @@ static int files_extend(FAR struct filelist *list, size_t row) } while (++i < row); + flags = enter_critical_section(); + + memcpy(tmp, list->fl_files, + list->fl_rows * sizeof(FAR struct file *)); + list->fl_files = tmp; list->fl_rows = row; + leave_critical_section(flags); + /* Note: If assertion occurs, the fl_rows has a overflow. * And there may be file descriptors leak in system. */ @@ -594,26 +602,42 @@ int fs_getfilep(int fd, FAR struct file **filep) * thread-specific file list. */ - /* And return the file pointer from the list */ - - ret = nxmutex_lock(&list->fl_lock); - if (ret < 0) + if (!nxmutex_is_locked(&list->fl_lock)) { - leave_critical_section(flags); - return ret; + *filep = files_fget(fd, list); + + /* if f_inode is NULL, fd was closed */ + + if (!(*filep)->f_inode) + { + *filep = NULL; + ret = -EBADF; + } } + else + { + /* And return the file pointer from the list */ - *filep = files_fget(fd, list); + ret = nxmutex_lock(&list->fl_lock); + if (ret < 0) + { + leave_critical_section(flags); + return ret; + } - /* if f_inode is NULL, fd was closed */ + *filep = files_fget(fd, list); - if (!(*filep)->f_inode) - { - *filep = NULL; - ret = -EBADF; + /* if f_inode is NULL, fd was closed */ + + if (!(*filep)->f_inode) + { + *filep = NULL; + ret = -EBADF; + } + + nxmutex_unlock(&list->fl_lock); } - nxmutex_unlock(&list->fl_lock); leave_critical_section(flags); return ret; }