diff options
author | mjg <mjg@FreeBSD.org> | 2014-10-30 05:21:12 +0000 |
---|---|---|
committer | mjg <mjg@FreeBSD.org> | 2014-10-30 05:21:12 +0000 |
commit | 569cf8ac16dba31f925cd8cda2c15ea8f3df4333 (patch) | |
tree | 138be2c1f48d5e57bba86ff55730cfc4fff99804 | |
parent | 5bb6a8bca1bb93742c27552b40fa4d271db0beb7 (diff) | |
download | FreeBSD-src-569cf8ac16dba31f925cd8cda2c15ea8f3df4333.zip FreeBSD-src-569cf8ac16dba31f925cd8cda2c15ea8f3df4333.tar.gz |
filedesc: microoptimize fget_unlocked by retrying obtaining reference count
without restarting whole lookup
Restart is only needed when fp was closed by current process, which is a much
rarer event than ref/deref by some other thread.
-rw-r--r-- | sys/kern/kern_descrip.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 36a4a79..2935223 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2359,6 +2359,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, } } #endif + retry: count = fp->f_count; if (count == 0) { fdt = fdp->fd_files; @@ -2368,10 +2369,8 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, * Use an acquire barrier to force re-reading of fdt so it is * refreshed for verification. */ - if (atomic_cmpset_acq_int(&fp->f_count, count, count + 1) == 0) { - fdt = fdp->fd_files; - continue; - } + if (atomic_cmpset_acq_int(&fp->f_count, count, count + 1) == 0) + goto retry; fdt = fdp->fd_files; #ifdef CAPABILITIES if (seq_consistent_nomb(fd_seq(fdt, fd), seq)) |