summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2013-11-06 11:34:02 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2013-11-06 11:34:02 +0100
commit1297a513dad3ce3bc6f8472ed592a865aea18fac (patch)
tree87e6b591464ffed530a4fcb039a4e201255664f7
parent85db86e6d9f61566a0de522d4e0dfbfe6787ba61 (diff)
downloadstrace-1297a513dad3ce3bc6f8472ed592a865aea18fac.tar.gz
strace-1297a513dad3ce3bc6f8472ed592a865aea18fac.tar.bz2
strace-1297a513dad3ce3bc6f8472ed592a865aea18fac.tar.xz
Speed up and explain fd_isset()
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r--desc.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/desc.c b/desc.c
index e18735c..3957226 100644
--- a/desc.c
+++ b/desc.c
@@ -477,12 +477,20 @@ sys_getdtablesize(struct tcb *tcp)
}
#endif
-static int
-fd_isset(int d, fd_set *fds)
+/* FD_ISSET from libc would abort for large fd if built with
+ * debug flags/library hacks which enforce array bound checks
+ * (fd_set contains a fixed-size array of longs).
+ * We need to use a homegrown replacement.
+ */
+static inline int
+fd_isset(unsigned fd, fd_set *fds)
{
- const int bpl = 8 * sizeof(long);
- long *s = (long *) fds;
- return !!(s[d / bpl] & (1L << (d % bpl)));
+ /* Using unsigned types to avoid signed divisions and shifts,
+ * which are slow(er) on many CPUs.
+ */
+ const unsigned bpl = 8 * sizeof(long);
+ unsigned long *s = (unsigned long *) fds;
+ return s[fd / bpl] & (1UL << (fd % bpl));
}
static int