public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] ftw.c: Check for "." and ".." branchlessly
@ 2023-09-24 17:16 Wilco Dijkstra
  2023-09-25  0:17 ` Paul Eggert
  0 siblings, 1 reply; 14+ messages in thread
From: Wilco Dijkstra @ 2023-09-24 17:16 UTC (permalink / raw)
  To: Xi Ruoyao, tirtajames45; +Cc: 'GNU C Library'

Hi,

> There are also other issues:
>
> 1. If "fname" is an empty string, there will be a buffer overread.  I
> don't know if fname can be empty string here though.

I think 'namlen' is the length of the string, so you could do something like:

if (namlen == 1 && (memcmp (fname, ".\0", 2) == 0)
  return 0;

That will generate a single 16-bit load on targets that support unaligned
access. But it would slow things down on targets that don't or don't expand
memcmp inline.

> 2. If "fname" is "..", then the bytes in "w4" can be:

Indeed, the expression:

(*(w4 *)fname | '\0' SH 24)

is incorrect since X | 0 << 24 is always the same as X.

And big-endian doesn't work like that either.

> 3. We should let the compiler decide to use the branchless operation or
> not.  If the compiler does not do the correct thing we should fix the
> compiler instead of writing some nasty code here because fixing the
> compiler will benefit both Glibc and other packages.  There is some
> related existing GCC bug report (https://gcc.gnu.org/PR109555), the
> problem is using a branchless operation here is not always a win.  See
> the comments in the bug report for reference.

Yes, branchless code is not a goal by itself. First determine whether this
function is performance critical, then determine the parts that are slower
than necessary. I don't think this check is a major bottleneck, however
assuming most filenames do not start with a '.', this would typically need
one load, compare and branch per call:

if (glibc_unlikely (fname[0] == '.'))
  ...

Cheers,
Wilco

^ permalink raw reply	[flat|nested] 14+ messages in thread
[parent not found: <CANDqPp0yVgx8hdeL9JUQgyMSww2MW7QDdPERC2Mxp5vdCOoOog@mail.gmail.com>]
* [PATCH] ftw.c: Check for "." and ".." branchlessly
@ 2023-09-24  6:45 James Tirta Halim
  2023-09-24 11:29 ` Xi Ruoyao
  0 siblings, 1 reply; 14+ messages in thread
From: James Tirta Halim @ 2023-09-24  6:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: James Tirta Halim

---
 io/ftw.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/io/ftw.c b/io/ftw.c
index a72c7d5171..742369a2d2 100644
--- a/io/ftw.c
+++ b/io/ftw.c
@@ -66,6 +66,7 @@ char *alloca ();
 #include <unistd.h>
 #include <not-cancel.h>
 #include <sys/param.h>
+#include <endian.h>
 #ifdef _LIBC
 # include <include/sys/stat.h>
 #else
@@ -388,6 +389,25 @@ open_dir_stream (int *dfdp, struct ftw_data *data, struct dir_data *dirp)
 }
 
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define SH <<
+#else
+#  define SH >>
+#endif
+
+static int
+is_relative (const char *fname)
+{
+	typedef uint16_t w2 __attribute__ ((__may_alias__));
+	typedef uint32_t w4 __attribute__ ((__may_alias__));
+	const uint16_t n1 = '.' | '\0' SH 8;
+	const uint32_t n2 = '.' | '.' SH 8 | '\0' SH 16;
+	return (*(w2 *)fname == n1) | ((*(w4 *)fname | '\0' SH 24) == n2);
+}
+
+#undef SH
+
+
 static int
 process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
 	       size_t namlen, int d_type)
@@ -397,9 +417,8 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
   int flag = 0;
   size_t new_buflen;
 
-  if (name[0] == '.' && (name[1] == '\0'
-			 || (name[1] == '.' && name[2] == '\0')))
-    /* Don't process the "." and ".." entries.  */
+  /* Don't process the "." and ".." entries.  */
+  if (is_relative(name))
     return 0;
 
   new_buflen = data->ftw.base + namlen + 2;
-- 
2.42.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-09-25  8:10 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-24 17:16 [PATCH] ftw.c: Check for "." and ".." branchlessly Wilco Dijkstra
2023-09-25  0:17 ` Paul Eggert
2023-09-25  6:26   ` Alexander Monakov
2023-09-25  6:45     ` Alexander Monakov
2023-09-25  7:10     ` Paul Eggert
2023-09-25  7:15       ` Andrew Pinski
2023-09-25  7:21         ` Andrew Pinski
2023-09-25  7:32         ` Paul Eggert
2023-09-25  7:32       ` Alexander Monakov
2023-09-25  8:10         ` Paul Eggert
     [not found] <CANDqPp0yVgx8hdeL9JUQgyMSww2MW7QDdPERC2Mxp5vdCOoOog@mail.gmail.com>
2023-09-24 13:14 ` Xi Ruoyao
  -- strict thread matches above, loose matches on Subject: below --
2023-09-24  6:45 James Tirta Halim
2023-09-24 11:29 ` Xi Ruoyao
2023-09-24 11:43   ` Xi Ruoyao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).