Martin Pelikan <martin.peli...@gmail.com> writes: > Hi! > > Recently, I had to unleash my crappy Atom and decided to run OpenBSD on it. > Then I became irritated with the performance of most X11 applications, and > started poking around: > - libfreetype.so is quite common > - it does setjmp (disguised as ft_setjmp) quite a lot > - setjmp needs to do sigprocmask > - sigprocmask (I presume) needs the kernel lock.
If you're right that atomic_{clear,set}bits_int is correct and sufficient and actually faster, then all dynamic executables would benefit from this speedup (sigprocmask is used in ld.so(1)). > sigprocmask(2) is quite simple actually, but wasn't marked as NOLOCK, > so I made it so. And then I made a pointless test to demonstrate my point, > and ran it on my pointless Atom N270 (two threads, one core from 1980s) > as well as in VMware, which is the only 4-core amd64 machine I can get > on right now. (did I say anything about using virtual machines to measure > things?) > > #include <setjmp.h> > > int > main(void) > { > jmp_buf env; > unsigned i; > > /* on amd64 this was too slow, so 20M was used instead */ > for (i = 0; i < 4000000; ++i) { > setjmp(env); > } > return (0); > } > > Before: > Atom, i386, single process, 0m3.80s real 0m1.15s user 0m2.50s system > Atom, i386, two processes, 0m4.81s real 0m1.44s user 0m3.09s system > > amd64, single process, i<20M, 0m3.35s real 0m0.65s user 0m2.23s system > amd64, two processes, i<20M, 0m4.48s real 0m0.66s user 0m3.37s system > > After: > Atom, i386, single process, 0m2.93s real 0m0.95s user 0m1.35s system > Atom, i386, two processes, 0m3.67s real 0m1.36s user 0m2.15s system > > amd64, single process, i<20M, 0m2.14s real 0m0.63s user 0m1.12s system > amd64, two processes, i<20M, 0m2.57s real 0m0.57s user 0m1.55s system > > > If anyone has a real test with some real-world application using lots > of setjmps, I'd like to see it. What'd I like to see most, is if does > it work on other architectures and if it is indeed correct. Although > the numbers suggest quite an improvement, bear in mind this kind of > load does not at all resemble any software actually doing useful stuff. > > Any comments? > -- > Martin Pelikan > > > Index: kern/init_sysent.c > =================================================================== > RCS file: /cvs/src/sys/kern/init_sysent.c,v > retrieving revision 1.145 > diff -u -p -r1.145 init_sysent.c > --- kern/init_sysent.c 9 Jun 2013 13:10:27 -0000 1.145 > +++ kern/init_sysent.c 19 Jun 2013 09:49:57 -0000 > @@ -136,7 +136,7 @@ struct sysent sysent[] = { > sys_sigaction }, /* 46 = sigaction */ > { 0, 0, 0, > sys_getgid }, /* 47 = getgid */ > - { 2, s(struct sys_sigprocmask_args), 0, > + { 2, s(struct sys_sigprocmask_args), SY_NOLOCK | 0, > sys_sigprocmask }, /* 48 = sigprocmask */ > { 2, s(struct sys_getlogin_args), 0, > sys_getlogin }, /* 49 = getlogin */ > Index: kern/kern_sig.c > =================================================================== > RCS file: /cvs/src/sys/kern/kern_sig.c,v > retrieving revision 1.152 > diff -u -p -r1.152 kern_sig.c > --- kern/kern_sig.c 1 Jun 2013 04:05:26 -0000 1.152 > +++ kern/kern_sig.c 19 Jun 2013 09:49:57 -0000 > @@ -429,28 +429,25 @@ sys_sigprocmask(struct proc *p, void *v, > syscallarg(sigset_t) mask; > } */ *uap = v; > int error = 0; > - int s; > sigset_t mask; > > *retval = p->p_sigmask; > - mask = SCARG(uap, mask); > - s = splhigh(); > + mask = SCARG(uap, mask) &~ sigcantmask; > > switch (SCARG(uap, how)) { > case SIG_BLOCK: > - p->p_sigmask |= mask &~ sigcantmask; > + atomic_setbits_int(&p->p_sigmask, mask); > break; > case SIG_UNBLOCK: > - p->p_sigmask &= ~mask; > + atomic_clearbits_int(&p->p_sigmask, mask); > break; > case SIG_SETMASK: > - p->p_sigmask = mask &~ sigcantmask; > + p->p_sigmask = mask; > break; > default: > error = EINVAL; > break; > } > - splx(s); > return (error); > } > > Index: kern/syscalls.master > =================================================================== > RCS file: /cvs/src/sys/kern/syscalls.master,v > retrieving revision 1.133 > diff -u -p -r1.133 syscalls.master > --- kern/syscalls.master 9 Jun 2013 13:10:19 -0000 1.133 > +++ kern/syscalls.master 19 Jun 2013 09:49:57 -0000 > @@ -123,7 +123,7 @@ > const struct sigaction *nsa, \ > struct sigaction *osa); } > 47 STD { gid_t sys_getgid(void); } > -48 STD { int sys_sigprocmask(int how, sigset_t mask); } > +48 STD NOLOCK { int sys_sigprocmask(int how, sigset_t mask); } > 49 STD { int sys_getlogin(char *namebuf, u_int namelen); } > 50 STD { int sys_setlogin(const char *namebuf); } > #ifdef ACCOUNTING > -- Jérémie Courrèges-Anglas PGP Key fingerprint: 61DB D9A0 00A4 67CF 2A90 8961 6191 8FBF 06A1 1494