SYSCALL_CANCEL: reduce the size of generated code

Message ID 1492200452-4653-1-git-send-email-ynorov@caviumnetworks.com
State New, archived
Headers

Commit Message

Yury Norov April 14, 2017, 8:07 p.m. UTC
  SYSCALL_CANCEL() currently calls INLINE_SYSCALL_CALL() both in true and
false branches of the "if (SINGLE_THREAD_P)" condition. If arguments that
passed in INLINE_SYSCALL_CALL() are wrapped with tricky macros or require
other additional handling, the code that does it becomes duplicated, and
it may increase the size of function that use it significantly.

This patch reworks the SYSCALL_CANCEL() to call INLINE_SYSCALL_CALL() only
once. On arm64/ilp32 it reduces the size of sync_file_range.o from 8736 to
7660 bytes.

The sync_file_range() is a simple single-line function though:

int
sync_file_range (int fd, __off64_t offset, __off64_t len, unsigned int flags)
{
  return SYSCALL_CANCEL (sync_file_range2, fd, flags, SYSCALL_LL64 (offset),
			 SYSCALL_LL64 (len));
}

	* sysdeps/unix/sysdep.h: Reduce duplication in SYSCALL_CANCEL() macro.
---
 sysdeps/unix/sysdep.h | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)
  

Comments

Florian Weimer April 15, 2017, 7:37 a.m. UTC | #1
On 04/14/2017 10:07 PM, Yury Norov wrote:
> SYSCALL_CANCEL() currently calls INLINE_SYSCALL_CALL() both in true and
> false branches of the "if (SINGLE_THREAD_P)" condition. If arguments that
> passed in INLINE_SYSCALL_CALL() are wrapped with tricky macros or require
> other additional handling, the code that does it becomes duplicated, and
> it may increase the size of function that use it significantly.

It also widens the window for the race, so I'm not sure if this is a 
good idea.

I think this code will change with the cancellation fixes anyway.

Thanks,
Florian
  

Patch

diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
index 38c2432..f0fa9da 100644
--- a/sysdeps/unix/sysdep.h
+++ b/sysdeps/unix/sysdep.h
@@ -91,14 +91,13 @@ 
 #define SYSCALL_CANCEL(...) \
   ({									     \
     long int sc_ret;							     \
-    if (SINGLE_THREAD_P) 						     \
-      sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__); 			     \
-    else								     \
-      {									     \
-	int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();			     \
-	sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__);			     \
-        LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \
-      }									     \
+    int sc_cancel_oldtype;						     \
+    bool multithread = !SINGLE_THREAD_P;				     \
+    if (multithread)						             \
+      sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();				     \
+    sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__);				     \
+    if (multithread)						             \
+      LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \
     sc_ret;								     \
   })