diff options
author | Alexander Larsson <alexl@redhat.com> | 2020-04-01 10:58:14 +0200 |
---|---|---|
committer | Alexander Larsson <alexander.larsson@gmail.com> | 2020-04-02 17:01:01 +0200 |
commit | 123d22694a99f151db499462f22ef44d080d5128 (patch) | |
tree | b6c0baffdc68e161e890249729f22b888bec184e /document-portal | |
parent | 57bf174bdd21dd1a43e788d1d52af36dbe10f31a (diff) |
document-portal: Minor optization for refcounts
When we're forgetting kernel refs we allow unreffing all the refs
in one atomic op rather than looping over individual unrefs.
Diffstat (limited to 'document-portal')
-rw-r--r-- | document-portal/document-portal-fuse.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/document-portal/document-portal-fuse.c b/document-portal/document-portal-fuse.c index 1f0a57e..cc9a8d5 100644 --- a/document-portal/document-portal-fuse.c +++ b/document-portal/document-portal-fuse.c @@ -116,7 +116,7 @@ static void xdp_tempfile_unref (XdpTempfile *tempfile); G_DEFINE_AUTOPTR_CLEANUP_FUNC (XdpTempfile, xdp_tempfile_unref) typedef struct { - gint ref_count; /* atomic, includes kernel_ref_count */ + gint ref_count; /* atomic, includes one ref if kernel_ref_count != 0 */ gint kernel_ref_count; /* atomic */ XdpDomain *domain; @@ -702,26 +702,33 @@ retry_atomic_decrement1: static XdpInode * xdp_inode_kernel_ref (XdpInode *inode) { - g_atomic_int_inc (&inode->kernel_ref_count); - return xdp_inode_ref (inode); + int old; + + old = g_atomic_int_add (&inode->kernel_ref_count, 1); + + if (old == 0) + xdp_inode_ref (inode); + return inode; } static void -xdp_inode_kernel_unref (XdpInode *inode) +xdp_inode_kernel_unref (XdpInode *inode, unsigned long count) { - gint old_ref; + gint old_ref, new_ref; retry_atomic_decrement1: old_ref = g_atomic_int_get (&inode->kernel_ref_count); - if (old_ref <= 0) + if (old_ref < count) { g_warning ("Can't kernel_unref inode with no kernel refs"); return; } - if (!g_atomic_int_compare_and_exchange (&inode->kernel_ref_count, old_ref, old_ref - 1)) + new_ref = old_ref - count; + if (!g_atomic_int_compare_and_exchange (&inode->kernel_ref_count, old_ref, new_ref)) goto retry_atomic_decrement1; - xdp_inode_unref (inode); + if (new_ref == 0) + xdp_inode_unref (inode); } static int @@ -1400,7 +1407,7 @@ static void abort_reply_entry (struct fuse_entry_param *e) { XdpInode *inode = xdp_inode_from_ino (e->ino); - xdp_inode_kernel_unref (inode); + xdp_inode_kernel_unref (inode, 1); } static int @@ -1822,11 +1829,7 @@ forget_one (fuse_ino_t ino, { g_autoptr(XdpInode) inode = xdp_inode_from_ino (ino); - while (nlookup > 0) - { - xdp_inode_kernel_unref (inode); - nlookup--; - } + xdp_inode_kernel_unref (inode, nlookup); } static void |