Module: xenomai-head
Branch: master
Commit: 264b76b939fb2625b091a18133871e874479f97c
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=264b76b939fb2625b091a18133871e874479f97c

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Fri Dec  4 23:27:17 2009 +0100

signals: reduce signals handling memory footprint

---

 include/asm-arm/syscall.h      |    9 +---
 include/asm-blackfin/syscall.h |    8 +---
 include/asm-generic/syscall.h  |   18 ++++----
 include/asm-nios2/syscall.h    |    8 +---
 include/asm-powerpc/syscall.h  |    9 +---
 include/asm-x86/syscall.h      |   93 ++++++++++++++++++---------------------
 src/skins/common/bind.c        |   38 ++++++++++++++++
 7 files changed, 98 insertions(+), 85 deletions(-)

diff --git a/include/asm-arm/syscall.h b/include/asm-arm/syscall.h
index be16e9c..0b51492 100644
--- a/include/asm-arm/syscall.h
+++ b/include/asm-arm/syscall.h
@@ -201,13 +201,6 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
                        err = XENOMAI_DO_SYSCALL_INNER(nr, shifted_id,  \
                                                       op, &sigs, args); \
                        res = xnsig_dispatch(&sigs, res, err);          \
-                                                                       \
-                       while (sigs.nsigs && sigs.remaining) {          \
-                               sigs.nsigs = 0;                         \
-                               err = XENOMAI_DO_SYSCALL_INNER          \
-                                       (0, 0, __xn_sys_get_next_sigs, &sigs); \
-                               res = xnsig_dispatch_next(&sigs, res, err); \
-                       }                                               \
                } while (res == -ERESTART);                             \
                res;                                                    \
        })
@@ -226,6 +219,8 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
        XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
 #define XENOMAI_SYSBIND(a1,a2,a3,a4)                           \
        XENOMAI_DO_SYSCALL(4,0,__xn_sys_bind,a1,a2,a3,a4)
+#define XENOMAI_SYSSIGS(sigs)                                          \
+       XENOMAI_DO_SYSCALL_INNER(0, 0, __xn_sys_get_next_sigs, sigs)
 
 #define XENOMAI_SKINCALL0(id,op)               \
        XENOMAI_DO_SYSCALL(0,id,op)
diff --git a/include/asm-blackfin/syscall.h b/include/asm-blackfin/syscall.h
index 02cc143..9f90611 100644
--- a/include/asm-blackfin/syscall.h
+++ b/include/asm-blackfin/syscall.h
@@ -221,12 +221,6 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
                        __err__ = XENOMAI_DO_SYSCALL_INNER(nr, shifted_id, \
                                                           op, &__sigs__, 
##args); \
                        __res__ = xnsig_dispatch(&__sigs__, __res__, __err__); \
-                       while (__sigs__.nsigs && __sigs__.remaining) {  \
-                               __sigs__.nsigs = 0;                     \
-                               __err__ = XENOMAI_DO_SYSCALL_INNER      \
-                                       (0, 0, __xn_sys_get_next_sigs, 
&__sigs__); \
-                               __res__ = xnsig_dispatch_next(&__sigs__, 
__res__, __err__); \
-                       }                                               \
                } while (__res__ == -ERESTART);                         \
                __res__;                                                \
        })
@@ -238,6 +232,8 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    
XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) 
XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
 #define XENOMAI_SYSBIND(a1,a2,a3,a4)        
XENOMAI_DO_SYSCALL(4,0,__xn_sys_bind,a1,a2,a3,a4)
+#define XENOMAI_SYSSIGS(sigs)                                          \
+       XENOMAI_DO_SYSCALL_INNER(0, 0, __xn_sys_get_next_sigs, sigs)
 
 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_DO_SYSCALL(0,id,op)
 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_DO_SYSCALL(1,id,op,a1)
diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 926498b..483b99f 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -158,10 +158,15 @@ static inline int __xn_safe_strncpy_from_user(char *dst,
 #else /* !__KERNEL__ */
 
 #ifdef __cplusplus
-extern "C"
+extern "C" {
 #endif /* __cplusplus */
 int __xnsig_dispatch(struct xnsig *sigs, int cumulated_error, int last_error);
 
+int __xnsig_dispatch_safe(struct xnsig *sigs, int cumulated_error, int 
last_error);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
 /* Called to dispatch signals which interrupted a system call. */
 static inline int xnsig_dispatch(struct xnsig *sigs, int cumul, int last)
 {
@@ -170,16 +175,11 @@ static inline int xnsig_dispatch(struct xnsig *sigs, int 
cumul, int last)
        return last;
 }
 
-/* Called to dispatch additional signals (received with the special
-   system call __xn_sys_get_next_sigs), it may happen that this
-   syscall was in fact called whereas no additional signal was
-   pending, in this case, ignore the syscall return value (last) and
-   preserve the cumulated error. */
-static inline int xnsig_dispatch_next(struct xnsig *sigs, int cumul, int last)
+static inline int xnsig_dispatch_safe(struct xnsig *sigs, int cumul, int last)
 {
        if (sigs->nsigs)
-               return __xnsig_dispatch(sigs, cumul, last);
-       return cumul;
+               return __xnsig_dispatch_safe(sigs, cumul, last);
+       return last;
 }
 
 #endif /* !__KERNEL__ */
diff --git a/include/asm-nios2/syscall.h b/include/asm-nios2/syscall.h
index 98fea53..6dd81cb 100644
--- a/include/asm-nios2/syscall.h
+++ b/include/asm-nios2/syscall.h
@@ -241,12 +241,6 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
                        __err__ = XENOMAI_DO_SYSCALL_INNER(nr, shifted_id,      
\
                                                       op, &__sigs__, ##args);  
\
                        __res__ = xnsig_dispatch(&__sigs__, __res__, __err__);  
\
-                       while (__sigs__.nsigs && __sigs__.remaining) {  \
-                               __sigs__.nsigs = 0;                     \
-                               __err__ = XENOMAI_DO_SYSCALL_INNER      \
-                                       (0, 0, __xn_sys_get_next_sigs, 
&__sigs__);      \
-                               __res__ = xnsig_dispatch_next(&__sigs__, 
__res__, __err__); \
-                       }                                               \
                } while (__res__ == -ERESTART);                         \
                __res__;                                                \
        })
@@ -258,6 +252,8 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    
XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) 
XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
 #define XENOMAI_SYSBIND(a1,a2,a3,a4)        
XENOMAI_DO_SYSCALL(4,0,__xn_sys_bind,a1,a2,a3,a4)
+#define XENOMAI_SYSSIGS(sigs)                                          \
+       XENOMAI_DO_SYSCALL_INNER(0, 0, __xn_sys_get_next_sigs, sigs)
 
 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_DO_SYSCALL(0,id,op)
 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_DO_SYSCALL(1,id,op,a1)
diff --git a/include/asm-powerpc/syscall.h b/include/asm-powerpc/syscall.h
index 3190035..6db8667 100644
--- a/include/asm-powerpc/syscall.h
+++ b/include/asm-powerpc/syscall.h
@@ -147,13 +147,6 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
                        err = XENOMAI_DO_SYSCALL_INNER(nr, shifted_id,  \
                                                       op, &sigs, args); \
                        res = xnsig_dispatch(&sigs, res, err);          \
-                                                                       \
-                       while (sigs.nsigs && sigs.remaining) {          \
-                               sigs.nsigs = 0;                         \
-                               err = XENOMAI_DO_SYSCALL_INNER          \
-                                       (0, 0, __xn_sys_get_next_sigs, &sigs); \
-                               res = xnsig_dispatch_next(&sigs, res, err); \
-                       }                                               \
                } while (res == -ERESTART);                             \
                res;                                                    \
        })
@@ -165,6 +158,8 @@ static inline int __xn_interrupted_p(struct pt_regs *regs)
 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    
XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) 
XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
 #define XENOMAI_SYSBIND(a1,a2,a3,a4)        
XENOMAI_DO_SYSCALL(4,0,__xn_sys_bind,a1,a2,a3,a4)
+#define XENOMAI_SYSSIGS(sigs)                                          \
+       XENOMAI_DO_SYSCALL_INNER(0, 0, __xn_sys_get_next_sigs, sigs)
 
 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_DO_SYSCALL(0,id,op)
 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_DO_SYSCALL(1,id,op,a1)
diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h
index 7b6aa20..13a7a07 100644
--- a/include/asm-x86/syscall.h
+++ b/include/asm-x86/syscall.h
@@ -25,6 +25,26 @@
 #define __xn_mux_code(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 
0x7fff))
 #define __xn_mux_shifted_id(id) ((id << 16) & 0xff0000)
 
+#ifdef __i386__
+/* On x86_32, we want ebp to be both a valid frame pointer for correct
+   backtraces, and allow kernel-space to find deterministically the
+   starting address of the xnsig structure. So, we build a phony stack
+   frame which contains the xnsig structure.
+
+   Furthermore, since ebp is used by inline assembly to generate
+   references to memory operands, we can not touch it before all
+   memory operands have been referenced, so we make ebp point to this
+   phony frame only for the time of the syscall instruction.
+
+   We rely on the fact that the sigs structure in the first in the frame.
+*/
+struct frame {
+       struct xnsig sigs;
+       void *last_fp;
+       void *fn_addr;
+};
+#endif /* __i386__ */
+
 #ifdef __KERNEL__
 
 #include <linux/errno.h>
@@ -42,7 +62,8 @@
 #define __xn_reg_arg3(regs)   ((regs)->x86reg_dx)
 #define __xn_reg_arg4(regs)   ((regs)->x86reg_si)
 #define __xn_reg_arg5(regs)   ((regs)->x86reg_di)
-#define __xn_reg_sigp(regs)   ((regs)->x86reg_bp - sizeof(struct xnsig))
+#define __xn_reg_sigp(regs)   ((regs)->x86reg_bp                       \
+                              - offsetof(struct frame, last_fp))
 #else /* x86_64 */
 #define __xn_reg_arg1(regs)   ((regs)->x86reg_di)
 #define __xn_reg_arg2(regs)   ((regs)->x86reg_si)
@@ -140,22 +161,6 @@ asm (".L__X'%ebx = 1\n\t"
      ".endif\n\t"
      ".endm\n\t");
 
-/* We want ebp to be both a valid frame pointer for correct backtraces,
-   and allow kernel-space to find deterministically the starting
-   address of the xnsig structure. So, we build a phony stack frame
-   which contains the xnsig structure.
-
-   Furthermore, since ebp is used by inline assembly to generate
-   references to memory operands, we can not touch it before all
-   memory operands have been referenced, so we make ebp point to this
-   phony frame only for the time of the syscall instruction.
-*/
-struct frame {
-       struct xnsig sigs;
-       void *last_fp;
-       void *fn_addr;
-};
-
 static inline void __xn_get_eip(void **dest)
 {
         asm volatile("movl $1f, %0; 1:": "=m"(*dest));
@@ -172,9 +177,10 @@ static inline void __xn_get_ebp(void **dest)
        asm volatile (                                          \
                LOADARGS_##nr                                   \
                "movl %1, %%eax\n\t"                            \
+               "pushl %%ebp\n\t"                               \
                "movl %2, %%ebp\n\t"                            \
                DOSYSCALL                                       \
-               "movl (%%ebp), %%ebp\n\t"                       \
+               "popl %%ebp\n\t"                                \
                RESTOREARGS_##nr                                \
                : "=a" (__resultvar)                            \
                : "i" (__xn_mux_code(0, op)) ASMFMT_##nr(args)  \
@@ -195,13 +201,6 @@ static inline void __xn_get_ebp(void **dest)
                f.sigs.nsigs = 0;                                       \
                err = XENOMAI_SYS_MUX_INNER(nr, op, fp, args);          \
                res = xnsig_dispatch(&f.sigs, res, err);                \
-                                                                       \
-               while (f.sigs.nsigs && f.sigs.remaining) {              \
-                       f.sigs.nsigs = 0;                               \
-                       err = XENOMAI_SYS_MUX_INNER                     \
-                               (0, __xn_sys_get_next_sigs, fp);        \
-                       res = xnsig_dispatch_next(&f.sigs, res, err);   \
-               }                                                       \
        } while (res == -ERESTART);                                     \
        res;                                                            \
 })
@@ -212,9 +211,10 @@ static inline void __xn_get_ebp(void **dest)
        asm volatile (                                          \
                LOADARGS_##nr                                   \
                "movl %1, %%eax\n\t"                            \
+               "pushl %%ebp\n\t"                               \
                "movl %2, %%ebp\n\t"                            \
                DOSYSCALLSAFE                                   \
-               "movl (%%ebp), %%ebp\n\t"                       \
+               "popl %%ebp\n\t"                                \
                RESTOREARGS_##nr                                \
                : "=a" (__resultvar)                            \
                : "i" (__xn_mux_code(0, op)) ASMFMT_##nr(args)  \
@@ -234,14 +234,7 @@ static inline void __xn_get_ebp(void **dest)
        do {                                                            \
                f.sigs.nsigs = 0;                                       \
                err = XENOMAI_SYS_MUX_SAFE_INNER(nr, op, fp, args);     \
-               res = xnsig_dispatch(&f.sigs, res, err);                \
-                                                                       \
-               while (f.sigs.nsigs && f.sigs.remaining) {              \
-                       f.sigs.nsigs = 0;                               \
-                       err = XENOMAI_SYS_MUX_SAFE_INNER                \
-                               (0, __xn_sys_get_next_sigs, fp);        \
-                       res = xnsig_dispatch_next(&f.sigs, res, err);   \
-               }                                                       \
+               res = xnsig_dispatch_safe(&f.sigs, res, err);           \
        } while (res == -ERESTART);                                     \
        res;                                                            \
 })
@@ -253,9 +246,10 @@ static inline void __xn_get_ebp(void **dest)
        asm volatile (                                          \
                LOADARGS_##nr                                   \
                "movl %1, %%eax\n\t"                            \
+               "pushl %%ebp\n\t"                               \
                "movl %2, %%ebp\n\t"                            \
                DOSYSCALL                                       \
-               "movl (%%ebp), %%ebp\n\t"                       \
+               "popl %%ebp\n\t"                                \
                RESTOREARGS_##nr                                \
                : "=a" (__resultvar)                            \
                : "m" (__muxcode) ASMFMT_##nr(args)             \
@@ -276,13 +270,6 @@ static inline void __xn_get_ebp(void **dest)
                f.sigs.nsigs = 0;                                       \
                err = XENOMAI_SKIN_MUX_INNER(nr, shifted_id, op, fp, args); \
                res = xnsig_dispatch(&f.sigs, res, err);                \
-                                                                       \
-               while (f.sigs.nsigs && f.sigs.remaining) {              \
-                       f.sigs.nsigs = 0;                               \
-                       err = XENOMAI_SYS_MUX_INNER                     \
-                               (0, __xn_sys_get_next_sigs, fp);        \
-                       res = xnsig_dispatch_next(&f.sigs, res, err);   \
-               }                                                       \
        } while (res == -ERESTART);                                     \
        res;                                                            \
 })
@@ -320,6 +307,18 @@ static inline void __xn_get_ebp(void **dest)
 #define XENOMAI_SYSBIND(a1,a2,a3,a4) \
        XENOMAI_SYS_MUX_SAFE(4,__xn_sys_bind,a1,a2,a3,a4)
 
+#define XENOMAI_SYSSIGS(sigs)                                  \
+({                                                             \
+       void **volatile fp = &((struct frame *)sigs)->last_fp;  \
+       XENOMAI_SYS_MUX_INNER(0, __xn_sys_get_next_sigs, fp);   \
+})
+
+#define XENOMAI_SYSSIGS_SAFE(sigs)                                     \
+({                                                                     \
+       void **volatile fp = &((struct frame *)sigs)->last_fp;          \
+       XENOMAI_SYS_MUX_SAFE_INNER(0, __xn_sys_get_next_sigs, fp);      \
+})
+
 #else /* x86_64 */
 
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
@@ -396,14 +395,6 @@ static inline void __xn_get_ebp(void **dest)
                sigs.nsigs = 0;                                         \
                err = DO_SYSCALL_INNER(name, nr, &sigs, args);          \
                res = xnsig_dispatch(&sigs, res, err);                  \
-                                                                       \
-               while (sigs.nsigs && sigs.remaining) {                  \
-                       sigs.nsigs = 0;                                 \
-                       err = DO_SYSCALL_INNER                          \
-                               (__xn_mux_code(0,__xn_sys_get_next_sigs), \
-                                0, &sigs);                             \
-                       res = xnsig_dispatch_next(&sigs, res, err);     \
-               }                                                       \
        } while (res == -ERESTART);                                     \
        res;                                                            \
 })
@@ -417,6 +408,8 @@ static inline void __xn_get_ebp(void **dest)
 #define XENOMAI_SYSBIND(a1,a2,a3,a4) \
        XENOMAI_SYS_MUX(4,__xn_sys_bind,a1,a2,a3,a4)
 
+#define XENOMAI_SYSSIGS(sigs)                                  \
+       DO_SYSCALL_INNER(__xn_sys_get_next_sigs, 0, sigs)
 #endif /* x86_64 */
 
 #define XENOMAI_SYSCALL0(op)                   XENOMAI_SYS_MUX(0,op)
diff --git a/src/skins/common/bind.c b/src/skins/common/bind.c
index f84d69e..44017e8 100644
--- a/src/skins/common/bind.c
+++ b/src/skins/common/bind.c
@@ -24,6 +24,7 @@ int __xnsig_dispatch(struct xnsig *sigs, int cumulated_error, 
int last_error)
 {
        unsigned i;
 
+  dispatch:
        for (i = 0; i < sigs->nsigs; i++) {
                xnsighandler *handler;
                
@@ -31,10 +32,47 @@ int __xnsig_dispatch(struct xnsig *sigs, int 
cumulated_error, int last_error)
                if (handler)
                        handler(&sigs->pending[i].si);
        }
+
        if (cumulated_error == -ERESTART)
                cumulated_error = last_error;
+
+       if (sigs->remaining) {
+               sigs->nsigs = 0;
+               last_error = XENOMAI_SYSSIGS(sigs);
+               if (sigs->nsigs)
+                       goto dispatch;
+       }
+
+       return cumulated_error;
+}
+
+#ifdef XENOMAI_SYSSIGS_SAFE
+int __xnsig_dispatch_safe(struct xnsig *sigs, int cumulated_error, int 
last_error)
+{
+       unsigned i;
+
+  dispatch:
+       for (i = 0; i < sigs->nsigs; i++) {
+               xnsighandler *handler;
+               
+               handler = xnsig_handlers[sigs->pending[i].muxid];
+               if (handler)
+                       handler(&sigs->pending[i].si);
+       }
+
+       if (cumulated_error == -ERESTART)
+               cumulated_error = last_error;
+
+       if (sigs->remaining) {
+               sigs->nsigs = 0;
+               last_error = XENOMAI_SYSSIGS_SAFE(sigs);
+               if (sigs->nsigs)
+                       goto dispatch;
+       }
+
        return cumulated_error;
 }
+#endif /* XENOMAI_SYSSIGS_SAFE */
 
 int 
 xeno_bind_skin_opt(unsigned skin_magic, const char *skin, 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to