Module: xenomai-gch Branch: for-head Commit: 264b76b939fb2625b091a18133871e874479f97c URL: http://git.xenomai.org/?p=xenomai-gch.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