[prev in list] [next in list] [prev in thread] [next in thread] 

List:       uclinux-dev
Subject:    Re: [uClinux-dev] Threading and synchronization questions
From:       Mike Frysinger <vapier () gentoo ! org>
Date:       2009-04-13 13:45:28
Message-ID: 200904130945.29646.vapier () gentoo ! org
[Download RAW message or body]

[Attachment #2 (multipart/signed)]


On Monday 13 April 2009 09:29:00 Jamie Lokier wrote:
> Mike Frysinger wrote:
> > > You have to test the result of clone() before calling _exit().  How do
> > > you guarantee the compiler inserts no memory writes in that sequence
> > > using just INTERNAL_SYSCALL on all architectures?
> >
> > there is no guarantee of course, but i declare the storage of the
> > return value of clone with "register", so that seems to be "good
> > enough".  i reviewed the disassembly on a few arches and they all
> > look correct.  just dont build with optimization turned off ;).
>
> I think it's a really bad idea to depend on optimization (and no
> bb-profiling perhaps?) for correct code!

in general, sure.  when talking low level C library, not really.  the ldso 
already requires -O1+ in order to operate correctly.  glibc requires -O1+ for 
pretty much everything.  the Linux kernel too (although in many cases there, i 
think people are just being lazy).

> The x86 syscall does touch the stack: it pushes %ebx when __PIC__.  I
> know we're not doing NOMMU x86, but it shows how fragile depending on
> the C macros is.

indeed.  that'll probably not work, but as you point out, ive never heard of a 
x86 w/out a mmu let alone Linux support for it ...

> I think it would be best to have arch-specific fork_exit.S, in the
> same way that there's arch-specific vfork.S.  It's obviously very
> small, and it's easy to use the compiler output from your C version to
> check and write the .S for all architectures :-)

easier to be lazy: have common/fork_exit.c which uses my existing C 
implementation and then each arch can override it if they want with 
arch/fork_exit.S.

> Alternatively, a kernel flag CLONE_PARENT_EXIT would be a nice generic
> solution, but that doesn't have the niceness of working with old
> kernels.

yeah, that would be nicer, but i dont want to go through the lkml hassle 
trying to convince them too ;)

> > the Blackfin assembly for example is:
> >   18:   a0 00           EXCPT 0x0;	/* syscall(clone) */
> >   1a:   ea 63           R2 = -0x3 (X);
> >   1c:   08 30           R1 = R0;
> >   1e:   f8 67           R0 += -0x1;
> >   20:   10 0a           CC = R0 <= R2 (IU);
> >   22:   03 14           IF !CC JUMP 0x28 <_daemon+0x28> (BP);
> >   24:   08 68           P0 = 0x1 (X);
> >   26:   a0 00           EXCPT 0x0;	/* syscall(exit) */
> > no stack usage by the parent
>
> I'm sure it does work on all the architectures where it's needed.
> (For now).  But it's dubious, and someday someone will add an
> architecture where INTERNAL_SYSCALL touches the stack, causing a rare
> heisenbug in this generic code by accident.
>
> Is that Blackfin code correct?  Wouldn't tight code simply check for
> any result > 0, like this:

the Blackfin code is correct according to the C code that was used.
	if (ret != -1 && ret != 0)

i was thinking of INLINE_SYSCALL() when i wrote the code rather than 
INTERNAL_SYSCALL() (20$ if you deduced the behavior difference without ever 
seeing the code :P).  so the code should read:
	if (ret <= 0)
since the kernel returns negative errno values ... and we make the assumption 
that all negative values are errors for clone() rather than the typical range 
of -1...-4096.
-mike

["signature.asc" (application/pgp-signature)]

_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic