atomic cas, again; PHP this time (was Re: Please review this diff for atomic ops in mesa on m68k)
- To: debian-68k@lists.debian.org
- Subject: atomic cas, again; PHP this time (was Re: Please review this diff for atomic ops in mesa on m68k)
- From: Thorsten Glaser <tg@mirbsd.de>
- Date: Sun, 11 Mar 2012 16:26:50 +0000 (UTC)
- Message-id: <[🔎] Pine.BSM.4.64L.1203111618330.24179@herc.mirbsd.org>
- In-reply-to: <CAMuHMdUnLPQgg7k4mutOyx6gtginqKQj1f2xdjHCnAJg+i59UQ@mail.gmail.com>
- References: <Pine.BSM.4.64L.1201100853170.20819@herc.mirbsd.org> <CAMuHMdUnLPQgg7k4mutOyx6gtginqKQj1f2xdjHCnAJg+i59UQ@mail.gmail.com>
Geert Uytterhoeven dixit:
>CAS is a read-modify-write instruction, which is not guaranteed to work
>on all m68k platforms (hence the existence of CONFIG_RMW_INSNS in
>the kernel).
Hi,
this issue is popping up again with the php5-fpm SAPI, which wants
__sync_bool_compare_and_swap (and uses that if available).
I’m a bit concerned about performance (strace already shows a LOT
of SYS_333 calls since TLS). On what m68k platforms is cas.l safe
and is there a sane set of #if to check for it? Or do we really
have to use the syscall, all the time? (This question being the
main reason for me to write this mail – after all, I’m not fully
familiar with m68k specifics, nor with whether or how a MMU Linux
Coldfire port would deal with things or whether there are plans
to really do one.)
Is there a reusable example of how to use the syscall from generic
user-space code? It’s not really in any eglibc header, I think… at
least I didn’t find it.
The fpm SAPI uses this in the GCC builtin case:
|typedef volatile unsigned long atomic_t;
|#define atomic_cmp_set(a,b,c) __sync_bool_compare_and_swap(a,b,c)
I think this comes closest to the code in libatomic-ops-dev
from reading the inline asm versions of the above, which are
used when the GCC builtin isn’t available:
|typedef unsigned long AO_t __attribute__ ((aligned (4)));
|/* Returns nonzero if the comparison succeeded. */
|AO_INLINE int
|AO_compare_and_swap_full(volatile AO_t *addr,
| AO_t old, AO_t new_val)
|{
| char result;
|
| __asm__ __volatile__(
| "cas.l %3,%4,%1; seq %0"
| : "=d" (result), "=m" (*addr)
| : "m" (*addr), "d" (old), "d" (new_val)
| : "memory");
| return -result;
|}
Need to see whether result must be inversed for PHP, of course,
and why does the libatomic-ops-dev code not use volatile?
bye,
//mirabilos
--
15:39⎜«mika:#grml» mira|AO: "mit XFree86® wär’ das nicht passiert" - muhaha
15:48⎜<thkoehler:#grml> also warum machen die xorg Jungs eigentlich alles
kaputt? :) 15:49⎜<novoid:#grml> thkoehler: weil sie als Kinder nie den
gebauten Turm selber umschmeissen durften? -- ~/.Xmodmap wonders…
Reply to: