[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