Lock-free shared_ptr on g++/x86, test/review needed

I just added boost/detail/sp_counted_base_gcc_x86.hpp to the CVS. It is not enabled yet, i.e. sp_counted_base.hpp will not include it automatically. If you are interested, please take a look at the file and give it a test run. The easiest way to enable it is to do #include <boost/detail/sp_counted_base_gcc_x86.hpp> #define BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED (or to copy it over sp_counted_base.hpp) before including shared_ptr.hpp. Any comments appreciated. As usual, thanks to Alexander Terekhov for all the help and patience. -- Peter Dimov http://www.pdimov.com

I've also added a new test, libs/smart_ptr/test/weak_ptr_mt_test.cpp It will be helpful if someone with access to a multiprocessor can run it with the new g++/x86 code enabled and report any eventual crashes. ;-)

Peter Dimov wrote: [...]
If you are interested, please take a look at the file
Looks correct, but sill not quite optimal to my taste. A) There's no need to hinder compiler's ability to cache/reorder across increments. So you need neither __volatile__ nor "memory" clobber in increments case (lock prefix is still needed to ensure MP safety of competing read-modify-write operations). B) Something branchless is better for unconditional increments. C) In the case of decrements on weak_count, there's no need to make all clients pay the price of rather expensive interlocked operation even if they don't use weak pointers. I'd use "may not store zero" decrement. You'll need __volatile__ and "memory" as compiler fence, and as for hardware, that initial load does have acquire semantics and lock cmpxchg does have "msync::hsb" which we need here. [...]
thanks to Alexander Terekhov
Thanks to you for helping me to identify the problem with lock() (lack of inter-thread ordering with respect to that access and destruction of control block when the object is expired) in my original sketch. regards, alexander. P.S. When are you going to kick start an incarnation for Itanic with value dependent cmpxchg.rel-vs-cmpxchg.acq? ;-)

Alexander Terekhov wrote:
Peter Dimov wrote: [...]
If you are interested, please take a look at the file
Looks correct, but sill not quite optimal to my taste.
A) There's no need to hinder compiler's ability to cache/reorder across increments. So you need neither __volatile__ nor "memory" clobber in increments case (lock prefix is still needed to ensure MP safety of competing read-modify-write operations).
B) Something branchless is better for unconditional increments.
And unconditional decrements of use_count. I think that "lock inc" without __volatile__ and "memory" clobber for increments, and "lock dec" with __volatile__ and "memory" clobber for decrements of use_count, is the most optimal.
C) In the case of decrements on weak_count, there's no need to make all clients pay the price of rather expensive interlocked operation even if they don't use weak pointers. I'd use "may not store zero" decrement. You'll need __volatile__ and "memory" as compiler fence, and as for hardware, that initial load does have acquire semantics and lock cmpxchg does have "msync::hsb" which we need here.
It's probably better to get rid of cmpxchg loop for weak_count decrements as well. Just do load, compare it with 1, and (if !ZF) "lock dec" it (all inside one __asm__ __volatile__ with "memory" clobber). So now it's safe to get rid of __volatile__ and "memory" clobber for conditional increment in add_ref_lock() using "lock cmpxchg".
[...]
thanks to Alexander Terekhov
Thanks to you for helping me to identify the problem with lock() (lack of inter-thread ordering with respect to that access and destruction of control block when the object is expired) in my original sketch.
regards, alexander.
P.S. When are you going to kick start an incarnation for Itanic with value dependent cmpxchg.rel-vs-cmpxchg.acq? ;-)
and mere {re-}load.acq instead of load->cmpxchg.acq (when count value == 1) in weak_release() with cmpxchg.acq in add_ref_lock(). regards, alexander.

Alexander Terekhov wrote:
Peter Dimov wrote: [...]
If you are interested, please take a look at the file
Looks correct, but sill not quite optimal to my taste.
A) There's no need to hinder compiler's ability to cache/reorder across increments. So you need neither __volatile__ nor "memory" clobber in increments case (lock prefix is still needed to ensure MP safety of competing read-modify-write operations).
Yep. This doesn't make a difference in my tests here (single Athlon).
B) Something branchless is better for unconditional increments.
xadd is branchless; it just returns the old value, whereas inc doesn't. MSVC always generates lock xadd, even for _InterlockedIncrement, BTW. So there's probably no difference between the two. But I don't have a P4 or an Athlon 64 here to verify that. If someone wants to play, the version in the CVS now has atomic_increment; uncomment the one-liner at the top and comment out the __asm__ statement to compare the performance of the two versions.
C) In the case of decrements on weak_count, there's no need to make all clients pay the price of rather expensive interlocked operation even if they don't use weak pointers. I'd use "may not store zero" decrement. You'll need __volatile__ and "memory" as compiler fence, and as for hardware, that initial load does have acquire semantics and lock cmpxchg does have "msync::hsb" which we need here.
I wanted to get it to work first ;-) void release() // nothrow { if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) { dispose(); if( (long volatile&)weak_count_ == 1 ) // no weak ptrs { destroy(); } else { weak_release(); } } } ?
P.S. When are you going to kick start an incarnation for Itanic with value dependent cmpxchg.rel-vs-cmpxchg.acq? ;-)
IA64 assembly by hand? No thanks. I'll probably use _Interlocked* on Intel and __sync_* on g++. But x86 and PPC (CW and g++ versions) have priority over IA64.

Peter Dimov wrote: [...]
xadd is branchless; it just returns the old value, whereas inc doesn't. MSVC always generates lock xadd, even for _InterlockedIncrement, BTW.
Well, maybe. But you need value neither for increments nor decrements. (I mean that for decrements you can simply rely on ZF flag). Oder? [...]
void release() // nothrow { if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) { dispose();
if( (long volatile&)weak_count_ == 1 ) // no weak ptrs { destroy(); } else { weak_release(); } } }
?
Nah. For the sake of killing C/C++ volatiles rather sooner than later, I strongly suggest that you hide that load in asm. Just add load+cmp followed by ZF branch prior to "lock dec" which also sets ZF, IIRC. regards, alexander.

Alexander Terekhov wrote:
Peter Dimov wrote: [...]
xadd is branchless; it just returns the old value, whereas inc doesn't. MSVC always generates lock xadd, even for _InterlockedIncrement, BTW.
Well, maybe. But you need value neither for increments nor decrements. (I mean that for decrements you can simply rely on ZF flag). Oder?
I don't need the value, but it doesn't matter; it's just as fast. Or just as slow. x86 isn't very predictable (I don't know how familiar you are with it); some instructions look better on paper but are (or were) actually slower (on 586 and above) than an equivalent RISC-style read/modify/write sequence, inc included. And of course the rules change with every generation (in some cases, sub-generation) of CPUs. Basically, the only way to know which is faster is to measure it.
Nah. For the sake of killing C/C++ volatiles rather sooner than later, I strongly suggest that you hide that load in asm. Just add load+cmp followed by ZF branch prior to "lock dec" which also sets ZF, IIRC.
Eh, __asm__ is no better than a volatile. Both are non-portable. Yes, dec sets ZF (and SF). That's why InterlockedDecrement on 386 returns +1, 0 or -1 instead of the actual value. :-)

Peter Dimov wrote: [...]
I don't need the value, but it doesn't matter; it's just as fast. Or just as slow. x86 isn't very predictable (I don't know how familiar you are with it); some instructions look better on paper but are (or were) actually
1996 or 1997 was the last time I wrote something in x86 asm. On "Blue Lightning 486."
slower (on 586 and above) than an equivalent RISC-style read/modify/write sequence, inc included. And of course the rules change with every generation (in some cases, sub-generation) of CPUs.
Basically, the only way to know which is faster is to measure it.
Nah. For the sake of killing C/C++ volatiles rather sooner than later, I strongly suggest that you hide that load in asm. Just add load+cmp followed by ZF branch prior to "lock dec" which also sets ZF, IIRC.
Eh, __asm__ is no better than a volatile. Both are non-portable.
Except that volatile has defined semantics (both must die too in favor of threads and exceptions) that has really nothing to do with multiple threads and msync. I mean "decoration function" for sig_atomic_t statics and setjmp/longjmp()-sensitive locals in C and POSIX (C++ aside for a moment). "Promotion" of volatile mess is much worse than use of good asm, I think. regards, alexander.

Alexander Terekhov wrote:
Peter Dimov wrote:
Eh, __asm__ is no better than a volatile. Both are non-portable.
Except that volatile has defined semantics (both must die too in favor of threads and exceptions) that has really nothing to do with multiple threads and msync. I mean "decoration function" for sig_atomic_t statics and setjmp/longjmp()-sensitive locals in C and POSIX (C++ aside for a moment).
Yes, but in this case threads are not a problem (we're in release, destroying the last remaining shared_ptr; if we read weak_count_ == 1, no other thread can be creating/destroying weak pointers because of basic guarantee). Msync is not a problem because we've just acquired in the decrement. Now that I think of it, compiler value propagation isn't a problem either because of the "memory" clobber on the decrement. So the cast to volatile can be removed. void release() // nothrow { if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) { dispose(); if( weak_count_ == 1 ) // no weak ptrs { destroy(); } else { weak_release(); } } }

Peter Dimov wrote: [...]
Yes, but in this case threads are not a problem (we're in release, destroying the last remaining shared_ptr; if we read weak_count_ == 1, no other thread can be creating/destroying weak pointers because of basic guarantee). Msync is not a problem because we've just acquired in the decrement.
Yeah. Hello Peter, remember original void release() throw() { if (!use_count_.decrement()) { // "full" release-acquire protocol dispose(); if (!self_count_.decrement(msync::rel, count::may_not_store_min)) destruct(); } } ? (msync::rel on self_count_.decrement() was meant for "result is not min" case only; with naked op for "old value == min + 1" case.) Sure, it can be safely transformed to void release() throw() { if (!use_count_.decrement()) { // "full" release-acquire protocol dispose(); if (self_count_.load(msync::naked_competing) == 1 || // min == 0 !self_count_.decrement(msync::rel)) destruct(); } } but ...
Now that I think of it, compiler value propagation isn't a problem either because of the "memory" clobber on the decrement. So the cast to volatile can be removed.
void release() // nothrow { if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) { dispose();
if( weak_count_ == 1 ) // no weak ptrs
(this doesn't convey the notion of (potentially) competing accesses; who says that implementation can't read it bit-after-bit-and-sum-it, bytes aside for a moment... just for the sake of breaking your logic?)
{ destroy(); } else { weak_release(); } } }
... you also have and manage client-provided "deleter" objects and I see no reason why weak_ptr clients may NOT have access to them (resulting in similar problem with respect to access and destruction as with Whitehead's mutex). So to be safe, you need void release() throw() { if (!use_count_.decrement()) { // "full" release-acquire protocol dispose(); if (self_count_.load(msync::ccacq) == 1 || // min == 0 !self_count_.decrement()) // "full" release-acquire protocol destruct(); } // "full" means either "value dependent" or fully-fenced operation } So again, http://gcc.gnu.org/ml/libstdc++/2005-04/msg00000.html I suggest that you hide that access in asm (and consider using the same operation in weak_release() too... for the sake of KISS-on-IA32 and "easy" porting to RISC archs, where "count::may_not_store_min" is surely better in both release() and weak_release()). regards, alexander.

Alexander Terekhov wrote:
Peter Dimov wrote:
Now that I think of it, compiler value propagation isn't a problem either because of the "memory" clobber on the decrement. So the cast to volatile can be removed.
void release() // nothrow { if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) { dispose();
if( weak_count_ == 1 ) // no weak ptrs
(this doesn't convey the notion of (potentially) competing accesses; who says that implementation can't read it bit-after-bit-and-sum-it, bytes aside for a moment... just for the sake of breaking your logic?)
Hm. You are right in theory, but in practice, I know that this is g++ on x86, and I know that it doesn't do such things. (Aside: why invent naked_competing instead of just using nsync as per PL2?)
{ destroy(); } else { weak_release(); } } }
... you also have and manage client-provided "deleter" objects and I see no reason why weak_ptr clients may NOT have access to them (resulting in similar problem with respect to access and destruction as with Whitehead's mutex).
Hmmmm. IIUC, you are saying that a thread can obtain access to the deleter using get_deleter, then hold on to the returned pointer after the shared_ptr is destroyed while holding only a weak_ptr to the object to keep the deleter alive? I'm having trouble picturing a situation where disallowing this will be a problem. Via the pointer you can only _read_ the deleter safely, and only if its operator() is const (because operator() can be called at any time.) Hence, you could have performed the reads beforehand, while still holding a shared_ptr. This aside, is this a problem on x86? I don't think it is since the load has acquire semantics either way.

Peter Dimov wrote: [...]
Hm. You are right in theory, but in practice, I know that this is g++ on x86, and I know that it doesn't do such things.
(Aside: why invent naked_competing instead of just using nsync as per PL2?)
G++ is (relatively) easy to patch, and naked_competing simply sounds better. ;-) [...]
... you also have and manage client-provided "deleter" objects and I see no reason why weak_ptr clients may NOT have access to them (resulting in similar problem with respect to access and destruction as with Whitehead's mutex).
Hmmmm.
IIUC, you are saying that a thread can obtain access to the deleter using get_deleter, then hold on to the returned pointer after the shared_ptr is destroyed while holding only a weak_ptr to the object to keep the deleter alive?
Not necessarily just to keep the deleter alive. But ok, why not?
I'm having trouble picturing a situation where disallowing this will be a problem.
I'd rather provide template<class D, class T> D * get_deleter(weak_ptr<T> const & p); in addition to your existing template<class D, class T> D * get_deleter(shared_ptr<T> const & p);
Via the pointer you can only _read_ the deleter safely, and only if its operator() is const (because operator() can be called at any time.) Hence, you could have performed the reads beforehand, while still holding a shared_ptr.
Deleter can synchronize mutations (which might be caused by both shared_ptr and weak_ptr clients) internally with or *without* locks (using some lock-free stuff).
This aside, is this a problem on x86?
No.
I don't think it is since the load has acquire semantics either way.
Right. But I'd still (apart from evil-but-lawful G++ patches/new versions theory, not current practice) hide it in asm'd "may not store zero" decrement. regards, alexander.

Peter Dimov wrote: [...]
P.S. When are you going to kick start an incarnation for Itanic with value dependent cmpxchg.rel-vs-cmpxchg.acq? ;-)
IA64 assembly by hand? No thanks. I'll probably use _Interlocked* on Intel and __sync_* on g++.
That would mean expensive "mf" everywhere. http://gcc.gnu.org/ml/libstdc++/2005-04/msg00059.html http://gcc.gnu.org/ml/libstdc++/2005-04/msg00060.html Not good for Itanic which reportedly speculates and reorders like crazy. asm long atomic_decrement_weak( register long * pw ) { loop: <load-UNordered> <add -1> <branch if zero to acquire> <cmpxchg.rel> <branch if failed to loop else to done> acquire: <ld.acq> <add -1> <branch if !zero to acquire> done: <...> } asm long atomic_decrement_strong( register long * pw ) { loop: <load-UNordered> <add -1> <branch if zero to acquire> <cmpxchg.rel> <branch if failed to loop else to done> acquire: <cmpxchg.acq> <branch if failed to loop else to done> done: <...> } Oder? regards, alexander. P.S. For naked stuff, it is probably better to use ".rel", not more-speculation-hindering ".acq". Too bad Itanic doesn't have naked "semaphores"...

"Peter Dimov" <pdimov@mmltd.net> writes:
I just added boost/detail/sp_counted_base_gcc_x86.hpp to the CVS. It is not enabled yet, i.e. sp_counted_base.hpp will not include it automatically.
If you are interested, please take a look at the file and give it a test run. The easiest way to enable it is to do
#include <boost/detail/sp_counted_base_gcc_x86.hpp> #define BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
(or to copy it over sp_counted_base.hpp) before including shared_ptr.hpp. Any comments appreciated.
As usual, thanks to Alexander Terekhov for all the help and patience.
After building a copy fresh from the repository, I altered all of the files in libs/smart_ptr/test as instructed above. I am using a locally build gcc 3.4.3 on Redhat. I received quite a few compiler errors, which I've attached below. Robert Zeh razeh@lb1:/home/razeh/boost/libs/smart_ptr/test$ bjam ...found 335 targets... ...updating 39 targets... gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.o" "../../../libs/smart_ptr/test/get_deleter_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.o... ...removing ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.o ...skipped <@boost!libs!smart_ptr!test/get_deleter_test.test/gcc/debug>get_deleter_test for lack of <@boost!libs!smart_ptr!test/get_deleter_test.test/gcc/debug>get_deleter_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o" "../../../libs/smart_ptr/test/shared_from_this_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o... ...removing ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o ...skipped <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test for lack of <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o" "../../../libs/smart_ptr/test/weak_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o... ...removing ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o ...skipped <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test for lack of <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o" "../../../libs/smart_ptr/test/shared_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o... ...removing ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o ...skipped <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test for lack of <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o" "../../../libs/smart_ptr/test/shared_ptr_basic_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o... ...removing ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o ...skipped <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test for lack of <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.o" "../../../libs/smart_ptr/test/smart_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.o... ...removing ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.o ...skipped <@boost!libs!smart_ptr!test/smart_ptr_test.test/gcc/debug>smart_ptr_test for lack of <@boost!libs!smart_ptr!test/smart_ptr_test.test/gcc/debug>smart_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_delete_fail.test/gcc/debug/shared_ptr_delete_fail.o ../../../libs/smart_ptr/test/shared_ptr_delete_fail.cpp: In function `int main()': ../../../libs/smart_ptr/test/shared_ptr_delete_fail.cpp:27: error: type `class boost::shared_ptr<int>' argument given to `delete', expected pointer gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_assign_fail.test/gcc/debug/shared_ptr_assign_fail.o ../../../libs/smart_ptr/test/shared_ptr_assign_fail.cpp: In function `int main()': ../../../libs/smart_ptr/test/shared_ptr_assign_fail.cpp:32: error: no match for 'operator=' in 'p = (((int*)operator new(4u)), (((*<anonymous>) <unknown operator> 42), <anonymous>))' /home/razeh/boost/boost/shared_ptr.hpp:146: note: candidates are: boost::shared_ptr<T>& boost::shared_ptr<T>::operator=(const boost::shared_ptr<T>&) [with T = int] ...skipped <@boost!libs!smart_ptr!test/smart_ptr_test.test/gcc/debug>smart_ptr_test.run for lack of <@boost!libs!smart_ptr!test/smart_ptr_test.test/gcc/debug>smart_ptr_test... ...removing outdated ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.test ...skipped <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test.run for lack of <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test... ...removing outdated ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.test ...skipped <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test.run for lack of <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test... ...removing outdated ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.test ...skipped <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test.run for lack of <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test... ...removing outdated ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.test ...skipped <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test.run for lack of <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test... ...removing outdated ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.test ...skipped <@boost!libs!smart_ptr!test/get_deleter_test.test/gcc/debug>get_deleter_test.run for lack of <@boost!libs!smart_ptr!test/get_deleter_test.test/gcc/debug>get_deleter_test... ...removing outdated ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test.test (failed-as-expected) ../../../bin/boost/libs/smart_ptr/test/shared_ptr_assign_fail.test/gcc/debug/shared_ptr_assign_fail.o **passed** ../../../bin/boost/libs/smart_ptr/test/shared_ptr_assign_fail.test/gcc/debug/shared_ptr_assign_fail.test (failed-as-expected) ../../../bin/boost/libs/smart_ptr/test/shared_ptr_delete_fail.test/gcc/debug/shared_ptr_delete_fail.o **passed** ../../../bin/boost/libs/smart_ptr/test/shared_ptr_delete_fail.test/gcc/debug/shared_ptr_delete_fail.test ...failed updating 6 targets... ...skipped 18 targets... ...updated 15 targets...

Robert Zeh wrote: [...]
I am using a locally build gcc 3.4.3 on Redhat. [...] /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm'
http://gcc.gnu.org/ml/gcc/2004-04/msg01455.html http://gcc.gnu.org/ml/gcc/2005-03/msg00082.html (Not that I really understand what's the beef here...) regards, alexander.

Alexander Terekhov wrote:
Robert Zeh wrote: [...]
I am using a locally build gcc 3.4.3 on Redhat. [...] /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm'
http://gcc.gnu.org/ml/gcc/2004-04/msg01455.html http://gcc.gnu.org/ml/gcc/2005-03/msg00082.html
(Not that I really understand what's the beef here...)
I think I fixed it as suggested by Richard Henderson in one of the threads.

"Peter Dimov" <pdimov@mmltd.net> writes:
Alexander Terekhov wrote:
Robert Zeh wrote: [...]
I am using a locally build gcc 3.4.3 on Redhat. [...] /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' http://gcc.gnu.org/ml/gcc/2004-04/msg01455.html http://gcc.gnu.org/ml/gcc/2005-03/msg00082.html (Not that I really understand what's the beef here...)
I think I fixed it as suggested by Richard Henderson in one of the threads.
Have you committed the fixes to CVS? I just did an CVS update, and the build is still failing. Robert Zeh http://home.earthlink.net/~rzeh

Robert Zeh wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Alexander Terekhov wrote:
Robert Zeh wrote: [...]
I am using a locally build gcc 3.4.3 on Redhat. [...] /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' http://gcc.gnu.org/ml/gcc/2004-04/msg01455.html http://gcc.gnu.org/ml/gcc/2005-03/msg00082.html (Not that I really understand what's the beef here...)
I think I fixed it as suggested by Richard Henderson in one of the threads.
Have you committed the fixes to CVS? I just did an CVS update, and the build is still failing.
I did, but if you are using anonymous CVS, you may still be getting the older version. I've attached the new version.

"Peter Dimov" <pdimov@mmltd.net> writes:
Robert Zeh wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Alexander Terekhov wrote:
Robert Zeh wrote: [...]
I am using a locally build gcc 3.4.3 on Redhat. [...] /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_exchange_and_add(long int*, long int)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: warning: matching constraint does not allow a register /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:50: error: inconsistent operand constraints in an `asm' http://gcc.gnu.org/ml/gcc/2004-04/msg01455.html http://gcc.gnu.org/ml/gcc/2005-03/msg00082.html (Not that I really understand what's the beef here...)
I think I fixed it as suggested by Richard Henderson in one of the threads.
Have you committed the fixes to CVS? I just did an CVS update, and the build is still failing.
I did, but if you are using anonymous CVS, you may still be getting the older version.
I've attached the new version.
That removed some of the errors. Now I'm getting: razeh@lb1:/home/razeh/boost/libs/smart_ptr/test$ bjam ...found 335 targets... ...updating 31 targets... gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = V, T = V]' /home/razeh/boost/boost/enable_shared_from_this.hpp:49: instantiated from `boost::shared_ptr<T> boost::enable_shared_from_this<T>::shared_from_this() [with T = V]' ../../../libs/smart_ptr/test/shared_from_this_test.cpp:129: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o" "../../../libs/smart_ptr/test/shared_from_this_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o... ...skipped <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test for lack of <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = int, T = int]' ../../../libs/smart_ptr/test/weak_ptr_test.cpp:113: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o" "../../../libs/smart_ptr/test/weak_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o... ...skipped <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test for lack of <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = n_constructors::Y, T = n_constructors::Y]' ../../../libs/smart_ptr/test/shared_ptr_test.cpp:763: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o" "../../../libs/smart_ptr/test/shared_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o... ...skipped <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test for lack of <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = X, T = X]' ../../../libs/smart_ptr/test/shared_ptr_basic_test.cpp:234: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o" "../../../libs/smart_ptr/test/shared_ptr_basic_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o... ...skipped <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test for lack of <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test.o... gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test execute-test ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.test ...skipped <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test.run for lack of <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test... ...skipped <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test.run for lack of <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test... ...skipped <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test.run for lack of <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test... ...skipped <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test.run for lack of <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test... execute-test ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test.test ...failed updating 4 targets... ...skipped 12 targets... ...updated 15 targets... razeh@lb1:/home/razeh/boost/libs/smart_ptr/test$

Peter Dimov wrote:
Robert Zeh wrote:
/home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm'
The compiler could have told us which constraint is impossible ;-)
I'll try to update my cygwin g++ to 3.4; apparently, the new backend is less forgiving.
It works with -O1, -O2, -O3, but fails with -O0. Argh.

Peter Dimov wrote:
Peter Dimov wrote:
Robert Zeh wrote:
/home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm'
The compiler could have told us which constraint is impossible ;-)
I'll try to update my cygwin g++ to 3.4; apparently, the new backend is less forgiving.
It works with -O1, -O2, -O3, but fails with -O0. Argh.
Sorry for the noise. The attached should work. I even enabled it in sp_counted_base.

Peter Dimov wrote: [...]
------------------------------------------------------------------------ Name: sp_counted_base_gcc_x86.hpp sp_counted_base_gcc_x86.hpp Type: unspecified type (application/octet-stream) Encoding: 7bit
You can remove __volatile__ decorator and "memory" from clobber clause inside atomic_conditional_increment(). regards, alexander,

Peter Dimov wrote: [...]
------------------------------------------------------------------------ Name: sp_counted_base_gcc_x86.hpp sp_counted_base_gcc_x86.hpp Type: unspecified type (application/octet-stream) Encoding: 7bit
You can remove __volatile__ decorator and "memory" from clobber clause inside atomic_conditional_increment(). regards, alexander,

"Peter Dimov" <pdimov@mmltd.net> writes:
Peter Dimov wrote:
Peter Dimov wrote:
Robert Zeh wrote:
/home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm'
The compiler could have told us which constraint is impossible ;-)
I'll try to update my cygwin g++ to 3.4; apparently, the new backend is less forgiving.
It works with -O1, -O2, -O3, but fails with -O0. Argh.
Sorry for the noise. The attached should work. I even enabled it in sp_counted_base.
Now I get the following (gcc 3.4.3) razeh@lb1:/home/host/razeh$ cd /home/razeh/boost/libs/smart_ptr/test/ razeh@lb1:/home/razeh/boost/libs/smart_ptr/test$ bjam ...found 335 targets... ...updating 31 targets... gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = V, T = V]' /home/razeh/boost/boost/enable_shared_from_this.hpp:49: instantiated from `boost::shared_ptr<T> boost::enable_shared_from_this<T>::shared_from_this() [with T = V]' ../../../libs/smart_ptr/test/shared_from_this_test.cpp:129: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o" "../../../libs/smart_ptr/test/shared_from_this_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_from_this_test.test/gcc/debug/shared_from_this_test.o... ...skipped <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test for lack of <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = int, T = int]' ../../../libs/smart_ptr/test/weak_ptr_test.cpp:113: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o" "../../../libs/smart_ptr/test/weak_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/weak_ptr_test.test/gcc/debug/weak_ptr_test.o... ...skipped <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test for lack of <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = n_constructors::Y, T = n_constructors::Y]' ../../../libs/smart_ptr/test/shared_ptr_test.cpp:763: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o" "../../../libs/smart_ptr/test/shared_ptr_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_test.test/gcc/debug/shared_ptr_test.o... ...skipped <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test for lack of <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test.o... gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp: In function `long int boost::detail::atomic_conditional_increment(long int*)': /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:94: instantiated from `boost::shared_ptr<T>::shared_ptr(const boost::weak_ptr<Y>&) [with Y = X, T = X]' ../../../libs/smart_ptr/test/shared_ptr_basic_test.cpp:234: instantiated from here /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' set -e "g++" -c -Wall -ftemplate-depth-255 -g -O0 -fno-inline -Wno-non-virtual-dtor -I"../../../bin/boost/libs/smart_ptr/test" -I "/home/razeh/boost" -o "../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o" "../../../libs/smart_ptr/test/shared_ptr_basic_test.cpp" "/usr/bin/objcopy" --set-section-flags .debug_str=contents,debug "../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o" ...failed gcc-C++-action ../../../bin/boost/libs/smart_ptr/test/shared_ptr_basic_test.test/gcc/debug/shared_ptr_basic_test.o... ...skipped <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test for lack of <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test.o... gcc-Link-action ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test Chmod1 ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test execute-test ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/smart_ptr_test.test/gcc/debug/smart_ptr_test.test ...skipped <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test.run for lack of <@boost!libs!smart_ptr!test/shared_ptr_basic_test.test/gcc/debug>shared_ptr_basic_test... ...skipped <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test.run for lack of <@boost!libs!smart_ptr!test/shared_ptr_test.test/gcc/debug>shared_ptr_test... ...skipped <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test.run for lack of <@boost!libs!smart_ptr!test/weak_ptr_test.test/gcc/debug>weak_ptr_test... ...skipped <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test.run for lack of <@boost!libs!smart_ptr!test/shared_from_this_test.test/gcc/debug>shared_from_this_test... execute-test ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/get_deleter_test.test/gcc/debug/get_deleter_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/intrusive_ptr_test.test/gcc/debug/intrusive_ptr_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/atomic_count_test.test/gcc/debug/atomic_count_test.test execute-test ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test.run **passed** ../../../bin/boost/libs/smart_ptr/test/lw_mutex_test.test/gcc/debug/lw_mutex_test.test ...failed updating 4 targets... ...skipped 12 targets... ...updated 15 targets... razeh@lb1:/home/razeh/boost/libs/smart_ptr/test$

"Peter Dimov" <pdimov@mmltd.net> writes:
Peter Dimov wrote:
Robert Zeh wrote:
Now I get the following (gcc 3.4.3) /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' Hmm, the same message as before.
Please try again with the attached. ;-)
Everything builds! Robert

Robert Zeh wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Peter Dimov wrote:
Robert Zeh wrote:
Now I get the following (gcc 3.4.3) /home/razeh/boost/boost/detail/sp_counted_base_gcc_x86.hpp:91: error: impossible constraint in `asm' Hmm, the same message as before.
Please try again with the attached. ;-)
Everything builds!
Splendid, thank you. It's still not quite "by the book", because I'm using a hardcoded ebx as a temporary register, but I least I got the constraints/clobbers right. Someone should submit a GCC patch to improve its diagnostic output for these cases. :-)
participants (3)
-
Alexander Terekhov
-
Peter Dimov
-
Robert Zeh