Topic: Multithreaded programming: is the C++ standardization committee
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Mon, 13 Sep 2004 18:20:22 GMT Raw View
ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
[snip]
> By implicit cancellation polling I mean polling for and reporting of
> cancellation by library calls not directly related to it, which causes
> all this mess. I have no problem with provision for *explicit*
> polling, e.g. pthread_testcancel.
[snip]
Suppose a future C++ w/threads defines all standard library functions
so as to not poll for cancellation, except for
pthread_testcancel().
Then imagine some third-party library implementor calls
pthread_testcancel() in a library function.
As far as the user of the library is concerned, that's implicit
cancellation. So it's a mess that can't be wholly avoided; it can
only be minimized. (I do think that it should be minimized.)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Tue, 14 Sep 2004 04:06:27 GMT Raw View
dave@boost-consulting.com (David Abrahams) writes:
> llewelly.at@xmission.dot.com (llewelly) writes:
>
>> ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
>> [snip]
>>> By implicit cancellation polling I mean polling for and reporting of
>>> cancellation by library calls not directly related to it, which causes
>>> all this mess. I have no problem with provision for *explicit*
>>> polling, e.g. pthread_testcancel.
>> [snip]
>>
>> Suppose a future C++ w/threads defines all standard library functions
>> so as to not poll for cancellation, except for
>> pthread_testcancel().
>>
>> Then imagine some third-party library implementor calls
>> pthread_testcancel() in a library function.
>>
>> As far as the user of the library is concerned, that's implicit
>> cancellation. So it's a mess that can't be wholly avoided;
>> it can only be minimized. (I do think that it should be minimized.)
>
> What mess?
*shrug*
Transfering an error from one reporting mechanism (say, exceptions)
to another (say, to a global record like errno) introduces
complication at the point where the error must be transferred,
and more complication where the error is handled. It's
traditional to refer to complication as 'a mess'.
> That seems fine to me as long as the library function
> is specified to report other kinds of failures anyway.
If the library function wasn't specified to report failures, and yet
it polled for cancellation, I'd use a stronger word than
'mess'. :-)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sat, 11 Sep 2004 17:25:32 GMT Raw View
David Abrahams wrote:
[...]
> > b) In the polling functions, checking whether the exception can be
> > handled before reporting it. As you say, "an enormous amount of
> > complication".
>
> And if it can't be handled you throw, or you don't throw? Isn't "not
> handling" the exception exactly what you need in order to allow the
> thread to terminate? It seems to me that throwing might be just what
> the doctor ordered. Having to put in a catch(cancellation) block just
> to get the thread to terminate seems a little perverse to me.
The standard should simply say that 'execution of each and every
thread' [initial/main including] shall be done "as if"
whatever routine(...whatever...) throw(std::thread_exit,
std::thread_cancel);
is called; that implementation simply catches and finalizes
thread_exit{_value} or thread_cancel{_request} exception (if
thrown) resulting in thread termination and that any other
uncaught exception will end up in std::unexpected() invoked
at throw point. And dtors would have cancellation disabled
by default (unless they can handle it) due to implicit
throw()-nothing ES.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Sun, 12 Sep 2004 16:58:38 GMT Raw View
Falk Tannh=E4user wrote:
> No, a "volatile address" would be of type 'int* volatile'.
> Both '*(volatile int*)&b' and 'const_cast<int volatile&>(b)' denote
> lvalues constituting volatile-qualified access paths to 'b'.
>=20
>> it doesnt say
>> that the assignment to b is volatile. thats brings you back to casting=
to
>> volatile int....
>>
>> (volatile int ) * (volatile int*)&i =3D 4;
>=20
>=20
> I think that '(volatile int)i' has never been an lvalue in C, and I'm
> almost sure it has never been in C++, although some compilers accepted
> it as a "creative extension", with the same semantics as '*(volatile=20
> int*)&i'.
>=20
> Falk
>=20
Thinking about it a little more, I dont feel *(volatile int*)&i is the=20
correct semantic equivalent in C for (volatile int&) i
The problem I see in the C version is noticeable in the following
statement:
*(volatile int*)&i =3D 2;
Here the assignment does not really have volatile semantics. You are=20
saying that the address of 'i' is volatile data. Then you dereference=20
it. On dereferencing what you get is not volatile. And you are assigning=20
to the result of a dereference.
whereas
(volatile int&)i =3D 2;
here the information conveyed to the compiler seems to be different,=20
viz. "assign to something volatile".
Anyone know what would be the correct equivalent in C ?
or does an equivalent even exist ?
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Thu, 9 Sep 2004 09:53:11 GMT Raw View
Ben Hutchings wrote:
[... 2-phase EH ...]
> Please distinguish between "shall" and "should". You know that this
> is not actually possible in some existing exception implementations,
You mean single phase setjmp/longjmp stuff? See
http://groups.google.com/groups?selm=3EEB527C.9D72630%40web.de
(Subject: Re: std0X::expected_exception<T>())
ES, no_cancel {} and no_throw {} would simply "register" a fence.
It would certainly add to the overhead but who really cares
how "fast" is archaic setjmp/longjmp EH? (It isn't "real" EH
anyway.)
> and the addition of two keywords plus two-phase exception handling to
> the standard language for such a little gain is unlikely.
I don't think the gain is little.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Thu, 9 Sep 2004 15:27:24 GMT Raw View
David Abrahams wrote:
[...]
> If you only care about destructors, you *can* have the cancellation
> mechanism can check uncaught_exception; there's no need for 2-phase
> EH...
~object(bool) is probably better than uncaught_exception (with
count, not bool). Anyway, again:
~object() throw() {
try {
/* cancel point(s)/region(s) */
}
catch(std::thread_cancel_request const &) {
/* ... */
thread_self().cancel(); // reinject request
thread_self().enable_cancel(); // re-enable
}
}
You can have a destructor that can handle cancel request delivery.
And you generaly don't want to have throwing destructors (no
matter what the uncaught_exception state is), oder?
Think of _Uninit_fill. Googlygoogly. ;-)
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Alexander Terekhov <terekhov@web.de>
Date: Sat, 4 Sep 2004 19:05:06 GMT Raw View
David Abrahams wrote:
[... 'ECANCELED' ...]
> The C++ code, if correct in a non-threading environment, has to be
> able to deal with that.
How?
You know that 'stickiness' won't work; cancel delivery shall
disable cancellation. Even completely ignoring the issue of
cancel on unwinding path... at best, each 'correct' C++
library would 'translate' it to some library specific
nonstandard exception. I think that it's quite clear that
even with ECANCELED you'd have to modify your C/C++ library
code and make it 'cancel aware/safe'.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Wed, 8 Sep 2004 17:54:28 GMT Raw View
Ben Hutchings wrote:
[...]
> Cancellation should never be delivered to cleanup code.
Never say never. ;-)
> So somehow it
> has to be disabled in every destructor. Explicit calls in the
> destructor would be phenomenally expensive, so alternately the library
> could check the call stack to see whether a destructor is in there
The 'library' shall check whether a matching handler is in there. ES,
no_cancel {} and no_throw {} shall simply act as a 'fence' for the
search phase.
> before reporting cancellation (and if it is, disabling cancellation
> and retrying the system call). The way it's delivered doesn't make a
> difference.
POSIX could have introduced ECANCELED. For various reasons (think of
async-cancel-regions to begin with), POSIX ruled that cancellation
shall be delivered as exception (quoting Dimov: "a long-distance
return mechanism that unwinds the {POSIX cancellation} stack until
caught" by the implementation... or by the application via some non-
portable POSIX extension ala CATCH_ALL and/or C++-catch(...), catch-
by-type aside for a moment).
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Tue, 31 Aug 2004 04:33:44 GMT Raw View
David Abrahams wrote:
[...]
> I realize you're obsessed with 2-phase EH. I even think it's cool.
> But it doesn't solve any problems here.
Sure it does. throw() ES (less restrictive stuff with the same
effect aside for a moment) would "turn off" cancellation. No
cancel, no problem. Oder?
> Even if 2-phase EH searches
> up the stack and finds a handler that matches thread_cancel_request,
> it doesn't mean that the intervening code was written to expect a
> cancel request from otherwise nonthrowing 'C' library functions.
If the intervening code was not written to expect a cancel request
from otherwise nonthrowing 'C' library functions (I mean POSIX
cancellation points) then such code is simply cancel-unsafe. I can
live with it.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Wed, 1 Sep 2004 16:20:11 GMT Raw View
David Abrahams wrote:
[...]
> What problem are you solving?
~object() {
printf("arrivederci world.\n"); // cout aside for a moment
}
> If you can add a throw() ES, you can
> also add
>
> cancellation_disabler guard;
Sure.
>
> to the function implementation. You don't need 2-phase ES for that.
You do need 2-phase EH to make cancellation points (and async-cancel
regions) NOT throw "unexpected" cancellation exceptions... without
any cancellation_disabler guards.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Alexander Terekhov <terekhov@web.de>
Date: Thu, 2 Sep 2004 20:09:49 GMT Raw View
Peter Dimov wrote:
[... 2-phase EH and thread cancel ...]
> > cancellation_disabler guard;
> >
> > to the function implementation. You don't need 2-phase ES for that.
>
> Convenience.
And performance.
> The other part of Alexander's evil scheme to take over
> C++ exception handling (*) is implicit throw() on every destructor.
Plus "no_cancel {}", "no_throw {}" and "[a]sync_cancel {}" scopes. The
later ones shall be used to statically check async-cancel correctness.
http://www.codesourcery.com/archives/c++-pthreads/msg00124.html
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: aaa@bbb.com ("aaa@bbb.com")
Date: Sun, 29 Aug 2004 04:49:36 GMT Raw View
First of all thanks Andrei for having raised the MT subject which I
strongly agree it's of utmost importance for C++.
I have to say I'm not a big C++, CPU or MT expert but I will try to give
my contribution.
IMHO the problem has to be faced at various levels of abstraction.
The first thing to introduce (lower level of performance penalty), as
you suggested, is the constraint that operations with volatile variables
cannot be reordered with operations on other volatile variables.
This is in ADDITION of whatever else is needed. The new volatile
specification is needed because you don't always need CAS or
bus-interlocked semantics, which would slow down the program unneedingly
when you only need a specific ordering.
At a bit higher level of performance penalty there should be some
keyword or some template class to specify memory barrier visibility of
the changes immediately after modification. Like
rmembar<T>
wmembar<T>
rwmembar<T>
At a higher level of performance penalty we should have a way to provide
atomic increment (by 1), decrement (by 1), then atomic add and sub (by
+-n) and then atomic exchange.
At a higher level of performance penalty we should have the CAS
and I don't know if more is needed.
Of course if the CPU does not provide atomic increment, the
implementation on that compiler will be with CAS. If the data is too big
for a CAS, it will have a mutex. Templates with partial specialization
with CAS for the CASable types and mutexes in the general case should do
the job.
The programmer would be able to find if the actual implementation is
done with mutex by looking at
atomic<SomeType>::increment::is_mutexed
and for CAS:
atomic<SomeType>::compare_and_swap::is_mutexed
.
so the programmer can use enable_if to provide her own implementation if
s/he is not satisfied with the mutex.
Also see below
Andrei Alexandrescu (See Website for Email) wrote:
>
>>Same problem as above. You don't know which types are CAS-able.
>
> That's a good point to raise. I think CAS's spec should be "any POD of up to
> pointer size at least". That makes things hard, but not impossible. A more
> expressive CAS is "any POD of up to twice the pointer size".
Why should the standard specify this?
Some CPU would might not be able to provide that, so you wouldn't be
able to create a standard-conforming C++ compiler on that CPU... am I
missing something?
If there is no CAS for that data type on that CPU, the implementation
should be with the mutex. The programmer can query the implementation
with enable_if in case s/he wants tremendous performances. This is not
always the case, and also, usually the implementor of the library is
right about what is the fastest choice
> Implementation-defined (but the standard shall mandate the minimum).
> Amd there shall be a compile-time feature test mechanism.
>>> If you choose the wrong T, an atomic<> turns into a
>>> mutex-protected T, and you do not want that. The reason you don't
>>> want that is that in this case your own mutex-based logic will
>>> (typically) be superior.
>
>Yep. If you choose the wrong T, an atomic<> should invoke
>http://www.boost.org/libs/static_assert/static_assert.htm
Why should it? Then your code would not compile, that is, would not be
portable.
I think the way I explained above is better.
When we have the MT semantics defined, I think that another thing that
would be really important would be a standardization, or at least an
implementation, of lockfree STL-like containers.
This could be really hard. I hope that someone really knowledgeable can
work on one. Bad performances can be ok at the beginning. Having a slow
implementation is a big leap forward from not having an implementation
at all.
Java has got them, and having such an implementation is a real help in
avoiding deadlocks in multithreading, and more importantly, it's
practically a must for making a realtime software, because otherwise the
low-priority thread who comes first and accesses a mutexed container can
hold still a high-priority thread. If Java beats us even in the
realtime, what remains?
Thanks,
665BF55FD2E1F259FBB853129BA1D3A417AC69F2
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Mon, 30 Aug 2004 01:48:43 GMT Raw View
hyrosen@mail.com (Hyman Rosen) writes:
> Sergey P. Derevyago wrote:
>> IMHO POSIX C++ binding is the way to go.
>
> Concurrency must be defined by the language. It is
> impossible to add concurrency to C++ via nothing but
> a library.
[snip]
I'm certainly not a posix expert, but it was my impression that posix
includes changes to core C langauge semantics specficly to support
threads. Can anyone confirm or deny?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Mon, 30 Aug 2004 07:43:34 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> I think increment or decrement are about the same speed as
> adding/subtracting anything... moreover, many processors simply implement
> them all with CAS.
They do?
Actually, that approach is typically seen only on RISC CPUs.
On x86 machines, there is a single-instruction add to memory
operation, and the cache synchronization is good enough to
make it atomic. So, for most of the desktop machines
on the planet, that's not the case.
PowerPC machines favor a CAS approach,
offering some hardware suppport to tell whether another
CPU modified a value between two defined points.
On SPARC, atomic anything is hard to do, and
there have been requests for better hardware support.
Many implementations use a mutex.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Mon, 30 Aug 2004 17:27:32 GMT Raw View
Wil Evers wrote:
[...]
> target thread is expected to handle. This implies that the target thread
> should only deal with a cancellation request when it is ready to do so.
Yeah. "Ready to do so" meaning that thread cancellation is enabled AND
there's a matching handler for std::thread_cancel_request exception in
the dynamic scope.
> Obviously, when it is unwinding the stack because of some other exception,
> it is not.
~object() throw() {
try {
/* cancel point(s)/region(s) */
}
catch(std::thread_cancel_request const &) {
/* ... */
thread_self().cancel(); // reinject request
thread_self().enable_cancel(); // re-enable
}
}
Granted, that's not a "usual" case... but why not?
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: aaa@bbb.com ("aaa@bbb.com")
Date: Mon, 30 Aug 2004 17:57:25 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
>>If there is no CAS for that data type on that CPU, the implementation
>>should be with the mutex.
>
>
> I am not sure about this... there are implementations for which CAS is
> central and mutexing would imply a redesign. I don't think we can just
> abstract all that away.
>
> For example, say you want to do an atomic rmw operation on an integer. With
> CAS it's simple. Without CAS, you need a mutex. But the mutex needs to be
> stored with the integer. Now, can you modify the location (class etc.) where
> that integer is stored such that you plant the mutex in there? Etc. etc.
I don't understand the problem here.
E.g. atomic<long long> would be an object of 8 bytes size if the CAS
works for that datatype on that machine, while it would be 12 bytes size
if on that machine a mutex is needed for the atomic operations, which
would be (at least) something like
-----
T atomic<T>::get() const; //Yes it's needed! //also alias operator (T)
void atomic<T>::inc();
T atomic<T>::inc_get(); //also alias operators ++ postfix and prefix
void atomic<T>::dec();
T atomic<T>::dec_get(); //also alias operators -- postfix and prefix
void atomic<T>::add(T add_this);
T atomic<T>::add_get(T add_this); //also alias +=
void atomic<T>::sub(T subtract_this);
T atomic<T>::sub_get(T subtract_this); //also alias -=
T atomic<T>::swap(T put_this);
bool atomic<T>::test_and_set(T new_value, T supposed_old_value);
-----
(*)
I cannot see any implementation problem which could be related to the
location of the mutex: the mutex stays there together with the data, the
user should not need to provide an external one.
The only problem I can see for which the programmer might want to check
if the implementation is mutex-based would be the problem of the
priority inversion of the threads (only an issue for hard-realtime
systems, which anyway C++ NEEDS to address), and in that case the
programmer might use enable_if to decide for a *smaller data type* (the
only choice I can think of, other that failing to compile) if this is a
minor problem compared to the priority inversion.
I don't see any need to "redesign" any application for the presence of
the mutex, except for those rare cases concerned with the priority
inversion.
Of course if the programmer does not want to shrink the data type and
does not want the mutex (because of priority inversion), s/he can always
put a
STATIC_ASSERT(atomic<long long>::is_mutexed==false)
but this line should be written *by the user*! If the STATIC_ASSERT is
thrown by the standard library as you suggested, then the programmer who
was OK with the mutexed implementation will have a hell of a time for
compiling on foreign platforms. Her program needs to be tested platform
by platform on EVERY platform to make sure that it compiles with the
data types which are actually used. This is not a way to make C++
portable: how would you write a portable program using any
atomic<something>? not possible. S/he would have to NOT USE the
atomic<T> in order to be portable, so what would be the purpose of
standardizing these atomic operations?
OTOH the standard cannot mandate that there should be a non-mutexed
implementation for certain data sizes, because then it would not be
possible to make a standard compliant compiler for a CPU which does not
allow that.
(*) I made a mistake yesterday. I thought that it was possible for the
atomic<T>::inc operation to be non-mutexed while e.g. the atomic<T>::add
operation would instead be mutexed. Of course this is not possible
otherwise one thread could make an inc in the middle of an add of
another thread. Either all the operations above are mutexed or none of
them is. So there is need of only one flag for that class:
atomic<T>::is_mutexed
for checking the actual implementation for type T.
> I think that's a promising approach, however the
> primitives should also be
> exposed such that users create new algorithms using them.
Oh, I see. I understand now.
Yes, sure, if you expose static templated CAS functions, in that case
the STATIC_ASSERT is appropriate.
you mean that
long long ll;
std::threads::compare_and_swap(&ll, 71289307198372, 878902437809247);
should STATIC_ASSERT if compare_and_swap<long long>(...) is not
available on that platform! This for sure :-)
I would agree with you that atomic<T> and the static primitive functions
need both to be present. However, for the same reason I pointed above,
if one tries to make portable code by using the static functions he
needs to be lucky :-) so the class would be preferable.
The standard cannot mandate that std::threads::compare_and_swap<T>(...)
MUST exist (must not STATIC_ASSERT) for a certain T otherwise on some
CPUs you would not be able to create a compiler.
Oh and, yes, we also need the static functions for the memory barriers
:-) We would need at least a rmembar, a wmembar and a rwmembar static
functions. I don't know if there are any CPUs which can render globally
visible a read or write of a SINGLE variable (faster)... if there is at
least one, we should provide also that primitive, which would fall back
on the full-RAM-wide rmembar, wmembar, rwmembar functions for the other
CPUs.
I have another thought about the volatile problem: even if we enforce
that the optimizer should not reorder volatile statements, this would
probably NOT be enough. I'm not an expert of barriers but if we have:
volatile int data_available = 0; //0 = false, 1 = true
volatile char data=0;
char foo, bar, baz;
.
.
data = 30;
data_available = 1; //true
foo = 1;
bar = 2;
baz = 3;
even if these statements are not reordered, if the CPU optimizes the
writeback of "data" (a char, so it's SLOWER than an int) by delaying it
and coupling it with the writebacks of foo, bar and baz (probably they
will all be in the same CPU register and on 4 contiguous locations in
RAM), another CPU could see the writes of data_available coming BEFORE
the write of data!!
So it's probably NOT ENOUGH to mandate that the optimizer cannot reorder
the volatile assignments, but **the compiler should also put memory
barriers before/after every volatile statment!**
However there is no such problem with single-cpu machines: no-reordering
of volatiles is enough for single CPU machines.
So we might want to leave the volatile specification as
"non-reorderable" and then make other 3 standard classes like I wrote in
the previous post
rmembar<T>
wmembar<T>
rwmembar<T>
which would commit their reads and writes with barriers every time.
Thanks,
045E16DCB3300CC92FA5D0FE6A2F902E22273BB1
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Thu, 26 Aug 2004 17:43:02 GMT Raw View
stefan_heinzmann@yahoo.com (Stefan Heinzmann) writes:
> Andrei Alexandrescu (See Website for Email) wrote:
>
>> I believe what's reasonable and doable is:
>> a) Any thread API function (such as sleeping, locking a mutex,
>> waiting for an asynchronous result) will throw an exception when
>> thread cancelation has been requested. This way, a thread that has
>> proper exception handling and uses some synchronization routine will
>> finish properly. I wonder if CAS should be part of this
>> group... what are other people's thoughts?
>
> Can this be implemented without significant overhead in the
> synchronization routines? People wo don't use thread cancellation may
> not want to pay the price for it.
[snip]
Why can't there be a synchronization primitive which throws on thread
cancellation and one that doesn't?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Wed, 25 Aug 2004 04:26:53 GMT Raw View
"Steven E. Harris" wrote:
[...]
> Thread C is then left waiting when B should have signaled. It seems
> that the occasionally spurious signal on unlock is a necessary
> trade-off for correctness.
Yes. Optimal solution (for both mutexes and counting semas) can be
done with "lock queue" interface on the slow path with "waiters bit"
maintained by the "lock queue" implementation.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Wed, 25 Aug 2004 06:46:57 GMT Raw View
Wil Evers wrote:
> That's basically what POSIX calls deferred cancellation mode. Noteable
> differences are:
>
> * most (all?) blocking system calls, including those unrelated to threads,
> are cancellation points.
QNX implements this now, with a well thought out thread
cancellation mechanism. If you're interested in cancellation,
take a look at how QNX does it. There are cancellation points
and cancellation handlers.
But they're not integrated with C++, because QNX just
uses a stock GCC compiler.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Fri, 27 Aug 2004 19:17:56 GMT Raw View
David Abrahams wrote:
[...]
> Anyway, the additional provisions neccessary are simple: 'C' standard
> library functions don't throw; ...
I agree that additional provisions necessary are simple: both 'C'
and 'C++' standard library functions... and async-cancel-regions
don't throw UNEXPECTED std::thread_cancel_request exceptions.
Two-phase EH, you know.
// throw() shall be made implicit default for dtors
~object() throw() {
fclose(...);
}
Would consume 0 processing cycles unless cancel is pending (and
cancel state is enabled).
Alternatively, a program can disable cancelation via changing the
cancelation state. But that will burn cycles (and increase lines
of code ;-) ) even when you don't have a pending cancel request.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Tue, 24 Aug 2004 02:45:54 GMT Raw View
Wil Evers wrote:
[...]
> > I believe that experience has shown that asynchronous thread cancellation
> > is not the way to go;
>
> Agreed. I wasn't thinking about asynchronous thread cancellation; I banned
> that from my brain years ago.
Realtime Java supports it (using exceptions specifications to express
async-cancel-safety). The C++ language should be extended to understand
and enforce async-cancel-safety in a sorta similar way as it does today
for const-correctness. It's all in
http://www.codesourcery.com/archives/c++-pthreads/threads.html
I don't recall you objecting
http://www.codesourcery.com/archives/c++-pthreads/msg00124.html
;-)
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: falk.tannhauser@crf.canon.fr (=?ISO-8859-1?Q?Falk_Tannh=E4user?=)
Date: Tue, 24 Aug 2004 17:29:47 GMT Raw View
Roshan Naik wrote:
>
> "Andrei Alexandrescu (See Website for Email)" wrote:
>
>
>>>>"Roshan Naik" <someone@nowhere.com> wrote in message
>>>>news:4126BE7A.93C58FF2@nowhere.com...
>>>>
>>>>>Question 1: how far does volatile go ?
>>>>>-------------------
>>>>>wouldn't ...
>>>>>
>>>>> (volatile int) b = 6;
>>>>> (volatile int) a = 5;
>>>>>
>>>>>fix the problem you mention ?
>>>>
>>>>You mean:
>>>>
>>>>(volatile int&) b = 6;
>>>>(volatile int&) a = 5;
>>>>
>>>
>>>Hmm ! So i guess this idiom wont work in C. As I understand C
>>>doesnt have references. So it may need some more acrobatics
>>>if only some reads and writes to the variables need to be deemed
>>>observable behavior.
>>
>>It's trivial to transform the code above to use pointers.
>
> Is It ? You mean like this (in C)....
>
> *(volatile int*)&b = 6;
>
> .. but that only says that the address of b is volatile.
No, a "volatile address" would be of type 'int* volatile'.
Both '*(volatile int*)&b' and 'const_cast<int volatile&>(b)' denote
lvalues constituting volatile-qualified access paths to 'b'.
> it doesnt say
> that the assignment to b is volatile. thats brings you back to casting to
> volatile int....
>
> (volatile int ) * (volatile int*)&i = 4;
I think that '(volatile int)i' has never been an lvalue in C, and I'm
almost sure it has never been in C++, although some compilers accepted
it as a "creative extension", with the same semantics as '*(volatile int*)&i'.
Falk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhyslop@ieee.org (Jim Hyslop)
Date: Tue, 24 Aug 2004 23:47:55 GMT Raw View
Hyman Rosen wrote:
> Sergey P. Derevyago wrote:
>
>> IMHO POSIX C++ binding is the way to go.
>
>
> Concurrency must be defined by the language. It is
> impossible to add concurrency to C++ via nothing but
> a library.
You and Andrei have both made this statement. Could you provide some
references to background reading to support this? I have to admit I'm
not all that familiar with the low-level issues.
--
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sat, 21 Aug 2004 19:46:59 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
[...]
> > Granted, it would not be possible to implement
> > things like atomic<int> in portable, strictly conforming standard C++.
> > On the other hand, the standard C++ library already provides facilities
> > that cannot be implemented in conforming C++, and IMO, there is nothing
> > inherently wrong with a standard library facility that serves as a
> > portability device by encapsulating some platform-specific implementation
> > details.
>
> Hmmm... not quite. What one might refer to as a "library-based" solution is
> really a "solution with library syntax". What is unprecedented about threads
> is that calls into the so-called library are recognized by the compiler so
> that it can change code generation accordingly.
Current definition of the observable behavior of the C++ abstract
machine refers to library I/O functions calls. Upcoming definition
of inter-thread observable behavior could simply refer to atomic<>
::f({...,}msync::T> calls to define memory visibility/reordering
constraints.
>
> I personally consider such a setup ugly, ...
I don't know. Why do you consider it ugly? Uhmm,
// Andrei's 1st lock-free implementation of WRRMMap
// Works only if you have GC
// Unauthorizedly atomic<>ized by Alexander
template <class K, class V>
class WRRMMap {
atomic<Map<K, V>*> pMap_;
public:
V Lookup(class K& k) {
// Look, ma, no lock
return (*pMap_.load(msync::ddhlb))[k];
}
void Update(const K& k, const V& v) {
Map<K, V>* pNew = 0;
do {
Map<K, V>* pOld = pMap_.load(msync::ddhlb);
delete pNew;
pNew = new Map<K, V>(*pOld);
pNew->insert(make_pair(k, v));
} while (!pMap_.attempt_update(pOld, pNew, msync::ssb));
}
};
looks great. Oder? < ;-) >
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sat, 21 Aug 2004 22:17:43 GMT Raw View
Peter Dimov wrote:
[...]
> One problem is that the most efficient combination of memory barriers
> may differ depending on the platform. The unsupported standardized
> barriers will need to turn into full barriers (the most inefficient
> kind.)
The standard shall simply define the portable barriers model (and of
course including "relaxed"/"tuned" ones). Something like
msync::none // nothing (e.g. for refcount<T, basic>::increment)
msync::fence // classic fence (acq+rel -- see below)
msync::acq // classic acquire (hlb+hsb -- see below)
msync::ddacq // acquire with data dependency
msync::ccacq // acquire with control dependency
msync::hlb // hoist-load barrier -- acquire not affecting stores
msync::ddhlb // ...
msync::cchlb // ...
msync::hsb // hoist-store barrier -- acquire not affecting loads
msync::ddhsb // ...
msync::cchsb // ...
msync::rel // classic release (slb+ssb -- see below)
msync::slb // sink-load barrier -- release not affecting stores
msync::ssb // sink-store barrier -- release not affecting loads
msync::slfence // store-load fence (ssb+hlb -- see above)
Here's a few illustrations.
DCSI-MBR:
class stuff : private lazy_mutex { // "create/open named mutex"
// trick on windows
atomic<lazy const *> m_ptr;
public:
/* ... */
lazy const & lazy_instance() {
lazy const * ptr;
if (!(ptr = m_ptr.load(msync::ddhlb))) {
lazy_mutex::guard guard(this);
if (!(ptr = m_ptr.load(msync::none)))
m_ptr.store(ptr = new lazy(), msync::ssb);
}
return *ptr;
}
}
http://groups.yahoo.com/group/boost/message/15442
(that's "lazy mutex")
DCCI: (double-checked concurrent init)
class stuff {
atomic<lazy const *> m_ptr;
public:
/* ... */
lazy const & lazy_instance() {
lazy const * ptr;
if (!(ptr = m_ptr.load(msync::ddhlb)) &&
!m_ptr.attempt_update(0, ptr = new lazy(), msync::ssb)) {
delete ptr;
ptr = m_ptr.load(msync::ddhlb);
}
return *ptr;
}
}
Sorta better "critical-section" for windows.
// doesn't provide "POSIX-safety" with respect to destruction
class swap_based_mutex { // noncopyable
atomic<int> m_lock_status; // 0: free, 1/-1: locked/contention
auto_reset_event m_retry_event; // bin.sema/gate
public:
// ctor/dtor [w/o lazy event init]
void lock() throw() {
if (m_lock_status.swap(1, msync::ccacq))
while (m_lock_status.swap(-1, msync::ccacq))
m_retry_event.wait();
}
bool trylock() throw() {
return !m_lock_status.swap(1, msync::ccacq) ?
true : !m_lock_status.swap(-1, msync::ccacq);
}
bool timedlock(absolute_timeout const & timeout) throw() {
if (m_lock_status.swap(1, msync::ccacq)) {
while (m_lock_status.swap(-1, msync::ccacq))
if (!m_retry_event.timedwait(timeout))
return false;
}
return true;
}
void unlock() throw() {
if (m_lock_status.swap(0, msync::rel) < 0)
m_retry_event.set();
}
};
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sat, 21 Aug 2004 22:18:08 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> "Alexander Terekhov" <terekhov@web.de> wrote in message
> news:412533CA.82703A04@web.de...
>
>>Well, LL/SC is actually superior to CAS (LL/SC is ABA-proof), but
>>is less portable than CAS. And i386 doesn't have CAS, BTW.
>
> What's wrong with CMPXCHG8?
> [...]
Maybe the fact that the i386 doesn't have it. ;) According to:
http://developer.intel.com/design/pentium/manuals/24319101.pdf
CMPXCHG didn't appear until the i486, and CMPXCHG8B didn't appear
until the Pentium.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Sat, 21 Aug 2004 22:18:29 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
>>I agree with that if what you say is true, and you do not have to argue
>>further about it. However I am either not following your argument, or
>>multi-threaded computer programming is essentially dead if what you say=
is
>>irrevocably true. Somehow I do not think the latter can be the case, so=
do
>>you care to try again ? If not, please point me to some article which
>>explains this. I am not buying it until I am convinced.
>=20
>=20
> There is a third option. MT programming is not dead. It works because a=
ny MT=20
> system defines (more or less rigurously) a set of semantics that change=
s=20
> C++'s underspecified observable behavior rules as mandated by the stand=
ard.=20
> Also the MT system defines primitives that enforce (for a given compile=
r and=20
> processor architecture) the order of execution of reads and writes - in=
=20
> other words, it disables in key points the reorderings that both the=20
> compiler and the hardware do all over the place.
It is somewhat against my current belief about reordering or observable=20
behaviour. If you have the following code :
a=3D1;
f();
b=3D2;
And you do not have access to the source code for f(), there is no way=20
you can knows if reordering the assignements around the call to f()=20
might change or not the observable behaviour of the program (a and b=20
might be aliased...).
Therefore, you are not allowed to do it, and if f really is a=20
synchronisation primitive, this apply but just as the special case of a=20
more generic rule.
Is there any flaw in this way of thinking ?
> Scott and my article discuss the issues above in all of their subtletie=
s.
I hope to read it soon.
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sat, 21 Aug 2004 22:19:04 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
[...]
> > Also, variable-level visibility qualifiers may be inefficient even on
> > hardware that supports "everything". Consider a typical shared_ptr
> > reference count. It doesn't need any kind of barrier on increment and
> > needs a "conditional" barrier on decrement, depending on whether the
For example (not really optimal but good enough for an illustration),
http://www.terekhov.de/pthread_refcount_t/experimental/refcount.cpp
template<typename min_msync, typename update_msync>
bool decrement(min_msync mms, update_msync ums) throw() {
numeric val;
do {
val = m_value.load(msync::none);
assert(min() < val);
if (min() + 1 == val) {
m_value.store(min(), mms);
return false;
}
} while (!m_value.attempt_update(val, val - 1, ums));
return true;
}
template<typename min_msync, typename update_msync>
bool decrement(min_msync mms, update_msync ums, may_not_store_min_t) throw() {
numeric val;
do {
val = m_value.load(mms);
assert(min() < val);
if (min() + 1 == val)
return false;
} while (!m_value.attempt_update(val, val - 1, ums));
return true;
}
> > new value is zero.
And it doesn't need any barriers at all (even for decrements) if
managed object is immutable (i.e. shared_ptr shall use is_const<> ;-) ).
>
> I don't understand how shared_ptr gets away by incrementing a shared counter
> without absolutely any barrier.
Why would you need some barrier on increment?
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sun, 22 Aug 2004 05:15:08 GMT Raw View
Peter Dimov wrote:
[...]
> The problem with Alexander's atomic<T> is that you don't know which T
> to use.
Implementation-defined (but the standard shall mandate the minimum).
Amd there shall be a compile-time feature test mechanism.
> If you choose the wrong T, an atomic<> turns into a
> mutex-protected T, and you do not want that. The reason you don't want
> that is that in this case your own mutex-based logic will (typically)
> be superior.
Yep. If you choose the wrong T, an atomic<> should invoke
http://www.boost.org/libs/static_assert/static_assert.htm
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sun, 22 Aug 2004 05:16:07 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> [...]
> Then, you could have an integral constant
>
> const unsigned int std::max_threads = /implementation_defined/;
>
> Using that constant, programmers can use simple metaprogramming techniques
> to detect thread support at compile time.
Not to get bogged down in details, but when a user tries to create
a thread that would exceed max_threads, does create_thread() fail
silently, throw an exception, abort, or magically get detected at
compile time for the case where max_threads == 1?
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sun, 22 Aug 2004 05:17:25 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
>
> "Alexander Terekhov" <terekhov@web.de> wrote in message
> news:412533CA.82703A04@web.de...
> > Well, LL/SC is actually superior to CAS (LL/SC is ABA-proof), but
> > is less portable than CAS. And i386 doesn't have CAS, BTW.
>
> What's wrong with CMPXCHG8?
Lack of CMPXCHG16 cousin to begin with. ;-) Well, you can solve
ABA at expense of extra space, counting, and wider CAS. OTOH,
LL/SC does suffer from ABA and you don't have to pay that price.
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sun, 22 Aug 2004 05:37:01 GMT Raw View
Alexander Terekhov wrote:
> [...]
> Why would you need some barrier on increment?
Thread 1 loads count from memory and increments it. It gets written to
cache but not to memory [yet]. Thread 2, on a different processor,
loads the same count from memory and increments it. They each write the
same value to memory. Are you saying this won't happen, and why?
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Sat, 21 Aug 2004 01:35:16 GMT Raw View
David Abrahams wrote:
> That's much more complicated than saying they must provide
> multi-threaded support with a lower bound of 1 on the number of
> threads you can create. That results in simpler standardese AND (for
> a certain class of applications) simpler programs, with no #ifdefs.
Hopefully the changes in the language will not require to creating bindings
(like pthreads-c bindings) specifically to its own standard threading library.
Me, you ,
he , the other guy, or some company should be able to take the guarantees (or
changes or new primitices or whatever) provided by the core language and
implement their own threading library... there is always a chance you dont like
whats in the standard library or realize that it is not good enough for you...
Hopefully as replaceable as the containers and algorithms in the standard
library.
Just wishful thinking!
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Sat, 21 Aug 2004 16:37:58 GMT Raw View
Sergey P. Derevyago wrote:
> IMHO POSIX C++ binding is the way to go.
Concurrency must be defined by the language. It is
impossible to add concurrency to C++ via nothing but
a library.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Sat, 21 Aug 2004 16:38:24 GMT Raw View
Dietmar Kuehl wrote:
> There definitely *is* a requirement that any proposal has to say how to
> deal with platforms where it cannot be implemented. There will be no
> requirement that MT be available on all or no system. However, some way
> how a conforming implementation can be realized without MT support will
> be required.
I disagree strongly. There is no such thing as a platform which
cannot support MT. Vendors of embedded systems tools have tiny
multitasking kernels that run on all sorts of weak chips. Also,
the standard doesn't specify what to do on systems that can't
implement exceptions, or file systems, or floating point math.
If some system really can't support it, then the vendors will
have to ship a subset compiler, but there's no reason for the
standard to be encumbered by this.
GNAT Ada runs on a large number of platforms with full task
support, and this has included MS-DOS.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Sat, 21 Aug 2004 16:40:20 GMT Raw View
News Subsystem wrote:
> You say that threads can't be properly handled by a library, but there are
> obviously many people out there writing MT apps in C++ today using library
> implementations, and the apps are working just fine. How, specifically,
> for those of us who are not experts, are they not handling threads properly?
They are relying, knowingly or not, on vagaries of their implementation.
Most likely, these vagaries are not explicitly specified by their vendor,
and are liable to change in unpredictable ways. In short, they are lucky.
> If I understand correctly, this situation is currently handled by critical
> sections or mutexes. Do I misunderstand? Or is this a bad way to do it,
> and if so why?
The compiler must understand that these mutexes are concurrency primitives.
Otherwise it may do code motions and optimizations around them that are
invalid in context.
> you need to tell them why it's better than the other bandwagons.
The other bandwagons are held together with spit and baling wire.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Sat, 21 Aug 2004 16:40:32 GMT Raw View
Roshan Naik wrote:
>>It is not viable to write libraries for just one system alone. For
>>library implementation it will be necessary to be thread aware at least
>>in some places - after all you want thread support, aren't you? So it
>>will be necessary to have source compatible versions which may run on
>>both kinds of systems.
>=20
>=20
> Its not "just one system".. there are far too many platforms with MT su=
pport.
> And as I said it makes no sense running MT programs on non MT systems.
> So thats a worthless goal for the standard to try to make your MT progr=
ams
> run or even compile on non MT systems.
I have string class that uses COW. I want this class to be thread safe=20
(in the way defined by Herb Sutter in the September 2004 CUJ). I also=20
want to use it in monothread environment. And I don't want to use #if.=20
In this case, making those synchronisations no-op is the perfect choice.
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sat, 21 Aug 2004 16:45:51 GMT Raw View
Alexander Terekhov wrote:
> [...]
> Well, LL/SC is actually superior to CAS (LL/SC is ABA-proof), but
> is less portable than CAS. And i386 doesn't have CAS, BTW.
> [...]
That's interesting, because:
http://www.research.ibm.com/people/m/michael/ieeetpds-2004.pdf
claims that LL/SC is fairly watered down in practice. Also, whether
an algorithm is ABA-proof is not solely determined by the primitives
used, as I understand it.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: tannhauser86549spam@free.fr (=?ISO-8859-1?Q?Falk_Tannh=E4user?=)
Date: Sat, 21 Aug 2004 17:04:45 GMT Raw View
Dietmar Kuehl wrote:
> someone@nowhere.com (Roshan Naik) wrote:
>=20
>>>The standardization committee is well aware of the existance of thread=
s
>>>and I doubt that it will reject a reasonable proposal adding threads t=
o
>>>C++ (although such a proposal probably will have to address how thread
>>>support is to be implemented on systems not supporting threads).
>>
>>I would imagine that this requirement (if true) would be the biggest
>>impediment to ever having MT in the standard.
>=20
>=20
> There definitely *is* a requirement that any proposal has to say how to
> deal with platforms where it cannot be implemented. There will be no
> requirement that MT be available on all or no system. However, some way
> how a conforming implementation can be realized without MT support will
> be required.
Today there already are two kinds of implementation: hosted and freestand=
ing
(=A7 1.4/7). So I suppose there could be 2 more kinds added (hosted with =
MT
and freestanding with MT).
Falk Tannh=E4user
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Sat, 21 Aug 2004 17:05:05 GMT Raw View
>
> std::cout << "We have optional features already.\n";
>
In absolute terms ..not really.... Your assumption that this should go to a
console is incorrect. It is not
"optional" at all, it is "implementation defined"
[1.9.11]
"...What constitutes an interactive device is implementation defined."
so chanelling that output to /dev/null is perfectly standards conformant.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Sat, 21 Aug 2004 17:08:03 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> ""Sergey P. Derevyago"" <non-existent@iobox.com> wrote in message
> news:412472B2.C6BFB163@iobox.com...
> > C++ is not a niche programming language so it must not copy Java MT
> > design.
> > IMHO POSIX C++ binding is the way to go.
>
> Java's not niche either, but I won't spread myself too thin.
>
> I agree that a POSIX C++ binding would be good. The problem is, C++ has so
> complex semantics, the pthreads people (who are, as a community, less
> experts in C++'s subtleties) won't attempt.
I would disagree. Pthread bindings will only help people using pthreads
library...
what about the rest of the world ?
I mentioned this in another post, but it would be nice to keep away from
library specific bindings moving forward. The core language should provide
sufficient (and minimal ?) guarantees (or features or whatever) to enable
anyone
(individuals or vendors) to create a their own threading threading library...
when the standard library doesn't quite cut it...just like the std::containers
and
std::algorithms.
When I decide to to do a better job at designing a MT library than the std
library
(i.e after I get a YASLand citizenship) , I shouldnt have to go knocking on
doors
of compiler vendors to adopt my requirements and make their compiler compliant
to my library.
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Sat, 21 Aug 2004 18:17:43 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> Modern compilers *and* processors reorder writes to memory. For example:
>
> int a, b;
> ..
> b = 6;
> a = 5;
>
> might be actually seen as:
>
> a = 5;
> b = 6;
>
> by another thread.
>
> .......[ snip ] ...
> Such an unintuitive reordering is because the speed difference among the
> various stages in the memory cache hierarchy (registers, level I, level II,
> RAM) is staggering and increasing. Writes are done to the cache first and
> then the cache is committed to the main memory in bursts, that is, a
> bank/line at a time. That means, if a's address is before b's in memory, as
> far as another processor could tell, a will be written to first, and only
> then b.
May be there are a few more people like myself who are a bit confused about
things inspite of reading the DDJ article and some more stuff here and there.
So i will ask (silly questions) in more basic terms ...
Question 1: how far does volatile go ?
-------------------
wouldn't ...
(volatile int) b = 6;
(volatile int) a = 5;
fix the problem you mention ?
I mean, its no diff (in terms of order of observable behavior and the "as-if" rule)
than saying ...
std::cin >> b;
std::cin >> a;
[on a side note i like to call the "as-if" rule as the "footnote rule". This important rule
discretely tucked away in a footnote in the standard eluded my attention and caused me
far too much anguish and needlessly long exchange of msgs with the Andrei, scott and
c.l.c++.moderated ]
Question 2 : Breaking down the MT problems in DCL
------------------------------------------
I would imagine that compilers (today) aren't going to place a memory barrier between the
statements
(in either of above case) ...but should it for MT programs ? Perhaps yes(in my limited
wisdom).
If not then how is volatile (or output functions) being guaranteeing observable behavior today
?
Aside from the instruction(memory ?) ordering problem the DDj article pointed out (as I
understand)
that updates to data (pInstance) on one processor are not necessarily visible to other
processor's.
So does that mean two independent problems...
- instruction ordering,
- memory (or cache ?) coherency
- (and maybe a third..) memory ordering
?
Question 3 : instruction v/s memory ordering
------------------------------------------------------
Now, very often i see people referring to "memory ordering" being referred to and then
providing
examples dealing with instruction ordering.
Cuz (as I understand) regardless of the compiler or processor doing things "right", the memory
subsystem has its own mind on how those updates will be really done. So telling the processor
anything
seems like waste. I am thinking perhaps these two terms (instruction / memory ordering )
should be used more carefully...and precisely.
Inserting of memory barriers _limits_ the flexibility of how instructions are executed
by the processor near the barrier point(i.e exec fully all (memory related) instructions prior
to barrier
b4 continuing... semantically like sequence points)...so its really a instruction ordering
tool. although
intended for ensuring correct memory updates ? should they have called it "instruction
barrier" ?
So is it right to say that asking the processor to update memory in a certain order has no
bearing
on how the memory is finally updated by the memory subsystem in a multiprocessor subsystem ?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Thu, 19 Aug 2004 20:18:10 GMT Raw View
Dietmar Kuehl wrote:
> > I think the easiest (and may be best way) to tackle this is to
> > require intelligence from the compiler to issue an error when <thread> would
> > be included.
>
> I would strongly oppose such an approach - assuming that <thread> is the
> header which defines all thread related entities. I would not oppose that
> e.g. attempting creation of a thread would yield an error but e.g. the
> lock mechanisms should be implemented as no-ops on systems not supporting
> multiple threads: this is crucial when implementing libraries which are
> intended to be used on more than one platform.
>
You see ...the earlier you point out an error to the programmer the better.
Rather turn all his thread creation, thread synch etc code into nops or
some run time errors. Compile time errors are preferrable to run time ones.
So whaterver the mechanism for issuing the error msg to the programmer
.. it doesnt matter as long as its compile time.
> > ...on a platform that doesn't support MT. Case closed! The rest
> > of the world shouldn't be penalized cuz a small fraction of the systems
> > do not have certain capabilities.
>
> Right. Unfortunately, the small fraction of systems is not the one you
> think it is :-) ...and even if systems without MT support are the small
> fraction, your approach is not how standards work.
And C++ isnt going to be in the business of providing MT on systems
where MT doesnt exist. Programmers are concerned only about
getting MT where MT is supported.
> > If they dot have MT capability then they aren't going to use it anyway,
> > so better not to fuss too much.
>
> It is not viable to write libraries for just one system alone. For
> library implementation it will be necessary to be thread aware at least
> in some places - after all you want thread support, aren't you? So it
> will be necessary to have source compatible versions which may run on
> both kinds of systems.
Its not "just one system".. there are far too many platforms with MT support.
And as I said it makes no sense running MT programs on non MT systems.
So thats a worthless goal for the standard to try to make your MT programs
run or even compile on non MT systems.
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Thu, 19 Aug 2004 21:19:27 GMT Raw View
Steven E. Harris wrote:
> nagle@animats.com (John Nagle) writes:
>=20
>=20
>>The committee's emphasis is on obscure template features too fragile
>>to use in production code. LISP went through this process in the
>>1980s. The heavy work was going into obscure macros. And when the
>>dust settled, LISP was irrelevant.
>=20
>=20
> Bite your tongue. Is ANSI Common Lisp=B9 the settled dust? Surely macro=
s
> are one of Lisp's greatest strengths, not a cause for any decline in
> popularity or "relevance."
The MIT Loop Macro and CLOS come to mind, along with the big
effort by Symbolics (anybody remember them?) to get everything
their hardware did well into Common LISP.
Finally, Scheme cleaned up much of the mess, but by then
it was too late.
C++ is repeating some of the mistakes of the LISP community.
Trying to fix fundamental language problems by layering macros
(or, in C++'s case, templates) on top does not work well.
The resulting excuse for a language is too fragile.
The bugs become more and more obscure.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Thu, 19 Aug 2004 21:19:38 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> ""Balog Pal"" <pasa@lib.hu> wrote in message
> news:41246302@andromeda.datanet.hu...
>
>>""Andrei Alexandrescu (See Website for Email)""
>><SeeWebsiteForEmail@moderncppdesign.com> wrote in message
>>To deal with situations where the order of memory accesses is important, a
>>new keyword membar(type) is introduced. type can be one of the 16 values
>>used for ordering memory barrier instructions in the SPARC architecture.
>>The presense of the keyword ensures that loads/stores designated by the
>>type
>>can not be carried through that point. Also the implemetation issues the
>>proper instruction to the processor/architecture if needed. [note: that
>>will be nothing on majority of current platforms]
>>
>>atomic types. access to the (list) types is atomic. Read/write such a type
>>is always safe and read will yield a value exactly as previously stored.
>>(however if multiple threads store a value it is unknown which value is
>>read
>>unless membars are properly used and sequencing considered)
That feature is so l33t that nobody will use it right.
Threading with mutexes is too hard for most programmers
to get right. This is harder.
I'd like to put some of the people who advocate things like
this on maintenance programming for a year, reading crash
dumps and fixing the bugs that caused them.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Fri, 20 Aug 2004 03:30:40 GMT Raw View
Wil Evers wrote:
[...]
> And CAS could be provided as a standard library facility too.
Well, LL/SC is actually superior to CAS (LL/SC is ABA-proof), but
is less portable than CAS. And i386 doesn't have CAS, BTW.
> But even if
> the issues above are resolved, there are lots of other things to worry
> about. A particularly nasty one is the question of how thread cancellation
> should be integrated into the C++ exception handling framework - if at all.
atomic<> side for a moment, a good "exercise" for the C++ committee
folks (with the help of their sponsor orgs) is to sponsor a contest
for "the best" <cthread>/<pthread.h> impl in terms of <thread>. ;-)
I mean stuff a la (just an illustration, nothing real)
typedef std::thread * pthread_t; // e.g.
#define PTHREAD_CANCELED std::thread_canceled()
struct thread_canceled {
operator void * () { return &unique; }
static thread_canceled unique;
};
class thread_termination_request : public std::exception ...
class thread_cancel_request : public std::thread_termination_request ...
class thread_exit_request : public std::thread_termination_request ...
template<typename T> class thread_exit_value : public
std::thread_exit_request ...
extern "C" pthread_t pthread_self() throw() {
return std::thread_self().raw_ptr();
}
extern "C" void pthread_exit(void * ptr)
throw(std::thread_termination_request) {
ptr == PTHREAD_CANCELED ? std::thread_cancel() :
std::thread_exit(ptr);
}
template<typename T>
void thread_exit(T value) {
assert(std::thread_self().can_exit_with<T>());
throw thread_exit_value(value);
}
template<>
void thread_exit(std::thread_canceled) {
thread_cancel();
}
void thread_cancel() {
throw std::thread_cancel_request();
}
struct no_cleanup {
void operator()(void *) {
// NOOP
}
};
template<typename cleanup>
bool no_TSD_cleanup(const cleanup &) throw() {
return false;
}
template<>
bool no_TSD_cleanup(const no_cleanup &) throw() {
return true;
}
template<typename T, typename cleanup>
class thread_specific_ptr : cleanup /* noncopyable */ {
_TSD_key_t _key;
static void dtor(void * data, void * THIS) {
static_cast<thread_specific_ptr *>(THIS)->
operator()(static_cast<T *>(data));
}
public:
thread_specific_ptr()
throw(std::bad_alloc, std::try_again);
thread_specific_ptr(const cleanup&)
throw(std::bad_alloc, std::try_again);
~thread_specific_ptr() throw();
T * get() throw();
void set(T *) throw(std::bad_alloc);
T * operator->() throw();
T * release() throw();
void dispose() throw();
void reset(T *) throw(std::bad_alloc);
};
template<typename T, typename cleanup>
thread_specific_ptr<T, cleanup>::thread_specific_ptr()
throw(std::bad_alloc, std::try_again) {
_tsd_key_create(&_key, no_TSD_cleanup(
*static_cast<cleanup *> (this)) ? 0 : &dtor, this);
}
template<typename T, typename cleanup>
thread_specific_ptr<T, cleanup>::thread_specific_ptr(
const cleanup& _cleanup) throw(std::bad_alloc,
std::try_again) : cleanup(_cleanup) {
_tsd_key_create(&_key, no_TSD_cleanup(
__cleanup) ? 0 : &dtor, this);
}
/* ... */
extern "C" typedef void (* _c_TSD_dtor_t)(void *);
extern "C++" typedef void (* _cpp_TSD_dtor_t)(void *);
struct _cthread_TSD_cleanup {
_cthread_TSD_cleanup(_c_TSD_dtor_t _c_TSD_dtor_) :
_func(_c_TSD_dtor_ ? c : null),
_c_TSD_dtor(_c_TSD_dtor_) {
}
_cthread_TSD_cleanup(_cpp_TSD_dtor_t _cpp_TSD_dtor_) :
_func(_cpp_TSD_dtor_ ? cpp : null),
_cpp_TSD_dtor(_cpp_TSD_dtor_) {
}
void operator()(void * _data) {
if (_data) switch(_func) {
case c: _c_TSD_dtor(_data); break;
case cpp: _cpp_TSD_dtor(_data); break;
}
}
enum { null, c, cpp } _func;
union {
_c_TSD_dtor_t _c_TSD_dtor;
_cpp_TSD_dtor_t _cpp_TSD_dtor;
};
};
template<>
bool no_TSD_cleanup(const _cthread_TSD_cleanup & _cleanup)
throw() {
return _cleanup._func == _cthread_TSD_cleanup::null;
}
typedef std::thread_specific_ptr<void, _cthread_TSD_cleanup> *
pthread_key_t;
// try { throw; } catch... "idiom"
int _translate_exception_to_error_code() throw();
extern "C" int pthread_key_create(pthread_key_t * key,
void ( * dtor)(void *)) throw() {
try {
*key = new std::thread_specific_ptr<void,
_cthread_TSD_cleanup>(_cthread_TSD_cleanup(dtor));
}
catch(...) {
return _translate_exception_to_error_code();
}
return 0;
}
extern "C++" int pthread_key_create(pthread_key_t * key,
void ( * dtor)(void *)) throw() {
try {
*key = new std::thread_specific_ptr<void,
_cthread_TSD_cleanup>(_cthread_TSD_cleanup(dtor));
}
catch(...) {
return _translate_exception_to_error_code();
} return 0;
}
extern "C" int pthread_key_delete(pthread_key_t key)
throw() {
delete key;
return 0;
}
extern "C" void * pthread_getspecific(pthread_key_t key)
throw() {
return key->get();
}
extern "C" int pthread_setspecific(pthread_key_t key,
const void * p) throw() {
try {
key->set(const_cast<void *>(p));
}
catch(...) {
return _translate_exception_to_error_code();
}
return 0;
}
extern "C" int pthread_resetspecific(pthread_key_t key,
const void * p) throw() {
try {
key->reset(const_cast<void *>(p));
}
catch(...) {
return _translate_exception_to_error_code();
}
return 0;
}
extern "C" void * pthread_releasespecific(pthread_key_t key)
throw() {
return key->release();
}
extern "C" void pthread_disposespecific(pthread_key_t key)
throw() {
return key->dispose();
}
// PODs
typedef std::aligned_storage<std::mutex> pthread_mutex_t;
typedef std::aligned_storage<std::mutexattr_t> pthread_mutexattr_t;
#define PTHREAD_MUTEX_INITIALIZER /* magic */
extern "C" int pthread_mutex_init(pthread_mutex_t * mutex_storage,
const pthread_mutexattr_t * attr_storage) throw() {
try {
attr_storage ? new (mutex_storage->place())
std::mutex(attr_storage->object()) :
new (mutex_storage->place())
std::mutex();
}
catch(...) { // see ES of mutex::mutex(/*...*/)
return _translate_exception_to_error_code();
}
return 0;
}
extern "C" int pthread_mutex_lock(pthread_mutex_t * m) throw() {
try {
m->object().acquire();
}
catch(...) { // see ES of mutex::acquire()
return _translate_exception_to_error_code();
}
return 0;
}
extern "C" int pthread_mutex_destroy(pthread_mutex_t * m) throw() {
m->object().~mutex();
return 0;
}
typedef aligned_storage< once_call< void > > pthread_once_t;
#define PTHREAD_ONCE_INIT /* magic */
extern "C" int pthread_once(pthread_once_t * once_control,
void (* init_routine)()) {
once_control->object()(init_routine);
return 0;
}
extern "C++" int pthread_once(pthread_once_t * once_control,
void (* init_routine)()) {
once_control->object()(init_routine);
return 0;
}
and so forth (or something like that ;-) ). See also
http://groups.google.com/groups?selm=3ECB8F71.689E551C%40web.de
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 20 Aug 2004 16:33:34 GMT Raw View
Edward Diener wrote:
> This seems wrong. I do not know if what you are saying is wrong or not but I
> always assumed that sequence points in C++ tell me that the memory which a
> points to will be set to the integer value of 5 before the memory which b
> points to is set to the integer value of 6.
You will not get very far complaining to Sun that their hardware
violates the C++ standard! You will also not get very far if you
demand that compilers surround every access with synchronization
primitives. Instead, you must do as has been often repeated here.
Every thread which means to share access to a common resource must
synchronize that access with system-defined primitives for doing
so, in the absence of language-defined means.
> I would have assumed that if this were the case, then the CPU would have to
> make sure that the values were both updated to their proper values if any
> instruction occurred which attempted to access those memory locations.
The "values which are both updated" may simultaneously live in a
variety of memories - registers, cache, swap. No hardware platform
is going to enforce synchronization on every instruction, because
it would be much too slow. Not only that, the offending instruction
might be running on a completely different processor.
> If not, we are talking about random computing here.
No, because at the program level, the program knows about shared
resources and multiple threads, and it is the responsibility of the
program to issue the appropriate synchronization requests at the
appropriate times. This limits such requests only to the parts of
the program that need it, and allows the rest of the program to run
unfettered by the need to synchronize.
> Somehow I find it very hard to believe what you say is justified in reality.
It has been demonstrated by actual code on actual computers.
> You are telling me that areas in computer memory do not have to hold the values
> to which a computer instruction has set it to be when another computer instruction
> attempts to access it. Huh ?
There are many memories and many computers issuing instructions. If they
are to share common resources, they must synchronize as required by the
platform. If they do not, then they cannot expect the guarantees normally
provided by the synchronization.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Fri, 20 Aug 2004 16:35:36 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> Problems start to crop up as soon as one tries to do lock-free programming.
> Lock-free programming means, you try to do synchronization by manipulating
> memory locations directly, not by locking.
>
IMHO this is the root of misunderstanding.
Generally speaking, lock free should mean "(almost) independent simultaneous
execution". MT is not about locking, MT is about simultaneous execution: even
false data sharing and other types of "cache ping-pong" must be avoided.
As David Butenhof has written: "multithreading is defined by an application
design that ALLOWS FOR concurrent or simultaneous execution". That is your
"synchronization by manipulating memory locations directly, not by locking"
definition does NOT allow for simultaneous execution.
> Lock-free data structures are
> significantly better than they locked-counterparts at pretty much all tests,
> plus they are immune to deadlock, immune to livelock, immune to thread
> killing (killing any thread at any time won't hang other threads), immune to
> priority inversion, and immune to... what was the last one? ah, asynchronous
> signals (signals can call lock-free functions at any time).
>
Also, the "manipulating memory locations directly" is not so cool as one
might expect. There were a lot of discussions on this topic in
comp.programming.threads. In particular, please let me quote David Butenhof
once more:
-----------------------------------8<-----------------------------------
The basic fallacy of SenderX's arguments is that, while he's correct that
execution of a lock-free algorithm will not "indefinitely postpone"
execution of an individual thread, that's NOT necessarily always in the
best interests of the application (much less of the SYSTEM) as a whole.
Sometimes it really IS better to block a particular thread and allow others
to make progress. That's why you're often (and perhaps even "almost
always") better off using a carefully tuned COMBINATION of lock-based and
lock-free mechanisms. (And, in other contexts, though he keeps slipping
back into old habits, SenderX has even admitted that in this newsgroup.)
Furthermore, to say that lock-free algorithms don't "stall" a thread is
physically inaccurate. Memory contention WILL stall the processor's
interlocked operations, or cause them to fail and retry. The thread in
question is NOT making "uninterrupted forward progress". It's just in a
hardware stall or spinloop instead of being blocked on a wait queue.
Sometimes, especially in low-level operations that rarely contend, this is
good.
In other contexts, though, it's bad; and it can be seriously bad, if the
contention levels are high enough and evenly distributed. Where a blocking
algorithm allows SOME thread to complete its operation without
interference, the stalls and spins in a poorly tuned lock-free application
can instead cause ALL threads to struggle along in slow motion. (Of course
one shouldn't ever design such prolonged high contention into a program.
That sort of rule unfortunately is far easier to toss off with an
authoritative air in a newsgroup than to actually implement and guarantee
in a large application.)
-----------------------------------8<-----------------------------------
> C++ lacks the means to have the programmer specify the order of reads and
> writes for certain variables, and that is a core language issue.
>
Yes, the "lock-free programming" has some advantages in some contexts.
My point is: Is it _really_ so important to have some special support by core
of general purpose programming language like C++? Do we fight _main_ MT
targets dealing with it?
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 20 Aug 2004 20:42:53 GMT Raw View
David Abrahams wrote:
> Please, no.
ATC (Asynchronous Transfer of Control) is widely regarded as
a language design mistake in Ada.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: Fri, 20 Aug 2004 22:50:40 GMT Raw View
Uwe Schnitker wrote:
>
>
> Hmm, Andrei, since you cannot yet present a proposal to seed a
> discussion, how about filing a defect report?
>
Administrivia: Please have a look at the newsgroup FAQ about defect
reports. A defect report points out some sort of error in the
existing standard. By definition, a DR does not request a new
language feature.
We do need an actual proposal for how MT should be included in the
standard, written by someone who understands the issues. Accusations
of ignorance and sloth do not help to advance the cause.
A *final* proposal needs to be complete and detailed, suitably worded
for inclusion in the Standard. An *initial* proposal is not expected
to meet those criteria. It should cover the major points, discuss
implementation issues and the effect on the rest of the language, and
explain why it is better than alternatives.
---
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Thu, 19 Aug 2004 04:00:00 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> "Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
> news:5b15f8fd.0408180300.6413ef48@posting.google.com...
>
>>Andrei Alexandrescu wrote:
> I understand that. But that's also a "put up or shut up" attitude. If the
> committee understands the larger view (which is the reason of my posting
> here), and if they understand that forwarding constructors are a petty issue
> compared to threads and Java's threat in the area, then they will think of
> ways to attract MT specialists and researchers. The damage about shooing
> away (for good) PL language design experts has been done; see the Tom
> Penello episode. The consequences of that attidude have been very costly.
> Why repeat that damage with MT people?
The committee has already driven away the multithreading
people. Go back and read the threads in this group relating
to language-level concurrency issues. There's repeated
insistence that it's an "OS issue". This despite the obvious
point that good concurrency support requires compile-time
help, and sometimes the generation of special machine instructions.
One direct consequence of the committee's denial of the problem
is that locking in C++ tends to be much slower than
it could be.
The committee also has driven away the safety, quality,
and reliability people. Any attempt to tighten up a hole,
no matter how many bugs it causes, is met with the argument
that in some obscure circumstance, more relaxed rules might
possibly be useful. We pay for this every day, as buffer
overflow stories make the headlines in the mainstream press.
The committee's emphasis is on obscure template features too
fragile to use in production code. LISP went through this process
in the 1980s. The heavy work was going into obscure macros.
And when the dust settled, LISP was irrelevant.
Java and C# exist primarily because the C++ crowd was
unwilling to fix fundamental problems in the language.
That's a strong indictment of the standardization
process.
Remember Pascal. Good language, botched standard,
refusal by key designer to fix clear problems. Nearly
dead today. That's where C++ is headed.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhyslop@ieee.org (Jim Hyslop)
Date: Thu, 19 Aug 2004 04:40:03 GMT Raw View
Sergey P. Derevyago wrote:
> BTW there are a lot of (really important) environments that have C++
> implementations but do _not_ support MT. Are you going to force these
> implementations to somehow emulate MT?
That's not necessary. The standard could allow compilers *not* to
implement MT features, as long as the compiler recognizes them for what
they are.
Something along these lines should do it:
This clause defines the [keywords/library/what have you] that provide
support for multiple threads of execution. Whether or not an
implementation supports multiple threads of execution is
implementation-defined. An implementation that does not support multiple
threads of execution shall not reject code that is well-formed according
to this clause, provided that the code is otherwise well-formed.
--
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhyslop@ieee.org (Jim Hyslop)
Date: Thu, 19 Aug 2004 06:17:18 GMT Raw View
Craig Henderson wrote:
> The definition of a generic programming language such as C++
> should not, imho, rely upon or restrict itself to the capabilities of the
> application's target hardware.
Ah, but I think you're looking through the wrong end of the telescope.
Adding MT support does not restrict the language - indeed, it opens up
whole new areas of development. Conversely, adding support for MT
programming to the language does not force compilers or hardware to
provide or even emulate MT.
The key, as I hinted at in my other message in this thread, is not to
say "Implementations must provide multi-threaded support." No, rather,
we want to say "Implementations *MAY* provide multi-threaded support,
and if they choose to do so, this is how it shall be done."
--
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhyslop@ieee.org (Jim Hyslop)
Date: Thu, 19 Aug 2004 06:17:39 GMT Raw View
Dietmar Kuehl wrote:
> The standardization committee is well aware of the existance of threads
> and I doubt that it will reject a reasonable proposal adding threads to
> C++ (although such a proposal probably will have to address how thread
> support is to be implemented on systems not supporting threads).
Implementing the support is quite trivial, actually. A system that does
not support threads generates exactly the code that is required:
nothing. It should be easy enough to recognize the MT features and just
ignore them. I'd prefer ignoring MT features over generating an error,
because with an error you don't have portable code: you have to wrap
your code in ugly #ifdefs.
The standard does not have to say "Implementations must support multiple
threads of execution". The standard could say "An implementation may
support multiple threads of execution, and if it does, this is how it
shall be done."
--
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Thu, 19 Aug 2004 14:40:37 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> So I think the "obvious reason" is that many standard C++ users and pun=
dits=20
> think that threads can be handled properly by a library. It cannot. If=20
> enough people understand that, and also understand the competitive bene=
fit=20
> that Java's threading amenities lends to that language, interest will b=
e=20
> born.
If you give us an link to an article that explains that, instead of just=20
vague allegations that Java does it better, then poeple will be able to=20
read this article and there might be enough people to understand that.
>>The standardization committee is well aware of the existance of threads
>>and I doubt that it will reject a reasonable proposal adding threads to
>>C++ (although such a proposal probably will have to address how thread
>>support is to be implemented on systems not supporting threads). Howeve=
r,
>>the committee will not start working on multi-threading: the work has t=
o
>>be done by people who are interested in this area.
>=20
>=20
> I understand that. But that's also a "put up or shut up" attitude. If t=
he=20
> committee understands the larger view (which is the reason of my postin=
g=20
> here), and if they understand that forwarding constructors are a petty =
issue=20
> compared to threads and Java's threat in the area, then they will think=
of=20
> ways to attract MT specialists and researchers. The damage about shooin=
g=20
> away (for good) PL language design experts has been done; see the Tom=20
> Penello episode. The consequences of that attidude have been very costl=
y.=20
> Why repeat that damage with MT people?
What is "PL language" ?
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Thu, 19 Aug 2004 15:48:10 GMT Raw View
Jim Hyslop wrote:
> Dietmar Kuehl wrote:
>
>> The standardization committee is well aware of the existance of threads
>> and I doubt that it will reject a reasonable proposal adding threads to
>> C++ (although such a proposal probably will have to address how thread
>> support is to be implemented on systems not supporting threads).
>
>
> Implementing the support is quite trivial, actually. A system that does
> not support threads generates exactly the code that is required:
> nothing. It should be easy enough to recognize the MT features and just
> ignore them. I'd prefer ignoring MT features over generating an error,
> because with an error you don't have portable code: you have to wrap
> your code in ugly #ifdefs.
>
> The standard does not have to say "Implementations must support multiple
> threads of execution". The standard could say "An implementation may
> support multiple threads of execution, and if it does, this is how it
> shall be done."
It would also have to say "If the implementation supports only
a single thread of execution, this is how to indicate that."
I think there is broad agreement that it should be possible to
take code which exploits multithreading and compile it on a
single-threaded platform if it has been written to cope with
the restriction of running in a single thread. We would probably
want to be able to detect this at compile time when possible, and
at runtime when a given compile-time environment might correspond
to either a ST or MT runtime environment.
-- James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Thu, 19 Aug 2004 15:49:14 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> > Generally speaking any MT support is inherently OS-dependant and can be
> > thought as a hardware feature in this respect.
>
> Java found a pretty good (albeit limiting in some ways) abstraction of that.
>
I hold the converse opinion.
> > Generally speaking, real Java code isn't as portable as it was promised.
> > But MT Java code is extremely non-portable.
>
> You're right... about of the state-of-the-art as of 2 years ago. Things have
> gotten better by leaps and bounds. And they are making progress *fast*.
>
I have been using Java for about 5 years: its _realworld_ progress is
questionable and there are a lot of signs of regress.
C++ is not a niche programming language so it must not copy Java MT design.
IMHO POSIX C++ binding is the way to go.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Thu, 19 Aug 2004 15:49:55 GMT Raw View
news@news.astraweb.com ("News Subsystem") writes:
> On Wed, 18 Aug 2004 20:45:25 GMT, "Andrei Alexandrescu (See Website for
> Email)" wrote:
>
>> So I think the "obvious reason" is that many standard C++ users and pundits
>> think that threads can be handled properly by a library. It cannot.
>
> I'm afraid that you may not be expressing yourself clearly enough. You say
> that threads can't be properly handled by a library, but there are
> obviously many people out there writing MT apps in C++ today using library
> implementations, and the apps are working just fine.
[snip]
Does anyone here know of a compiler which (a) is completely unaware of
threads, and (b) there is some 3rd party threading library which
works well when used with that compiler?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Thu, 19 Aug 2004 18:41:01 GMT Raw View
Dietmar Kuehl wrote:
[...]
>=20
>>I mean, well yes there is DOS which doesn't
>>support MT. Who would base any new project on DOS saying "my app needs =
to
>>be MT ?".. same with any Os not supporting MT.
>=20
>=20
> However, I would guess that the majority of systems, both in terms of
> operating system and number of machines, running C++ programs do not ha=
ve
> MT support! The majority of systems are not desktop machines or work
> stations but embedded systems. The DOS machines are indeed probably not
> the target of new projects but embedded systems definitely are.
However, more and more of the embeded system include MT support.
>>I think the easiest (and may be best way) to tackle this is to
>>require intelligence from the compiler to issue an error when <thread> =
would
>>be included.
>=20
>=20
> I would strongly oppose such an approach - assuming that <thread> is th=
e
> header which defines all thread related entities. I would not oppose th=
at
> e.g. attempting creation of a thread would yield an error but e.g. the
> lock mechanisms should be implemented as no-ops on systems not supporti=
ng
> multiple threads: this is crucial when implementing libraries which are
> intended to be used on more than one platform.
100% agreed. Thread creation and lock mechanism are totally diffent=20
issues in term of portability. One could also wonder wether lock issues=20
sould only be used for multithread, or also for multi-process. Thus some=20
notions of IPC might be usefull. I'm not sure wether they should be part=20
of the same proposal.
I'm not sure even that the model of thread implicit in this discussion=20
(explicit thread creation/destruction) is one size-fit all for all=20
application domain. For instance, on massively parallel computers, is=20
this the good metaphore?
[...]
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Mon, 23 Aug 2004 08:29:46 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> I agree that a POSIX C++ binding would be good. The problem is, C++ has so
> complex semantics, the pthreads people (who are, as a community, less
> experts in C++'s subtleties) won't attempt.
>
> So the binding needs to come from the C++ standardization committee.
>
Andrei, this statement can easily be inverted: MT programming has so complex
semantics, the C++ people won't attempt...
We're trying to introduce some standard MT support into C++. If some "C++'s
subtleties" don't allow us to introduce good MT support we'd better throw them
out of C++ rather than throw the pthreads people out of the process.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: stefan_heinzmann@yahoo.com (Stefan Heinzmann)
Date: Mon, 23 Aug 2004 08:30:00 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> I believe what's reasonable and doable is:
>
> a) Any thread API function (such as sleeping, locking a mutex, waiting for
> an asynchronous result) will throw an exception when thread cancelation has
> been requested. This way, a thread that has proper exception handling and
> uses some synchronization routine will finish properly. I wonder if CAS
> should be part of this group... what are other people's thoughts?
Can this be implemented without significant overhead in the
synchronization routines? People wo don't use thread cancellation may
not want to pay the price for it.
> b) A thread that hangs in a loop without calling any thread API function
> will not be stoppable.
>
> I think that's entirely reasonable. After all, you can't claim peaceful
> termination of a ST process that just hangs in a loop.
Agreed.
--
Cheers
Stefan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Mon, 23 Aug 2004 08:30:09 GMT Raw View
Roshan Naik wrote:
> I would disagree. Pthread bindings will only help people using pthreads
> library...
> what about the rest of the world ?
>
Well, POSIX isn't perfect. But currently it's the best standard for
_portable_ threads programming.
C++ must not be locked into any non-portable and/or proprietary MT model.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Mon, 23 Aug 2004 15:55:24 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
[...]
> >> > Also, variable-level visibility qualifiers may be inefficient even on
> >> > hardware that supports "everything". Consider a typical shared_ptr
> >> > reference count. It doesn't need any kind of barrier on increment and
> >> > needs a "conditional" barrier on decrement, depending on whether the
>
> (Incorrect quote btw...)
??? What do you mean?
[...]
> > Why would you need some barrier on increment?
>
> Not sure how Peter does it. You'd need a barrier at least on some
> architecture to read the counter even if you use CAS.
Do you have a link?
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Mon, 23 Aug 2004 15:58:07 GMT Raw View
Lo=EFc Joly wrote:
> Roshan Naik wrote:
>=20
>> Its not "just one system".. there are far too many platforms with MT=20
>> support.
>> And as I said it makes no sense running MT programs on non MT systems.
>> So thats a worthless goal for the standard to try to make your MT=20
>> programs
>> run or even compile on non MT systems.
>=20
>=20
> I have string class that uses COW. I want this class to be thread safe=20
> (in the way defined by Herb Sutter in the September 2004 CUJ). I also=20
> want to use it in monothread environment. And I don't want to use #if.=20
> In this case, making those synchronisations no-op is the perfect choice.
>=20
You know any non-MT operating systems on which COM is available ?
Yes, on MT systems where you want to write ST apps they could be
easily turned into NOPs. But ..this is not the big problem ...
the real problem is in doing MT right on MT systems with multiple
processors and funky memory subsystems.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Mon, 23 Aug 2004 16:32:55 GMT Raw View
Roshan Naik wrote:
>=20
>=20
> Lo=EFc Joly wrote:
>=20
>> Roshan Naik wrote:
>>
>>> Its not "just one system".. there are far too many platforms with MT=20
>>> support.
>>> And as I said it makes no sense running MT programs on non MT systems.
>>> So thats a worthless goal for the standard to try to make your MT=20
>>> programs
>>> run or even compile on non MT systems.
>>
>>
>>
>> I have string class that uses COW. I want this class to be thread safe=
=20
>> (in the way defined by Herb Sutter in the September 2004 CUJ). I also=20
>> want to use it in monothread environment. And I don't want to use #if.=
=20
>> In this case, making those synchronisations no-op is the perfect choic=
e.
>>
>=20
> You know any non-MT operating systems on which COM is available ?
I did not say COM, I said COW, a shorthand for copy on write. A still=20
common "optimisation" for strings.
> Yes, on MT systems where you want to write ST apps they could be
> easily turned into NOPs. But ..this is not the big problem ...
> the real problem is in doing MT right on MT systems with multiple
> processors and funky memory subsystems.
I agree it is not the most difficult problem. Nevertheless, some care=20
must be taken so that a not MT oriented library could be used equally=20
well with no rewriting on both a ST and a MT environment.
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Mon, 23 Aug 2004 16:57:14 GMT Raw View
Sergey P. Derevyago wrote:
> Andrei, this statement can easily be inverted: MT programming has so complex
> semantics, the C++ people won't attempt...
> We're trying to introduce some standard MT support into C++. If some "C++'s
> subtleties" don't allow us to introduce good MT support we'd better throw them
> out of C++ rather than throw the pthreads people out of the process.
Agreed. Threads are necessary. The more elaborate forms of
"generic programming" are optional. If push comes to shove, it's
clear what has to go.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Mon, 23 Aug 2004 21:31:48 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> "Roshan Naik" <someone@nowhere.com> wrote in message
> news:4126BE7A.93C58FF2@nowhere.com...
> > Question 1: how far does volatile go ?
> > -------------------
> > wouldn't ...
> >
> > (volatile int) b = 6;
> > (volatile int) a = 5;
> >
> > fix the problem you mention ?
>
> You mean:
>
> (volatile int&) b = 6;
> (volatile int&) a = 5;
>
Hmm ! So i guess this idiom wont work in C. As I understand C
doesnt have references. So it may need some more acrobatics
if only some reads and writes to the variables need to be deemed
observable behavior.
"Andrei Alexandrescu (See Website for Email)" wrote:
> It will fix the problem in the current thread, in that now you are
> guaranteed that in the current thread b will be assigned to before a. It
> won't guarantee (1) that other threads will see the same order; (2) the
> non-volatile reads and writes are in any way ordered, even in the current
> thread. The article (second part, DDJ Aug 2004) mentions both problems.
Yes. I read those two conlcusions (1 & 2). But the meaning of (1) wasnt clear
at all due to lack of a precise example. Do you mean other threads executing the
same (volatile marked) portion of code or other threads executing some other
piece
of code ? If so how can that come about ? I have been trying to warp my mind
trying
to think of what that means.
What came to my mind regarding (1) was : I beleive the
microprocessor "reordering engine" wont really guarantee that the
same set of assembly instructions to be executed in the same order each
time around.
(2) is not a big deal as it we are moving out of the realm of observable
behavior. Wherever the programmer wants strict ordering he needs to use
the right tools (whatever that might be...and if they exist).
"Andrei Alexandrescu (See Website for Email)" wrote:
> > I would imagine that compilers (today) aren't going to place a memory
> > barrier between the
> > statements
> > (in either of above case) ...but should it for MT programs ? Perhaps
> > yes(in my limited
> > wisdom).
>
> That would slow down the program down to a crawl.
Ofcourse. But correct semantics of observable behavior will be preserved.
No need to say... you cant sacrifice correctness to gain performance.
Which reminds me you mentioning somewhere "its easier to make a correct
program fast than a fast program correct" :-)
Anyway there is no performance requirement imposed on volatile by the standard
but it does implcitly demand correctness.
"Andrei Alexandrescu (See Website for Email)" wrote:
> > If not then how is volatile (or output functions) being guaranteeing
> > observable behavior today
> > ?
>
> Depends on the platform, the standard says.
Where?. I looked and couldnt find.
Even more dangerous is the following code
my_stream_object << "hello " ;
my_stream_object << "world" ;
The system(compiler, processor, memory subsystem) can print
(to file/socket/pipe/whereever) "world" first and then followed by "hello"
..depending upon the platform ! Why is it more dangerous ?
because the standard doesnt define "library I/O functions". While atleast
there is some attempt made to define volatile.
If compiler has intimate knowledge about its i/o functions(which is likely
true),
then we are deep trouble! We would need to approach the compiler vendors
to modify their compiler to all us to write our custom i/o libraries (same as
POSIX Pthreads to C bindings). Wow !
"Andrei Alexandrescu (See Website for Email)" wrote:
> > Aside from the instruction(memory ?) ordering problem the DDj article
> > pointed out (as I
> > understand)
> > that updates to data (pInstance) on one processor are not necessarily
> > visible to other
> > processor's.
> >
> > So does that mean two independent problems...
> > - instruction ordering,
> > - memory (or cache ?) coherency
> > - (and maybe a third..) memory ordering
> >
> > ?
>
> It's the memory reads and writes that are important. The issues you mention
> are all causes of the lack of causality between reads and writes among
> various threads, which is causing all of the headache.
>
Ok thanks ! So memory ordering and instruction ordering are two independent
terms.
and instruction ordering may (or may not) influence memory ordering.
And, as u mentioned below, instruction ordering is not our concern, memory
ordering is.
Now this is leading us to a very intresting tarpit (as I note next)......
"Andrei Alexandrescu (See Website for Email)" wrote:
> > Question 3 : instruction v/s memory ordering
> > ------------------------------------------------------
> >
> > Now, very often i see people referring to "memory ordering" being referred
> > to and then
> > providing
> > examples dealing with instruction ordering.
> >
> > Cuz (as I understand) regardless of the compiler or processor doing things
> > "right", the memory
> >
> > subsystem has its own mind on how those updates will be really done. So
> > telling the processor
> > anything
> > seems like waste. I am thinking perhaps these two terms (instruction /
> > memory ordering )
> > should be used more carefully...and precisely.
>
> It's not that bad. Instruction ordering is irrelevant as long as it doesn't
> produce reorderings of reads and writes. Most of the time, the compiler does
> instruction reordering. Then there comes the hardware that reorders memory
> accesses again.
>
> Mentally, I think of it that way (and simplify my life a lot in the
> process): Between your source code and the electrons there is an entity that
> reorders all it wants as long as it stays within observable behavior. Then I
> need to only focus on understanding observable behavior and (according to
> it) what legal executions of my code are possible.
>
> > So is it right to say that asking the processor to update memory in a
> > certain order has no
> > bearing
> > on how the memory is finally updated by the memory subsystem in a
> > multiprocessor subsystem ?
>
> That is correct (on some systems).
If thats true we are chasing a problem thats not solvable on those systems
by the gamut of language designers, compiler writers and microprcoessor
designers and (last and also the least) a programmer.
volatile seems to be only helping in constraining instructions ordered by the
optimizer. Unless compiler places memory barriers, the processor
can still come around and execute instructions any which way it feels like.
Even if it doesnt, this does not necessarily have an effect on
memory ordering.
The problem is the approach itself then, and i can try to
described in short (in my words).....
"We are trying to control memory ordering by controlling instruction ordering"
Futile ... atleast theoretically.
Programmers would need something that instruct ALL the layers
it relies upon (compile,processor and memory system) to
do the right memory ordering. what is missing link in the chain
seems like a communication between the processor and
the memory subsystem. (also between programmer and processor
if there are no memory barriers between volatile reads and writes)
"Andrei Alexandrescu (See Website for Email)" wrote:
> Historically, the speed gap inside the
> memory hierarhcy (processor registers - L1 cache - L2 cache - DRAM - disk)
> is increasing exponentially. (By 2010, if the current trends go forth,
> formatting an HDD will take a week. I guess new disk drivers will format
> on-the-fly as needed.) Therefore, drastic measures must be taken to
> streamline communication within the memory hierarchy. Burst updates from
> cache to RAM are an effective one.
I would imagine similar weird problems can happen with disk drives and other
storage
devices. So we are not just talking about problems with main memory but also
external I/O devices. As I pointed out in the code above.
Hopefully when you read this email message the text is in the same order as I
typed it
- Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Mon, 23 Aug 2004 22:06:58 GMT Raw View
Given the complexities apparently involved, I feel that a new
committee/group needs to be created to look specifically into
threading issues. Not sure if it would have to be a formal ISO committee
or just a "task group" (no pun intended :-) and make it less formal.
A commitee/group comprised of experts from the threading and C++ worlds
might help the cause, and also relieve some burden off of the core language
and LWG committees. Anyway both these committees (not the members
individually though ) are more of "inspectors" that pass/reject/review proposals
We need a group that pursues different solutions and finally comes up with a
proposal
for the main committees in the area of MT.
-Roshan
[ I must admit..."design by committee" ...gives me the shivers. ]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Tue, 24 Aug 2004 00:38:47 GMT Raw View
Altought I dont like nuking off a thread I can definitely imagine there are
many
cases where it is indeed safe to do so.
- A thread can get stuck (hung or whatever) interacting with some external
world
due problem associated with the connecting fabric and weak protocol, and
the
thread doesnt use any important resources that if killed by brute force
wont mess
things up. It is best to be able to provide a button that allows end user
to nuke the thread
w/o bothering about proper clean up.
"Andrei Alexandrescu (See Website for Email)" wrote:
> "David Abrahams" <dave@boost-consulting.com> wrote in message
> news:u8yc75o5n.fsf@boost-consulting.com...
> > The only hard things there are "political," (**) not technical. The
> > political difficulties are:
> >
> > 1. That there's already some precedent somewhere for throwing
> > exceptions for thread cancellation from 'C' library functions.
> > That's a suboptimal choice at best, but it's hard to swim against
> > the tide.
> >
> > 2. Some people believe strongly that it should be possible to ensure
> > that thread cancellation requests can never be ignored and always
> > lead to thread termination in finite time. That's just
> > impossible to do in general without corrupting program state
> > (i.e. crashing), but these people aren't convinced.
> >
> > So if someone can tackle the political problems, we can get on with
> > implementing the obvious <wink> technical solutions.
>
> I guess the hard part is to present people under (2) a viable compromise.
>
> I believe what's reasonable and doable is:
>
> a) Any thread API function (such as sleeping, locking a mutex, waiting for
> an asynchronous result) will throw an exception when thread cancelation has
> been requested. This way, a thread that has proper exception handling and
> uses some synchronization routine will finish properly. I wonder if CAS
> should be part of this group... what are other people's thoughts?
>
> b) A thread that hangs in a loop without calling any thread API function
> will not be stoppable.
>
Will "thread API" function also be as fuzzy a concept as "standard I/O
functions" ?
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Tue, 24 Aug 2004 00:39:15 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> >> "Roshan Naik" <someone@nowhere.com> wrote in message
> >> news:4126BE7A.93C58FF2@nowhere.com...
> >> > Question 1: how far does volatile go ?
> >> > -------------------
> >> > wouldn't ...
> >> >
> >> > (volatile int) b = 6;
> >> > (volatile int) a = 5;
> >> >
> >> > fix the problem you mention ?
> >>
> >> You mean:
> >>
> >> (volatile int&) b = 6;
> >> (volatile int&) a = 5;
> >>
> >
> > Hmm ! So i guess this idiom wont work in C. As I understand C
> > doesnt have references. So it may need some more acrobatics
> > if only some reads and writes to the variables need to be deemed
> > observable behavior.
>
> It's trivial to transform the code above to use pointers.
Is It ? You mean like this (in C)....
*(volatile int*)&b = 6;
.. but that only says that the address of b is volatile. it doesnt say
that the assignment to b is volatile. thats brings you back to casting to
volatile int....
(volatile int ) * (volatile int*)&i = 4;
> It's very hard to talk about what threads could do in a language that has a
> single-threaded abstract machine. We can contemplate our navels all year
> long. This ends the whole discussion on C++ volatile's merits rather
> abruptly.
The other usual foregone conclusion "C++ abstract machine is single threaded"
is inaccurate in absolute terms. The standard doesnt say it is single threaded
nor does it say that it is multi threaded. Consequently it is
"thread-defective"...
incomplete.... or undefined. take your pick.
Getting pedantic about it...if the C++ abstract machine were prohitbited from
being MT, then a MT program is a non-conformant (as opposed to undefined)
program, even in the simple case that none of the threads perform any
synchronization.
> In short: volatile won't cut it. At all. Java 1 tried to redefine it so that
> it does. It still didn't. Java 1.5 defined one that does. (But that's too
> restrictive.)
[..snip..]
> I did. I snipped most of it because it drives from an untrue conjecture.
> Volatile won't help.
I fully agree ! In theory it should have helped. In reality it doesnt it.
As 'volatile' ness about the portion of code is lost after the optimizer stage.
I must add at this point.... we are not just dealing with MT and main memory.
We are dealing also with "true" I/O for ST programs.. 1st program comes in
and does some IO... termiantes. ...next program comes in and does some more
IO...terminates..... now how the IO of the two programs is actually reflected
on the final device/stream/whatever is not defineable at source code
level...without certain guarantees from underlying
layers(os/compiler/driver/...).
The need to make use of these guarantees on ordering has to be expresssable in
source code by programmer and this info must reach out to all the layers.
In practice I/O is perhaps less of an issue than memory for such cases.
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Tue, 24 Aug 2004 02:41:07 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> > As David Butenhof has written: "multithreading is defined by an
> > application design that ALLOWS FOR concurrent or simultaneous execution".
> > That is your "synchronization by manipulating memory locations directly,
> > not by locking" definition does NOT allow for simultaneous execution.
> >
> It does, except in very few points. No?
>
Point of view is the key.
MT code should be designed in such a way that several threads work
simultaneously and almost independently. The points where they _must_
synchronize their work are really rare. These synchronization points are _not_
the bottle neck.
So why are you playing around synchronization? We'd better fight for the
standard that allows for concurrent execution rather than for premature
locking optimization.
> > My point is: Is it _really_ so important to have some special support by
> > core of general purpose programming language like C++? Do we fight _main_
> > MT targets dealing with it?
> >
> What would be the alternative? Let people who want to write portable MT
> programs flock to other languages?
>
Portable MT is _nice_ to have. The success of C++ is based on the good enough
implementation of the "must have" features.
> Friend templates, forwarding constructors, or template typedefs won't be
> strategic reasons to choose a language. Portable MT support can be.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: non-existent@iobox.com ("Sergey P. Derevyago")
Date: Wed, 18 Aug 2004 11:35:03 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> C++, as we all know, chose (and as far as I understand, is undecided as of
> the next standardization iteration) to stay away from MT altogether.
>
One of the main goals of C/C++ design is to work with hardware without
"artificial" overhead. In theory, C/C++ doesn't try to define some standard
(i.e. "one size fits all") binding to some hardware feature if it can not be
implemented without such an overhead.
Generally speaking any MT support is inherently OS-dependant and can be
thought as a hardware feature in this respect.
> Once it became evident that threads must be part of the language
>
IMHO it's not the case.
Obviously, there must be some way to do _portable_ MT in C++ and it seems
like (currently unavailable) POSIX C++ binding is what we need in this
respect.
BTW there are a lot of (really important) environments that have C++
implementations but do _not_ support MT. Are you going to force these
implementations to somehow emulate MT?
> Java even has lock-free structures in their current distribution
> (http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html).
> If this trend will continue, soon Java will be the language of choice for
> portable multithreaded programming, and standard C++ will be out in the cold
> clenching its teeth.
>
Actually, Java gives you almost _nothing_ w.r.t. _portable_ MT: too many
critically important features are unspecified and/or implementation dependant.
Generally speaking, real Java code isn't as portable as it was promised. But
MT Java code is extremely non-portable.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Wed, 18 Aug 2004 16:53:51 GMT Raw View
"Sergey P. Derevyago" wrote:
[...]
> Obviously, there must be some way to do _portable_ MT in C++ and it seems
> like (currently unavailable) POSIX C++ binding is what we need in this
> respect.
Yeah.
http://www.codesourcery.com/archives/c++-pthreads/msg00005.html
regards,
alexander.
P.S. c++-pthreads list is pretty dead. Time to resurrect... ;-)
--
"Notwithstanding the provisions of section 106(3), the owner of
a particular copy or phonorecord lawfully made under this title,
or any person authorized by such owner, is entitled, without
the authority of the copyright owner, to sell or otherwise
dispose of the possession of that copy or phonorecord."
-- 17 USC 109 (aka "GPL killer")
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Wed, 18 Aug 2004 18:42:56 GMT Raw View
Dietmar Kuehl wrote:
> As far as I can tell, nobody is pushing multi-threading in the
> standardization committee. The obvious reason for this is that apparently
> nobody has sufficient interest to push this issue. If there is not
> sufficient interest, why standardize it?
There is no interest in MT with C++ ? I think the reality
is that, the complexity of the task is a little steep for the ordinary
programmer to come up with a proposal that fits the C++ mantra
of being "meticulous and comprehensive". I bet you, if MT makes
its debut into the C++0x standard, the rest of the big new features will
hardly even be noticeable.
My understanding is that the LWG's primary task is to review proposals
and reject them or accept them(with or without modifications). "Design by
Committee" doesn't work very well for complex coherent tasks anyway. So until
some bright chappy comes along with something good the committee wont
be making a move. No proposal, no feature!
> The standardization committee is well aware of the existance of threads
> and I doubt that it will reject a reasonable proposal adding threads to
> C++ (although such a proposal probably will have to address how thread
> support is to be implemented on systems not supporting threads).
I would imagine that this requirement (if true) would be the biggest impediment
to
ever having MT in the standard. I mean, well yes there is DOS which doesn't
support MT. Who would base any new project on DOS saying "my app needs to
be MT ?".. same with any Os not supporting MT.
I think the easiest (and may be best way) to tackle this is to
require intelligence from the compiler to issue an error when <thread> would
be included ....on a platform that doesn't support MT. Case closed! The rest
of the world shouldn't be penalized cuz a small fraction of the systems do not
have
certain capabilities. If they dot have MT capability then they aren't going to
use it anyway,
so better not to fuss too much.
> However,
> the committee will not start working on multi-threading: the work has to
> be done by people who are interested in this area. At the last Redmond
> meeting was a presentation of the Boost thread library which was well
> received. However, since then the proponents of this library apparently
> discontinued their work, at least as far as I can tell from a
> standardization perspective.
When I saw some early presentations by Bjarne on C++0x, i thought threading was
indeed
going to be part of the standard....as it was one of big ticket items. I hope
sockets make
their debut too. A new standard with just a bunch of ultra smart pointers,
pretty hash tables and
some more razzle dazzle isn't quite worth it.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Thu, 19 Aug 2004 01:41:04 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
[...]
> A look into Java's new semantics of the volatile keyword (which are pretty
> good but still too limiting) is a great point to start.
Java's new volatiles are Not Good. They are inefficient (impose
most expensive store-load barrier even when you don't need it)
and rather confusing (many erroneously think that "volatile_a++"
is atomic) beasts. You might want to take a look at: (Subject:
Re: DCSI - thread safe singleton ;-) )
http://groups.google.com/groups?selm=40F4F750.FE8BCD9B%40web.de
http://groups.google.com/groups?selm=40F647F8.F59FE644%40web.de
http://groups.google.com/groups?selm=40f77780_1%40news.melbourne.pipenetworks.com
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]