Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multithreaded programming: is the C++ standardization committee listening?

59 views
Skip to first unread message

Andrei Alexandrescu (See Website for Email)

unread,
Aug 18, 2004, 1:36:48 AM8/18/04
to
Years ago, Java decided to add support for multithreading to the core
language. Many MT experts said that the support was not very good. Standard
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.

Since then, a predictable sequence of events has happened.

The Java community got better at what they were doing, and the C++ community
continued to segregate deeper and deeper among standard-conforming
programmers who don't use MT, multi-standard programmers who use, say,
pthreads and its C binding (and tread carefully as far as mixing C++ with
pthreads go), and hard-core MT programmers who use nonportable documentation
provided by their own platform and compiler.

Once it became evident that threads must be part of the language, the
pursuit of better language-level abstractions for multithreading naturally
continued within the Java research and industrial communities. Also,
hard-core C and C++ MT programmers became a more and more isolated clique
(occasionally perceived at snooty by the standard-compliant programmers who
don't understand the complexities that are at stake).

As a result, much of the research on the recent lock-free data structures
(which surpass the now-familiar lock-based structures in performance) has
been done in Java or uses C/C++ only as "pseudocode", the real C/C++ code
being not portable.

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.

Does the C++ standardization committee plan to address threads at all, or
continue to ignore them?


Andrei


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Sergey P. Derevyago

unread,
Aug 18, 2004, 7:35:03 AM8/18/04
to
"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

Balog Pal

unread,
Aug 18, 2004, 10:17:52 AM8/18/04
to
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsit...@moderncppdesign.com> wrote in message

> Does the C++ standardization committee plan to address threads at all, or
> continue to ignore them?

Is there a proposal the committee can chew on?

If there is, they must deal with it one way or another.
If there isn't we (mean you, me, others who care) shall flesh out one ASAP.

Craig Henderson

unread,
Aug 18, 2004, 10:43:55 AM8/18/04
to

""Andrei Alexandrescu (See Website for Email)""
<SeeWebsit...@moderncppdesign.com> wrote in message
news:2ofbepF...@uni-berlin.de...

[snip]

> The Java community got better at what they were doing, and the C++
community
> continued to segregate deeper and deeper among standard-conforming
> programmers who don't use MT, multi-standard programmers who use, say,
> pthreads and its C binding (and tread carefully as far as mixing C++ with
> pthreads go), and hard-core MT programmers who use nonportable
documentation
> provided by their own platform and compiler.

I'd put myself in the latter classification...

[snip]

>
> Also,
> hard-core C and C++ MT programmers became a more and more isolated clique
> (occasionally perceived at snooty by the standard-compliant programmers
who
> don't understand the complexities that are at stake).

Really?

> As a result, much of the research on the recent lock-free data structures
> (which surpass the now-familiar lock-based structures in performance) has
> been done in Java or uses C/C++ only as "pseudocode", the real C/C++ code
> being not portable.

The implementation language is surely irrelevent in pure 'research' terms.
I'd expect research to develop ideas and algorithms, with proof and
investigation in a specific language for sure, but not limited to it.


> Java even has lock-free structures in their current distribution
>
(http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentLink
edQueue.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.

Isn't the lock-free structure (in)capability of C++ more an issue of GC than
MT?

>
> Does the C++ standardization committee plan to address threads at all, or
> continue to ignore them?

I have no affiliation with the standardization commitee, but what exactly do
you want to be addressed? I disagree that MT is an issue for the language
standard. 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. An issue such as MT is better addressed by a
library implementation rather than a language definition. There are such
libraries in existence (Boost.Threads for example), and standards such as
POSIX make portable library definitions easier.

If your query is whether or not the commitee will standardize a library such
as Boost.Threads into the STL, then I agree this would be useful. However,
any further requirement on the language syntax/semantics could cause
portability issues of the standard itself.

-- Craig

tom_usenet

unread,
Aug 18, 2004, 12:52:24 PM8/18/04
to
On Wed, 18 Aug 2004 05:36:48 GMT,
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See

Website for Email)") wrote:

>Does the C++ standardization committee plan to address threads at all, or
>continue to ignore them?

Seems like unless boost.threads is "finished" (e.g. atomic ops,
membars, the rest of pthreads functionality added, etc.), there is
nothing for the standardization committee to standardize!

What language changes would be useful to make the writing of
threadsafe applications easier? (I think this is a question for the
hard-core multithreaders)

Tom

Alexander Terekhov

unread,
Aug 18, 2004, 12:53:51 PM8/18/04
to

"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")

Thorsten Ottosen

unread,
Aug 18, 2004, 12:54:23 PM8/18/04
to
""Balog Pal"" <pa...@lib.hu> wrote in message news:4123...@andromeda.datanet.hu...

| ""Andrei Alexandrescu (See Website for Email)""
| <SeeWebsit...@moderncppdesign.com> wrote in message
|
| > Does the C++ standardization committee plan to address threads at all, or
| > continue to ignore them?
|
| Is there a proposal the committee can chew on?

nope.

| If there is, they must deal with it one way or another.
| If there isn't we (mean you, me, others who care) shall flesh out one ASAP.

AFAIK, nobody within the committee is actively persuing this. I think people are waiting
for boost.thread to mature perhaps with Kevlin Henney's ideas build on top of it. So right now
people are expecting a library solution.

br

Thorsten

Dietmar Kuehl

unread,
Aug 18, 2004, 1:17:20 PM8/18/04
to
Andrei Alexandrescu wrote:
> Does the C++ standardization committee plan to address threads at all, or
> continue to ignore them?

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?

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). 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.
--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Steven E. Harris

unread,
Aug 18, 2004, 1:20:47 PM8/18/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:

> Java even has lock-free structures in their current distribution

It's nice to see Doug Lea's util.concurrent library getting into the
Java standard library. I read his /Concurrent Programming in Java/
several years ago, used his Java library on some projects, and ported
much of it to C++ atop ACE.

Perhaps Alexander Terekhov can bring similarly powerful knowledge to
bear on C++'s progress (via Boost).

--
Steven E. Harris

Roshan Naik

unread,
Aug 18, 2004, 2:42:56 PM8/18/04
to

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.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 18, 2004, 2:54:16 PM8/18/04
to
""Craig Henderson"" <"."@eu.uu.net> wrote in message
news:41235a93$0$20252$ed9e...@reading.news.pipex.net...

>> As a result, much of the research on the recent lock-free data structures
>> (which surpass the now-familiar lock-based structures in performance) has
>> been done in Java or uses C/C++ only as "pseudocode", the real C/C++ code
>> being not portable.
>
> The implementation language is surely irrelevent in pure 'research' terms.
> I'd expect research to develop ideas and algorithms, with proof and
> investigation in a specific language for sure, but not limited to it.

That is true. Yet programming language research is always interested in
finding the right language abstractions that allow all sorts of
optimizations while allowing the programmer to specify synchronization.

> Isn't the lock-free structure (in)capability of C++ more an issue of GC
> than
> MT?

No, as Michael Maged's recent papers show.

>> Does the C++ standardization committee plan to address threads at all, or
>> continue to ignore them?
>
> I have no affiliation with the standardization commitee, but what exactly
> do
> you want to be addressed? I disagree that MT is an issue for the language
> standard.

I am sorry, but your opinion is entirely wrong. This has been exceedingly
shown by Doug Lea's, William Pugh, and many others' research on Java MT
programming. I also hope that "C++ and The Perils of Double-Checked Locking"
by Scott Meyers and myself (Doctor Dobb's Journal, July and August 2004)
shows very clearly how MT hits at the core of language semantics and code
generation.

Unfortunately, I am afraid that some more influential (to the
standardization process) people are of the same opinion. They'd think, "hey,
no problem. Sooner or later someone will come with a good library proposal,
and we'll look into it. At any rate, changes in the core language will be
minimal if at all."

> 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. An issue such as MT is better addressed by
> a
> library implementation rather than a language definition. There are such
> libraries in existence (Boost.Threads for example), and standards such as
> POSIX make portable library definitions easier.

Again, it's a core language issue, and emphatically so. Thinking that MT can
be handled by a library is a chymera. For those who don't know, POSIX
threads is not a library, it's a "C compiler subspec + library" combo. There
are specific requirements that POSIX threads makes of the C compiler used
with it, which is a most awkward situation.

> If your query is whether or not the commitee will standardize a library
> such
> as Boost.Threads into the STL, then I agree this would be useful. However,
> any further requirement on the language syntax/semantics could cause
> portability issues of the standard itself.

No, my query is NOT about standardizing a library. (In particular, now that
we got to talk about Boost.threads, I don't like it at all. I'd actually go
ahead and say, I actively dislike it. I think standardizing Boost.threads
would be an order of magnitude a bigger gaffe than standardizing
shared_ptr.)

My query is for people in the committee to (1) understand the current
semantics of Java's volatile, (2) look into current research in MT lock-free
structures and Java's new, exceedingly powerful MT libraries, (3) understand
how they CANNOT be replicated in standard C++, (4) understand that that's a
huge "competitive threat", and (5) take the appropriate measures.


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 18, 2004, 2:54:32 PM8/18/04
to
"tom_usenet" <tom_u...@hotmail.com> wrote in message
news:6uh6i0tbr0j0urbno...@4ax.com...

> On Wed, 18 Aug 2004 05:36:48 GMT,
> SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See
> Website for Email)") wrote:
>
>>Does the C++ standardization committee plan to address threads at all, or
>>continue to ignore them?
>
> Seems like unless boost.threads is "finished" (e.g. atomic ops,
> membars, the rest of pthreads functionality added, etc.), there is
> nothing for the standardization committee to standardize!
>
> What language changes would be useful to make the writing of
> threadsafe applications easier? (I think this is a question for the
> hard-core multithreaders)

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.

In short, the language should be able to allow programmers to specify that
certain variable types must be read and written to in the exact order of the
reads and writes as the source code's sequence points dictate.


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 18, 2004, 2:54:41 PM8/18/04
to
""Thorsten Ottosen"" <nes...@cs.auc.dk> wrote in message
news:4123699d$0$73951$1472...@news.sunsite.dk...

> ""Balog Pal"" <pa...@lib.hu> wrote in message
> news:4123...@andromeda.datanet.hu...
> | ""Andrei Alexandrescu (See Website for Email)""
> | <SeeWebsit...@moderncppdesign.com> wrote in message
> |
> | > Does the C++ standardization committee plan to address threads at all,
> or
> | > continue to ignore them?
> |
> | Is there a proposal the committee can chew on?
>
> nope.
>
> | If there is, they must deal with it one way or another.
> | If there isn't we (mean you, me, others who care) shall flesh out one
> ASAP.
>
> AFAIK, nobody within the committee is actively persuing this. I think
> people are waiting
> for boost.thread to mature perhaps with Kevlin Henney's ideas build on top
> of it. So right now
> people are expecting a library solution.

But that's a fallacy. They're expecting something that doesn't exist. MT
can't be confined to a library. It is a core language issue.

So people should be educated about what they can expect, and take the
appropriate measures. Hence my post.


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 18, 2004, 4:45:25 PM8/18/04
to
"Dietmar Kuehl" <dietma...@yahoo.com> wrote in message
news:5b15f8fd.04081...@posting.google.com...

> Andrei Alexandrescu wrote:
>> Does the C++ standardization committee plan to address threads at all, or
>> continue to ignore them?
>
> 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?

One reason is unawareness of competitive threat from other languages.

Another is that (from my own interactions with the MT community) many
hardcore MT programmers aren't active in the standard C++ language community
and vice versa. They are people who have hard problems, know how to solve
them, understand they can't be solved in standard C++, and go on about doing
their job instead of convincing others that they ought to be able to do
their job easily and portably.

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. If
enough people understand that, and also understand the competitive benefit
that Java's threading amenities lends to that language, interest will be
born.

> 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). However,
> the committee will not start working on multi-threading: the work has to
> be done by people who are interested in this area.

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?

> 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.

I think discontinuing that work was a lucky turn of events :o).


Andrei

Howard Hinnant

unread,
Aug 18, 2004, 7:06:07 PM8/18/04
to
In article <2ohmicF...@uni-berlin.de>,
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See
Website for Email)") wrote:

> My query is for people in the committee to (1) understand the current
> semantics of Java's volatile, (2) look into current research in MT lock-free
> structures and Java's new, exceedingly powerful MT libraries, (3) understand
> how they CANNOT be replicated in standard C++, (4) understand that that's a
> huge "competitive threat", and (5) take the appropriate measures.

Just so you know Andrei, the deadline for the pre-Redmond mailing is
Sep. 10. So you shouldn't dally. :-)

-Howard

Andrei Alexandrescu (See Website for Email)

unread,
Aug 18, 2004, 9:40:25 PM8/18/04
to
""Sergey P. Derevyago"" <non-ex...@iobox.com> wrote in message
news:41233B8F...@iobox.com...

> "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.

Java found a pretty good (albeit limiting in some ways) abstraction of that.

>> 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.

There is no way of doing portable MT in C++. The POSIX threads C binding
imposes ways in which the C compiler works. The currently nonexisting POSIX
threads C++ binding would have some much more to say about how the C++
compiler must work.

> 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?

No. The thread creation functions would always fail on those ports, and the
threading-related type modifiers would be ignored.

It's the latter I'm most worried about, because they address changes to the
core language.

>> 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.

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*.


Andrei

Alexander Terekhov

unread,
Aug 18, 2004, 9:41:04 PM8/18/04
to

"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.

Thorsten Ottosen

unread,
Aug 18, 2004, 9:48:56 PM8/18/04
to
| ""Thorsten Ottosen"" <nes...@cs.auc.dk> wrote in message

| > AFAIK, nobody within the committee is actively persuing this. I think


| > people are waiting
| > for boost.thread to mature perhaps with Kevlin Henney's ideas build on top
| > of it. So right now
| > people are expecting a library solution.
|
| But that's a fallacy. They're expecting something that doesn't exist. MT
| can't be confined to a library. It is a core language issue.
|
| So people should be educated about what they can expect, and take the
| appropriate measures. Hence my post.

Ok. I'm sure a lot of people would appreciate that you showed up in Redmond with a proposal under your
arms, or better yet, wrote one for the 10th sept deadline.

br

Thorsten

John Nagle

unread,
Aug 19, 2004, 12:00:00 AM8/19/04
to
Andrei Alexandrescu (See Website for Email) wrote:
> "Dietmar Kuehl" <dietma...@yahoo.com> wrote in message
> news:5b15f8fd.04081...@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

Edward Diener

unread,
Aug 19, 2004, 12:00:43 AM8/19/04
to
"Andrei Alexandrescu (See Website for Email)" wrote:
> ""Craig Henderson"" <"."@eu.uu.net> wrote in message
> news:41235a93$0$20252$ed9e...@reading.news.pipex.net...
>> 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. An issue such as MT is better
>> addressed by a
>> library implementation rather than a language definition. There are
>> such libraries in existence (Boost.Threads for example), and
>> standards such as POSIX make portable library definitions easier.
>
> Again, it's a core language issue, and emphatically so. Thinking that
> MT can be handled by a library is a chymera.

It's chimera. But why do you believe that ? Just saying so does not make it
so unless you have some proof. From what you say, it sounds like you believe
that something in the C++ language itself makes it incapable of allowing a
fail-safe threading library to be written. Yet OSs whose threading support
is clearly done through just procedural function calls do support threading.
If you have arguments why effective threading can not be done at the library
level in C++, you need to make them rather than just asserting that what you
believe to be true is true.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 12:39:50 AM8/19/04
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:4123BD01...@web.de...

>
> "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

I am aware of those limitations. I believe advanced optimizations can
overcome some of them. The funny thing is, even with Java 1.5 overly
limiting volatile, one can write MT Java code that's fast and portable.

But volatile is not the only thing I worry about. CAS is another one.


Andrei

Jim Hyslop

unread,
Aug 19, 2004, 12:40:03 AM8/19/04
to
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

News Subsystem

unread,
Aug 19, 2004, 12:59:01 AM8/19/04
to
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. How, specifically,
for those of us who are not experts, are they not handling threads
properly? Is it simply an efficiency concern, or are there things that
absolutely cannot be done without language support? (I haven't had a
chance to get to your DDJ article yet. It's in the "to read" pile.)

You wrote earlier:

> In short, the language should be able to allow programmers to specify that
> certain variable types must be read and written to in the exact order of the
> reads and writes as the source code's sequence points dictate.

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?

I'm not asking questions idly. I really am interested in the answers, and
I expect others are too. I guess what I'm saying is you can't just drive
by with a bandwagon and expect everyone to jump on, you need to tell them
why it's better than the other bandwagons.

--
Greg Schmidt gr...@trawna.com
Trawna Publications http://www.trawna.com/

Jim Hyslop

unread,
Aug 19, 2004, 2:17:18 AM8/19/04
to
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

Jim Hyslop

unread,
Aug 19, 2004, 2:17:39 AM8/19/04
to
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


Uwe Schnitker

unread,
Aug 19, 2004, 4:02:07 AM8/19/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2ohnh2F...@uni-berlin.de>...

<SNIP>

> 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.

Hmm, Andrei, since you cannot yet present a proposal to seed a
discussion, how about filing a defect report?

After all, AFAIK (which is admittedly not very deeply), the attitude
you are engaging against can be subsumed like "MT can be done by a
library, using the native means behind an abstraction, and carefully
guarding the critical variables by declaring them as volatile", and
one of the main issues that transformed the DCL into "Triple-Checked
Locking" is that volatile is not sufficient to bestow that protection.

Of course, the standard doesn't mention multithreading, but - not
having a copy at hand - to my understanding it claims that volatile
can be used to protect against misoptimizations with variables that
can be altered by an outside effect (which could be construed to
nclude "another thread").

A defect report "insufficient specification of volatile" would in all
probability be rejected as NAD in the end, but you would at least
"force" some discussion about the issue.

OTOH, this could be seen as abusing the system - maybe I shouldn't
have read Grisham's "The King Of Torts" lately :-( - and might not
be the best way to earn respect and empathy from the standard comittee
members, wich could be important if you want to achieve progress in
the future.

But such an action would be truly Quixotic (rsp. Alexandresque),
wouldn't it?

With the usual very high regards,

Uwe

Thorsten Ottosen

unread,
Aug 19, 2004, 10:39:33 AM8/19/04
to
"John Nagle" <na...@animats.com> wrote in message news:bJQUc.7526$iW....@newssvr29.news.prodigy.com...

| The committee also has driven away the safety, quality,
| and reliability people.

really? can you mention people who have written proposals and showed up to meetings
that was not taken serious?

| 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.

what holes are you talking about.

| We pay for this every day, as buffer
| overflow stories make the headlines in the mainstream press.

well, if one is ignorant enough to use built-in arrays directly, you get what you ask for.

| The committee's emphasis is on obscure template features too
| fragile to use in production code.

not sure what you mean exactly. If you think a template is
too "hardcore" for your work, then you will get the very big benefit
of libraries written in it. This is a hige benefit for "production code".

| Remember Pascal. Good language, botched standard,
| refusal by key designer to fix clear problems. Nearly
| dead today. That's where C++ is headed.

maybe for you, not for me.

br

Thorsten

Loïc Joly

unread,
Aug 19, 2004, 10:40:37 AM8/19/04
to
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. If
> enough people understand that, and also understand the competitive benefit
> that Java's threading amenities lends to that language, interest will be
> born.

If you give us an link to an article that explains that, instead of just
vague allegations that Java does it better, then poeple will be able to
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). However,
>>the committee will not start working on multi-threading: the work has to
>>be done by people who are interested in this area.
>
>
> 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?

What is "PL language" ?

--
Loïc

Dietmar Kuehl

unread,
Aug 19, 2004, 10:42:00 AM8/19/04
to
som...@nowhere.com (Roshan Naik) 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).
>
> I would imagine that this requirement (if true) would be the biggest
> impediment to ever having MT in the standard.

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 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.

However, I would guess that the majority of systems, both in terms of
operating system and number of machines, running C++ programs do not have
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.

> 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.

> ...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.

> 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.

> 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.

For neither of these things there is a proposal. Personally, I doubt that
sockets will become available in standard C++. I would guess that threads
become available assuming that there are people knowledgable in the area
which push the issue.

> A new standard with just a bunch of ultra smart pointers,
> pretty hash tables and
> some more razzle dazzle isn't quite worth it.

Well, I'm not too excited about these issue, too, but there are things
I'm more interested in than e.g. sockets: I'm already using sockets
using [platform specific] C functions wrapped by a stream buffer. I
don't use e.g. some form of reflection because it is not available.


--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

---

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 11:47:54 AM8/19/04
to
"Jim Hyslop" <jhy...@ieee.org> wrote in message
news:4124340A...@ieee.org...

> 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."

That's how I was thinking of a setup, too. Similarly, C++ can be (and is)
implemented on systems or subsystems that have no filesystems or no standard
I/O console. In Windows native programs there's no console unless you create
one explicitly, and if you write a Windows service, you might not have
access to the display altogether.

Andrei

James Dennett

unread,
Aug 19, 2004, 11:48:10 AM8/19/04
to
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

Balog Pal

unread,
Aug 19, 2004, 11:48:53 AM8/19/04
to
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsit...@moderncppdesign.com> wrote in message

> I understand that. But that's also a "put up or shut up" attitude.

IMHO it's more like asking the general to fly from flower to flower like a
bee.

Suppose you have the wand to mind twist the members to whatever you think.
And they all recon what you say, core issues shall be fixed, and there is
the competitive stuff and all. Then what? To have stuff it still must be
made. And by those who can do it. Who have enough understanding of the
issues. And those are people you hardly need the wand to use on.

> 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.

*If* I understand the committee work correctly, that's not their way.
And probably it's more effective to attract those people separately, by
other members of that group, and make the WG21 involved only when there is a
proposal created.

> 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?

Where can I read about that episode?
- -------------

> Unfortunately, I am afraid that some more influential (to the
> standardization process) people are of the same opinion. They'd think,
"hey,
> no problem. Sooner or later someone will come with a good library
proposal,
> and we'll look into it. At any rate, changes in the core language will be
> minimal if at all."

The interesting thing is, the last statement is not far away from truth.
As core language changes are essential to solve the issue, but that part is
not a big one, nor does it change stuff, just define some (in fact already
existing) behavior.

In the core a memory model must be defined. Then what else do we need?
Let me think one:
>>
C++ uses a *relaxed* memory model with thread-self-coherency. That means as
long as nothing else (especially no other thread) modifies any object usef
by a thread the behavior is exactly what is described in the current
standard.

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)

Access to an object of a non-atomic type is undefined if it was modified by
another thread AND that thread didnt't get past a store membar AND the
current thread didn't get past a load membar. (Otherwise the thread will see
the state as the other thread).
<<

Is there anything more essential in core?
Oh yes, there are some complex operations, and those shall be defined either
as 'thread safe' or mention they are not. Like creation of a local static.
maybe the new operator too.

volatile? I gave thought to volatile many times, with recurring 'it would
be cool with implicit membar semantics'. But then concluded it is not so.
Not at all. Just to have safe code you need far less membars than the
implicit solution would force. Especially if you have more than one volatile
around. It is way cleaner to put the membars (or the primitives with
implicit membar semantics, like mutex/lock) there, and just access plain
variables.

The rest really looks like a library issue.
And not an easy one. A set of primitives is obvious, but simple and wanted
stuff like interlocked operations (inc, dec, exchange, compare-exchange)
may not be available on some implementations as native. Sure it can be
provided with mutex but that would kinda defeat the original design goals on
using them.

Certainly those primitives must be defined to have certain membar semantics
implicitly.

After that we have to say something on the rest of the standard library, and
on the C library too, what is thread safe to call in the wild, what shall be
mutexed etc.

Paul

Sergey P. Derevyago

unread,
Aug 19, 2004, 11:49:14 AM8/19/04
to
"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

llewelly

unread,
Aug 19, 2004, 11:49:55 AM8/19/04
to
ne...@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?

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 12:53:58 PM8/19/04
to
"llewelly" <llewe...@xmission.dot.com> wrote in message
news:86acwr5...@Zorthluthik.local.bar...

> ne...@news.astraweb.com ("News Subsystem") writes:
> 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?

I know of none. If there's any that works, it works by mistake and future
minor releases of that compiler can break existing code.

Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 2:38:35 PM8/19/04
to
""Edward Diener"" <eldi...@earthlink.net> wrote in message
news:gtUUc.27242$nx2....@newsread2.news.atl.earthlink.net...

> "Andrei Alexandrescu (See Website for Email)" wrote:
>> Again, it's a core language issue, and emphatically so. Thinking that
>> MT can be handled by a library is a chymera.
>
> It's chimera. But why do you believe that ? Just saying so does not make
> it
> so unless you have some proof.

I took five months to coauthor a 5000-words article on the issue, and some
more time to author a 3000-words article on lock-free data structures. It's
not easy to give an executive summary, but I'll try (below).

> From what you say, it sounds like you believe
> that something in the C++ language itself makes it incapable of allowing a
> fail-safe threading library to be written. Yet OSs whose threading support
> is clearly done through just procedural function calls do support
> threading.

That's a fallacy. I *hope* most of the committee does not share this
dangerous fallacy. OSs that only offer threading support via calls of
functions (1) impose requirements of what assumptions and optimizations the
compiler can propagate across a function call (2) offer threading support
with lackluster performance.

> If you have arguments why effective threading can not be done at the
> library
> level in C++, you need to make them rather than just asserting that what
> you
> believe to be true is true.

Here's an attempt at an executive summary. For more details, I need to refer
you to Butenhof's book "Programming with POSIX(R) Threads" or (for a more
explicit treatment of how threads are in conflict with the C++ virtual
machine, and how C++ compiler optimizations and lock-free programs are in an
endless battle) Meyers/Alexandrescu, "C++ and the Perils of Double-Checked
Locking" in Doctor Dobb's Journal, Jul and Aug 2004, and to the bibliography
that the article mentions.

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.

If we only take a minute to reflect on that, we'll see what formidable core
language challenge we are looking at here. The reality summarized above
changes pretty much everything that a single-threaded programmer is used to
take for granted.

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.

This pretty much floors any attempt to write any MT code even remotely
correct. Consider a locked procedure call:

{
Lock lock(someMutex);
sharedObj->Transmogrify();
} // lock's destructor unlocks the mutex

If the lock's destructor doesn't use some magic to commit all of the memory
writes that sharedObj->Transmogrify() has done, we're in hot water.

Locks achieve that magic through a silent understanding with the compiler:
they make system calls that do the cache-flushing thingy and consider that
the compiler will not attempt to propagate any constant and reorder any
execution across such a call. For example, across such a call the compiler
won't assume anything about the variable a:

a = 5;
whatever_system_call();
if (a == 5) { ... } // a is not assumed to be 5
// load it from memory and test again

So basically the threading library dictates how the compiler must generate
code - how's that for the tail wagging the dog. (Oh, I remembered a joke
through the fog of my ADD... where did I hear it? "My dog has no snout."
"Hm, how does it smell?" "Terrible!") That way both processor and
compiler-introduced transformations and disabled. We're already on shaky
ground, but we're still standing.

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. 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).

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. Of course,
if you define a library that has you call assign(a, 5) instead of a = 5; et
cetera, you could claim, hey, we solved it entirely in a library manner
without changing the change. But (as the Romanian proverb says) you'd be
stealing your own hat: to generate efficient code, the compiler must
recognize those calls and generate code accordingly, which means, you still
changed the language, you just didn't change the syntax. That's fine if you
prefer the ugly syntax.

But the core language change has to be there. Java 1.5 has done it
(http://www-106.ibm.com/developerworks/java/library/j-jtp03304/) - and
because of that it now has lock-free data structures
(http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html).
And we not only refuse to look into changing the C++ core language, we don't
know Java has done it and why!


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 2:39:01 PM8/19/04
to
""News Subsystem"" <ne...@news.astraweb.com> wrote in message
news:2jd4algx2ppk$.dlg@trawna.com...

> 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. How, specifically,
> for those of us who are not experts, are they not handling threads
> properly? Is it simply an efficiency concern, or are there things that
> absolutely cannot be done without language support? (I haven't had a
> chance to get to your DDJ article yet. It's in the "to read" pile.)

I am sorry about being unclear, and thank you for asking.

There is no such thing as MT implemented as a library. What appears to be a
library is really a library/execution semantics combo. The library is
written making key assumptions about how the compiler generates code, in
particular the scope and aggressiveness of compiler optimizations. The
pthreads library has a "C binding" which specifies what requirements it
makes from its host C compiler. There is no C++ pthreads binding, which puts
in question the legality of C++ programs using pthreads. A C++ pthreads
binding would have a lot more restrictions to put on how the C++ compiler
lays out code.

So pthreads is a library only syntactically. In reality there's much more
going on: the compiler you compile on must be pthreads-compliant... and that
compliance is not in standard C - it's in POSIX Threads - and there's no
pthreads compliance even defined for C++ anywhere. We manage to compile and
run illegal C++ programs with pthreads in a stealthy, backhanded way, only
because C++ abstract machine is so close in semantics (but NOT identical) to
C's abstract machine. I think this is a woeful state of affairs.

>> In short, the language should be able to allow programmers to specify
>> that
>> certain variable types must be read and written to in the exact order of
>> the
>> reads and writes as the source code's sequence points dictate.
>
> 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?

Good question. The situation is indeed handled by mutexes. But again,
locking and unlocking makes calls to those functions that in turn make
assumptions about how the compiler generates code. Those assumptions ought
to be standardized, such that we can count on porting code from one MT
C++200x compiler to another MT C++200x compiler.

If lock-based programming is all we need to write MT programs, that would be
about it. We'd still want to add lock-based MT programming to the standards.
We'd need to specify some things about those function statics, exceptions,
etc. etc. and we're cool. That I believe is a reasonably hard task that
should be tackled anyway, but it's NOT the entire story.

Now other languages (which have done portable lock-based programming for a
while now and have gotten better and better at it) have access to
finer-grained multithreading support, and as such they can write portable
code that does things one order of magnitude faster than anything we can do
with locks. Is there where we want to stand? I guess not.

For C++ to keep a competitive edge, we need to make changes to the core
language. Those changes could be in the form of type modifiers (Java 1.5's
volatile) that convey to the compiler a need for hard sequencing of reads
and writes.


Andrei

Francis Glassborow

unread,
Aug 19, 2004, 2:39:56 PM8/19/04
to
In article <30381f67.04081...@posting.google.com>, Uwe
Schnitker <schnitkerAf...@sigma-c.com> writes

>A defect report "insufficient specification of volatile" would in all
>probability be rejected as NAD in the end, but you would at least
>"force" some discussion about the issue.

I think trying to use a DR would actually weaken the argument as WG21 is
now primarily in 'develop next release' mode. What would help would be a
paper that described exactly what core support would enable the
provision of an efficient (both in performance and ease of use) MT
support library. Bring such a proposal to the Evolution group at Redmond
and be willing to continue work on it afterwards and I think you will
find us open minded. Just saying 'someone ought to do the work to
provide this, unspecified, extension to the language will get nowhere.
We have enough work to do already without taking on someone else's.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Dietmar Kuehl

unread,
Aug 19, 2004, 2:40:05 PM8/19/04
to
jhy...@ieee.org (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.

My formulation was a little bit lax in that it might imply that true
multi-threading would have to be become available which was not my
intention. Instead, I entirely agree that doing nothing for certain
parts would be the right thing to do, e.g. for locking meachanisms.
It would probably be the wrong things for attempts of thread creation
which should produce an error as early as possible, probably at
compile time. However, these issues have to be addressed for any
proposal in this direction.

> 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."

Yes. The really interesting part is that this actually leads us into
optional features. Of course, any implementation can then choose to
support it or not to support it. There are pros and cons of this
approach. Other standards using optional components provide both
positive and negative examples of this approach.


--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

---

Dietmar Kuehl

unread,
Aug 19, 2004, 2:40:31 PM8/19/04
to
Andrei Alexandrescu 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?
>
> One reason is unawareness of competitive threat from other languages.

If the people investing into C++ ignore that thread, it is their choice.

> Another is that (from my own interactions with the MT community) many
> hardcore MT programmers aren't active in the standard C++ language community
> and vice versa. They are people who have hard problems, know how to solve
> them, understand they can't be solved in standard C++, and go on about doing
> their job instead of convincing others that they ought to be able to do
> their job easily and portably.

That is, they are not sufficiently interested in pushing the issue.

> So I think the "obvious reason" is that many standard C++ users and pundits
> think that threads can be handled properly by a library.

Actually, I doubt that many people in the C++ standardization commitee
believe that MT can be [entirely] handled by a library. It is just too
obvious that you e.g. need to provide support for exceptions in the
presence of multi-threading because multiple threads will throw
exceptions in parallel. I also think that those in the committee
realize that the compiler has to be restricted in moving operations
when MT-directives are involved. Neither can be handled by a pure
library approach. I guess there are probably more issues which need or
should, e.g. for performance reasons, be addressed.

On the other hand, I guess that the major portion of MT-support actually
will be in form of a library, similar to what pthreads is doing: the
compiler has to recognize that operations cannot be moved over certain
boundaries but the major part is still just a library.

> If
> enough people understand that, and also understand the competitive benefit
> that Java's threading amenities lends to that language, interest will be
> born.

Apparently there is nobody currently sufficiently interested to go
forward and create a proposal. At least, nobody has done it so far.



> > 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). However,
> > the committee will not start working on multi-threading: the work has to
> > be done by people who are interested in this area.
>

> I understand that. But that's also a "put up or shut up" attitude.

Yes. This is how standardization works: if you are interested in
something you have to invest in it if you want to make sure that
it happens (and even if you invest it is no guarantee that your
investment will be successful). You cannot rely on others doing the
work.

> 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 best the committee can do is to invite these people. Actually,
I think I have done that (whether I'm entitled to do so or not):
people who push the issue of multi-threading are definitely welcome
to participate - which, of course, includes creation of a proposal.

> 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?

Nobody is shooing them away. Actually, my recollection of the outcome
of the Boost.Threads presentation was clearly that people should go
forward with something like this. I'm actually quite sure that the
presentation was held in front of essentially the whole committee,
not just the library working group. Of course, how the effective
interface looks like, i.e. whether it is Boost.Threads does not really
matter to the people. However, Boost.Threads was at least something
on which people have worked and which was presented.

> > 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.
>
> I think discontinuing that work was a lucky turn of events :o).

You notice that you put yourself under quite some pressure, do you?
Essentially, I read this statement as a clear offer that you write
a proposal on how to integrate multi-threading into C++. Since the
next meeting is in Redmond, this would provide a good opportunity
for a presentation of your proposal (my understanding is that you
live in the Seattle area).

Peter Dimov

unread,
Aug 19, 2004, 2:40:53 PM8/19/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2ohmicF...@uni-berlin.de>...
>
> No, my query is NOT about standardizing a library. (In particular, now that
> we got to talk about Boost.threads, I don't like it at all. I'd actually go
> ahead and say, I actively dislike it. I think standardizing Boost.threads
> would be an order of magnitude a bigger gaffe than standardizing
> shared_ptr.)

In your opinion, what is wrong with Boost.Threads, and how would you
go about fixing it?

Loïc Joly

unread,
Aug 19, 2004, 2:41:01 PM8/19/04
to
Dietmar Kuehl wrote:

[...]

>
>>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.
>
>
> However, I would guess that the majority of systems, both in terms of
> operating system and number of machines, running C++ programs do not have
> 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.
>
>
> 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.

100% agreed. Thread creation and lock mechanism are totally diffent
issues in term of portability. One could also wonder wether lock issues
sould only be used for multithread, or also for multi-process. Thus some
notions of IPC might be usefull. I'm not sure wether they should be part
of the same proposal.

I'm not sure even that the model of thread implicit in this discussion
(explicit thread creation/destruction) is one size-fit all for all
application domain. For instance, on massively parallel computers, is
this the good metaphore?


[...]

--
Loïc

Steven E. Harris

unread,
Aug 19, 2004, 2:41:32 PM8/19/04
to
na...@animats.com (John Nagle) writes:

> 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.

Bite your tongue. Is ANSI Common Lisp¹ the settled dust? Surely macros
are one of Lisp's greatest strengths, not a cause for any decline in
popularity or "relevance."


Footnotes:
¹ http://www.lispworks.com/reference/HyperSpec/Front/Hilights.htm
http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+INCITS+226%2D1994+%28R1999%29

--
Steven E. Harris

David Abrahams

unread,
Aug 19, 2004, 2:42:52 PM8/19/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:

>>> Does the C++ standardization committee plan to address threads at
>>> all, or continue to ignore them?
>> I have no affiliation with the standardization commitee, but what
>> exactly do you want to be addressed? I disagree that MT is an issue
>> for the language standard.
>
> I am sorry, but your opinion is entirely wrong. This has been
> exceedingly shown by Doug Lea's, William Pugh, and many others'
> research on Java MT programming. I also hope that "C++ and The Perils
> of Double-Checked Locking" by Scott Meyers and myself (Doctor Dobb's
> Journal, July and August 2004) shows very clearly how MT hits at the
> core of language semantics and code generation.


>
> Unfortunately, I am afraid that some more influential (to the
> standardization process) people are of the same opinion. They'd think,
> "hey, no problem. Sooner or later someone will come with a good
> library proposal, and we'll look into it. At any rate, changes in the
> core language will be minimal if at all."

I do wish people -- and I don't only mean you -- would spend a whole
lot less time second-guessing what "influential (to the
standardization process) people" are thinking and more time making a
solid contribution to the process itself. We (those influential
because... ahem... we participate) are spread way too thinly.

When Dietmar says that nobody is "sufficiently interested" he's
technically correct, but it really doesn't give the whole picture.
I'm intensely interested in threading for the standard, but well,
what with trying to improve iterators, get move/forwarding semantics
in, making sure that concepts fit with the future, etc., etc., I have
my plate full. And frankly I don't have the expertise in threading
neccessary to propose anything with real conviction. I imagine the
same is true for most other committee members.

Predicting about what committee members will think of non-existent
proposals is a cop-out. Nobody's complacent or deluded into thinking
threading is a library-only problem. Work with the other interested
people to come up with solutions and build a consensus.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 3:01:53 PM8/19/04
to
""Balog Pal"" <pa...@lib.hu> wrote in message
news:4124...@andromeda.datanet.hu...

> ""Andrei Alexandrescu (See Website for Email)""
> <SeeWebsit...@moderncppdesign.com> wrote in message
>
>> I understand that. But that's also a "put up or shut up" attitude.
>
> IMHO it's more like asking the general to fly from flower to flower like
> a
> bee.

Not sure I understand. I think it's more like asking the body that should
most care about the C++ community and C++'s future, to care about the C++
community and C++'s future.

That's a great start, thanks for taking the time to write it down.

> Is there anything more essential in core?
> Oh yes, there are some complex operations, and those shall be defined
> either
> as 'thread safe' or mention they are not. Like creation of a local
> static.
> maybe the new operator too.

And exceptions.

> volatile? I gave thought to volatile many times, with recurring 'it would
> be cool with implicit membar semantics'. But then concluded it is not so.
> Not at all. Just to have safe code you need far less membars than the
> implicit solution would force. Especially if you have more than one
> volatile
> around. It is way cleaner to put the membars (or the primitives with
> implicit membar semantics, like mutex/lock) there, and just access plain
> variables.

I believe you are wrong here. You are basically advocating for dynamic,
unchecked semantics and ABP (Attention-Based Programming) and against
statically-checked, type-based semantics. MT programmers need all the
compiler help they could get, and a type modifier (or a set thereof) would
be golden.

Then, think of the boon for template programmers... :o)

> The rest really looks like a library issue.
> And not an easy one. A set of primitives is obvious, but simple and
> wanted
> stuff like interlocked operations (inc, dec, exchange, compare-exchange)
> may not be available on some implementations as native. Sure it can be
> provided with mutex but that would kinda defeat the original design goals
> on
> using them.

Atomic increment/decrement is not needed because it can be (and is in most
hardware) done via compare-and-swap (CAS) which has been shown is superior
(and fundamental for any serious MT programming). Most of today's processors
implement CAS, and those that don't have the equally powerful LL/SC pair of
primitives. CAS should be in the standard and guaranteed to execute
atomically.

Background. CAS is:

template <class T>
bool CAS(T* a, T e, T v) {
if (*a != e) return false;
*a = v;
return true;
}

T would be limited to a primitive type up to a certain size. CAS is a very
powerful primitive proven to allow implementation of any concurrent
structure without locks.


Andrei

Roshan Naik

unread,
Aug 19, 2004, 4:18:10 PM8/19/04
to

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

John Nagle

unread,
Aug 19, 2004, 5:19:27 PM8/19/04
to
Steven E. Harris wrote:
> na...@animats.com (John Nagle) writes:
>
>
>>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.
>
>
> Bite your tongue. Is ANSI Common Lisp¹ the settled dust? Surely macros
> 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

John Nagle

unread,
Aug 19, 2004, 5:19:38 PM8/19/04
to
Andrei Alexandrescu (See Website for Email) wrote:

> ""Balog Pal"" <pa...@lib.hu> wrote in message
> news:4124...@andromeda.datanet.hu...
>
>>""Andrei Alexandrescu (See Website for Email)""
>><SeeWebsit...@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

Wil Evers

unread,
Aug 19, 2004, 6:33:57 PM8/19/04
to
In article <2oig7mF...@uni-berlin.de>, Andrei Alexandrescu (See Website
for Email wrote:

> "Alexander Terekhov" <tere...@web.de> wrote in message
> news:4123BD01...@web.de...
>>
>> 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
>
> I am aware of those limitations. I believe advanced optimizations can
> overcome some of them. The funny thing is, even with Java 1.5 overly
> limiting volatile, one can write MT Java code that's fast and portable.

It's interesting to note that the articles Alexander is referring to suggest
a library-based, as opposed to language-based, alternative to Java's use of
the volatile keyword. 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. Volatile could certainly use some cleanup, but it may not be the
best way to express the semantics required by modern, lock-free algorithms.

> But volatile is not the only thing I worry about. CAS is another one.

And CAS could be provided as a standard library facility too. 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.

- Wil

--
Wil Evers, DOOSYS R&D, Utrecht, Holland
[Wil underscore Evers at doosys dot com]

David Abrahams

unread,
Aug 19, 2004, 6:34:17 PM8/19/04
to
dietma...@yahoo.com (Dietmar Kuehl) writes:

> Andrei Alexandrescu 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.
>
> Actually, I doubt that many people in the C++ standardization commitee
> believe that MT can be [entirely] handled by a library. It is just too
> obvious that you e.g. need to provide support for exceptions in the
> presence of multi-threading because multiple threads will throw
> exceptions in parallel.

And why does that neccessarily require much special support in the
language *specification*? There isn't any global state associated
with EH other than std::uncaught_exception.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 6:34:35 PM8/19/04
to
""Loďc Joly"" <loic.act...@wanadoo.fr> wrote in message
news:cg2fdb$p22$1...@news-reader4.wanadoo.fr...

>I'm not sure even that the model of thread implicit in this discussion
(explicit thread creation/destruction) is one size-fit all for all
application domain. For instance, on massively parallel computers, is
this the good metaphore?<

That's a good point. Parallel programming is distinct and uses different
paradigms, tools, and techniques than concurrent programming (our "MT" being
the latter). Loop transformation and explicitly lending operation for
parallelization is more of a concern to the former.

My ongoing crusade has more to do with concurrent programming than with
parallel programming. MT is much more widespread (oh by the way - it's very
likely you have an MT machine right in your pocket - your tissue phone!) and
is of primary urgency as far as standardization goes.


Andrei

Alexander Terekhov

unread,
Aug 19, 2004, 11:30:40 PM8/19/04
to

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.

Edward Diener

unread,
Aug 19, 2004, 11:30:59 PM8/19/04
to

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.

>
> If we only take a minute to reflect on that, we'll see what
> formidable core language challenge we are looking at here. The
> reality summarized above changes pretty much everything that a
> single-threaded programmer is used to take for granted.
>
> 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.

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. If
not, we are talking about random computing here. Somehow I find it very hard
to believe what you say is justified in reality. 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 ?

>
> This pretty much floors any attempt to write any MT code even remotely
> correct.

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.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 11:31:30 PM8/19/04
to
"Dietmar Kuehl" <dietma...@yahoo.com> wrote in message
news:5b15f8fd.04081...@posting.google.com...

> Andrei Alexandrescu 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?
>>
>> One reason is unawareness of competitive threat from other languages.
>
> If the people investing into C++ ignore that thread, it is their choice.

Or their myopia that will cost them later.

> Actually, I doubt that many people in the C++ standardization commitee
> believe that MT can be [entirely] handled by a library.

Hmmm... a couple of answers right in this thread suggest otherwise :o).

>> I think discontinuing that work was a lucky turn of events :o).
>
> You notice that you put yourself under quite some pressure, do you?
> Essentially, I read this statement as a clear offer that you write
> a proposal on how to integrate multi-threading into C++. Since the
> next meeting is in Redmond, this would provide a good opportunity
> for a presentation of your proposal (my understanding is that you
> live in the Seattle area).

Thanks for the invite (and to all others who've made it). My main research
focus is not C++. I am essentially writing this in zero time. That means,
I'd write a proposal in negative time. But it's still possible :o). This
morning I have ordered a few more MT books.

Delegation is good, management books and programming books say, so if anyone
would consider joining such an effort, post here and/or email me. Maybe
something can be started. My preferred role: naggerus majorus.


Andrei "I can't believe I'm doing this" Alexandrescu

Andrei Alexandrescu (See Website for Email)

unread,
Aug 19, 2004, 11:31:49 PM8/19/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:un00rq...@boost-consulting.com...

> When Dietmar says that nobody is "sufficiently interested" he's
> technically correct, but it really doesn't give the whole picture.
> I'm intensely interested in threading for the standard, but well,
> what with trying to improve iterators, get move/forwarding semantics
> in, making sure that concepts fit with the future, etc., etc., I have
> my plate full. And frankly I don't have the expertise in threading
> neccessary to propose anything with real conviction. I imagine the
> same is true for most other committee members.

I totally understand, and I believe that's a valid and reasonable point.

But let's think of the following. Imagine that someone brings to your
attention that MT is a very important issue as far as the future of C++ is
concerned. Imagine that you become convinced that MT is way more important
than all other things - like, one order of magnitude. Maybe then you'd
change priorities. If other people in the committee get convinced as well,
motivation will be there and action will come.

Compare with something that most agree is a gratuitous limitation, such as
template typedefs. They will be fixed because they are seen as an obvious
and sore problem. People are willing to dedicate time and energy to it.

> Predicting about what committee members will think of non-existent
> proposals is a cop-out. Nobody's complacent or deluded into thinking
> threading is a library-only problem. Work with the other interested
> people to come up with solutions and build a consensus.

Good. What I am trying with this thread is to bring information, create a
shared vision, and increase awareness, all of which I believe are lacking.
Gee I sound like a corporate poster :oD.


Andrei

David Abrahams

unread,
Aug 19, 2004, 11:35:35 PM8/19/04
to

===================================== MODERATOR'S COMMENT:
Before this discussion starts over again, all parties please review points made on the
c++-pthreads mailing list: <URL:http://www.codesourcery.com/archives/c++-pthreads/threads.html>. Thank you.


===================================== END OF MODERATOR'S COMMENT
bou...@dev.null (Wil Evers) writes:

> And CAS could be provided as a standard library facility too. 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.

Please, no.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 12:32:52 PM8/20/04
to
"Dietmar Kuehl" <dietma...@yahoo.com> wrote in message
news:5b15f8fd.04081...@posting.google.com...
> Yes. The really interesting part is that this actually leads us into
> optional features.

std::cout << "We have optional features already.\n";

Andrei

David Abrahams

unread,
Aug 20, 2004, 12:33:05 PM8/20/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:

>> 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). However,
>> the committee will not start working on multi-threading: the work has to
>> be done by people who are interested in this area.
>

> I understand that. But that's also a "put up or shut up" attitude.

That seems like a good attitude to have in some ways. What's the
alternative if those on the committee don't have the time or
expertise?

> 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.

Suggestions? I have no clue how to attract anyone to the committee.
Inviting people to show up and telling them it's been a great
experience for me doesn't seem to make much difference. If you don't
have the time or energy to be the committee's MT expert, maybe you
could be the guy that proposes and implements whatever attracts the MT
expert.

> The damage about shooing away (for good) PL language design experts
> has been done; see the Tom Penello episode.

Must've been before my time. Details?

> The consequences of that attidude have been very costly. Why repeat
> that damage with MT people?

What evidence have you got that the committee is shooing any MT
experts away?

>> 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.
>

> I think discontinuing that work was a lucky turn of events :o).

Snarky, but not very illuminating.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 12:33:15 PM8/20/04
to
"Wil Evers" <bou...@dev.null> wrote in message
news:cg33nf$k48$1...@news.cistron.nl...

> It's interesting to note that the articles Alexander is referring to
> suggest
> a library-based, as opposed to language-based, alternative to Java's use
> of
> the volatile keyword.

Oui.

> 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.

I personally consider such a setup ugly, but workable. Note, however, that
that's not really a "pure" library approach. I'd much rather have some
expressive type modifiers that allow me to devise in a typesafe manner
memory barrier operations.

> And CAS could be provided as a standard library facility too. 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.

I believe that experience has shown that asynchronous thread cancellation is
not the way to go; instead, the application architecture needs to provide
synchronous means that help application to terminate threads nicely. For
example, Lock::Lock(Mutex&) and perhaps other synchronization primitives
(not sure about CAS, it's supposed to be cheap...) could throw an exception
if another thread requires termination of the current thread. That would
allow synchronous and graceful termination.


Andrei

Hyman Rosen

unread,
Aug 20, 2004, 12:33:34 PM8/20/04
to
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.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 12:34:25 PM8/20/04
to
""Edward Diener"" <eldi...@earthlink.net> wrote in message
news:KUaVc.3193$2L3....@newsread3.news.atl.earthlink.net...

> "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.
>
> 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.

I'm very happy that my outrageous statement caught your attention :o).

The best way to explain this would be like this: say you're thinking, let's
prove Andrei's statement above wrong. So you fire your favorite editor and
compiler, and... and do what? Let's see some ways in which you can analyze
the values of a and b:

1. You use a step-by-step debugger such as gdb or MSVC's integrated one. In
debug mode (no optimizations) you might see indeed that a is changed first
and b second. But maybe you remember that in the past you've debugged
optimized code and on portions it made no sense to you. So you think you
want to do it programatically.

2. Change the code to this:

b = 6;
printf("%d %d ", a, b);
a = 5;
printf("%d %d", a, b);

and you see that indeed "0 6 5 6" is printed. But then I come and say,

that's as if you wrote:

a = 5;
b = 6;

printf("%d %d ", 0, 6);
printf("%d %d", 5, 6);

(that's a common optimization called "constant propagation" coupled with
some harmless reordering.)

3. You analyze the assembler code generated. You say: Aha! Here's the code
that does things in the same order as the source code. But then I come with
some documentation such as
http://www.microsoft.com/whdc/driver/kernel/MPmem-barrier.mspx (really
that's the first hit when I googled for "processor write reordering") and
show you that, even if one processor performs writes in some order, they
might be performed in main memory (and seen by another processor) in a
different order.

Equally well, I could come with some other expressions that are assigned to
a and b, and have the compiler reorder writes to better exploit its ALUs,
and show you in the generated code that a is assigned to before b.

4. You use a different thread to watch the contents of a and b. But then I
come and tell you, the Standard doesn't say anything about threads, so this
method of watching a C++ program's behavior is illegal.

5. So now finally we turn to the Standard in quest for an answer to the
question, what is really observable behavior? How can we tell that a C++
program does what we coded it to do?

Searching for "observable behavior" in the C++ standard takes as to 1.9/1:

<<
The semantic descriptions in this International Standard define a
parameterized nondeterministic abstract machine. This International Standard
places no requirement on the structure of conforming implementations. In
particular, they need not copy or emulate the structure of the abstract
machine. Rather, conforming implementations are required to emulate (only)
the observable behavior of the abstract machine as explained below.5)
>>

So the semantics don't prescribe that execution should follow the steps
taken by the source code, as long as the observable behavior is respected.
Interesting. (The few following paragrapsh in 1.9 are also pretty
interesting. The footnote on that page also defines the "as-if" rule.)

Clearly we need to figure out what that "observable behavior" means. 1.9/6
states it peremptorily:

<<
The observable behavior of the abstract machine is its sequence of reads and
writes to volatile data and calls to library I/O functions.
>>

Hah! So as long as these two things are respected, the program can do pretty
much anything it wants! That's super interesting.

Note that if you qualify every single variable in your program with
volatile, then you achieve exactly what you want: the variables will be read
and written in the same exact sequence as that in which they were written.
But there are two problems you now have:

1. The C++ abstract machine is single-threaded, and all of the above doesn't
say that "the sequence of reads and writes to volatile variables" must be
the exact same in various threads, because threads "don't exist". So still
different threads can see different sequences.

2. Your program will be slower - perhaps by an order of magnitude or more,
depending on the processor.

3. If you think of only volatile-qualifying the data that participates in
thread synchronization, you're out of luck: the relative ordering of
volatile and non-volatile data, which is essential, is not specified. (Java
1.5 specifies, actually overspecifies, it.)

[That reminds me of the following joke. A king visits a poor village with
much fuss and camarilla and all. And he asks the priest: why didn't the
church's bells toll when I arrived in this vilalge? And the priest answers:
"For several reasons, Your Highness. One of them is that our church doesn't
have bells."]

So really 2 and 3 are minor because 1 shatters any hope.

> 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.

There is a third option. MT programming is not dead. It works because any MT
system defines (more or less rigurously) a set of semantics that changes
C++'s underspecified observable behavior rules as mandated by the standard.
Also the MT system defines primitives that enforce (for a given compiler and
processor architecture) the order of execution of reads and writes - in
other words, it disables in key points the reorderings that both the
compiler and the hardware do all over the place.

Scott and my article discuss the issues above in all of their subtleties.

I hope this convinces everybody that changes to the language semantics are
utterly necessary to get threads working in Standard C++. Any questions are
welcome.


Andrei

Sergey P. Derevyago

unread,
Aug 20, 2004, 12:35:36 PM8/20/04
to
"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

Francis Glassborow

unread,
Aug 20, 2004, 12:35:58 PM8/20/04
to
In article <2oktlmF...@uni-berlin.de>, "Andrei Alexandrescu (See
Website for Email)" <SeeWebsit...@moderncppdesign.com> writes

>But let's think of the following. Imagine that someone brings to your
>attention that MT is a very important issue as far as the future of C++ is
>concerned. Imagine that you become convinced that MT is way more important
>than all other things - like, one order of magnitude.

Even given all those things any individual has to assess there ability
to contribute. For example, I think that move semantics is way more
important than any of my proposals but I do not have the technical
expertise to do anything about it so I will stick with working on the
things that I think I just might be able to follow through on.

There are numerous other things that I think have a desirable impact but
even if I have the expertise to handle them I certainly lack the time.
Just one example, in the context of modern multi-processor and/or
multi-core processors I think an ability to designate functions as pure
(no side-effects, no out parameters and only calls to pure functions)
would offer extra opportunities for safe optimisation (in much the same
way that const provides opportunities for optimising data handling).
However I have enough on my plate already.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---

Peter Dimov

unread,
Aug 20, 2004, 12:37:14 PM8/20/04
to
bou...@dev.null (Wil Evers) wrote in message news:<cg33nf$k48$1...@news.cistron.nl>...

> In article <2oig7mF...@uni-berlin.de>, Andrei Alexandrescu (See Website
> for Email wrote:
>
> > "Alexander Terekhov" <tere...@web.de> wrote in message
> > news:4123BD01...@web.de...
> >>
> >> 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
> >
> > I am aware of those limitations. I believe advanced optimizations can
> > overcome some of them. The funny thing is, even with Java 1.5 overly
> > limiting volatile, one can write MT Java code that's fast and portable.
>
> It's interesting to note that the articles Alexander is referring to suggest
> a library-based, as opposed to language-based, alternative to Java's use of
> the volatile keyword. Granted, it would not be possible to implement
> things like atomic<int> in portable, strictly conforming standard C++.

[...]

The problem with Alexander's atomic<T> is that you don't know which T
to use. 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.

> > But volatile is not the only thing I worry about. CAS is another one.
>
> And CAS could be provided as a standard library facility too.

Same problem as above. You don't know which types are CAS-able.

> 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.

Thread cancelation is an ordinary exception with no special
properties. It only gets nasty if you try to make it nasty. For some
reason many people believe that it ought to be made nasty.

Balog Pal

unread,
Aug 20, 2004, 12:37:34 PM8/20/04
to
""Edward Diener"" <eldi...@earthlink.net> wrote in message
news:KUaVc.3193$2L3....@newsread3.news.atl.earthlink.net...

> > 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.

Or may be seen as one or both access missing, or any other way.

> 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.

C++ does not say anything about memory. What is defined a _behavior_ of
objects and operations. having those assignments you later will find those
values on reading them. If you write expressions that tepend on another the
order mandated by seq points will be important to know which values you get.
But there is no way for a just-std program to know what really is in some
"memory" or even that such thing exist.

Access to nonvolatiles is not even sonsidered as "observable behavior" for
anything, so lisense is granted for the implementation to mess with ordering
as long as the result (observed from the only defined thread) is ensured.

> > 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.
>
> 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.

Id you want to deal with memory, you must drag in the dox on the OS, the
memory system, the procesor and so forth. There you find description on what
is supposed to happen as the processor executes machine instructions. And
what measures must be taken to have defined behavior having more than one
processor on the same memory, and other intersting situations. (you can't
talk about that in general as the systems differ pretty much.)

> If not, we are talking about random computing here.

It would be random if no one read those manuals, just expected "everything
will just work". :)

> Somehow I find it very hard
> to believe what you say is justified in reality. 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 ?

It very well may be the case, or it may not. Many architectures just
define a 'memoty system', and nothing is told about a cache. Cahe is a
transparent part of the memory, its controller must ensure the memory works
just as without cache, only at different speed.

The proc-memory bus may be defined to order asked transactions with
interleave, or it may just say simultaneous access to same location is
forbidden. Or it may cause mismatched result, a trap, etc. (try google for
'word tearing')

Whoever wants to have a working system must obey all the rules. A basic
strategy is to have critical sections in the code making access to shared
objects exclusive. And the sync primitives that implement the entry/exit of
the section use special instructions designed to this very purpose. What
may include inctructions to make the whole system syncronised, etc.

> > This pretty much floors any attempt to write any MT code even remotely
> > correct.
>
> 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.

It isn't dead just we sweat blood and sometimes juggle a tower of glasses on
our nose. And quite many times we must rely on stuff that is not really
documented, just we see it works for the case, and we expect the
implemetation actually observed some rules we think were essential to be
able to create any working stuff.

> 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.

Explain what more specifically? From the std/C++ point of view the
picture is pretty simple, no behavior is defined for a situation having
multiple threads. So you can't expect anything really. And if you restrict
to a single thread you dodge the whole set of issues.

Paul

David Abrahams

unread,
Aug 20, 2004, 3:06:25 PM8/20/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:

> Delegation is good, management books and programming books say, so
> if anyone would consider joining such an effort, post here and/or
> email me. Maybe something can be started. My preferred role:
> naggerus majorus.

Mine too. If I can get someone else to take up the real work on my
other standardization concerns, I could play naggerus majorus there,
and then maybe do all the real MT work for you ;-)

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

Hyman Rosen

unread,
Aug 20, 2004, 4:42:53 PM8/20/04
to
David Abrahams wrote:
> Please, no.

ATC (Asynchronous Transfer of Control) is widely regarded as
a language design mistake in Ada.

Thorsten Ottosen

unread,
Aug 20, 2004, 4:43:30 PM8/20/04
to
"Wil Evers" <bou...@dev.null> wrote in message news:cg33nf$k48$1...@news.cistron.nl...

| On the other hand, the standard C++ library already provides facilities that


| cannot be implemented in conforming C++,

what are you referring to?

br

Thorsten

David Abrahams

unread,
Aug 20, 2004, 4:45:00 PM8/20/04
to
na...@animats.com (John Nagle) writes:

> 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".

Does that come from just one or two people? Just wondering. There
are several hundred on the committee. Often a few loudmouths are
seen as representing committee opinion as a whole.

> 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.

Seems to me that you can handle at least that much at the library
level, even if you have to use asm { ... }. Remember, nobody expects
low-level threading primitives to have portable implementations.

> The committee also has driven away the safety, quality,
> and reliability people.

I'm still around, though I admit that after the struggle of getting
exception safety in, I haven't taken up anything quite so ambitious.

> 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.

That's a (ahem, be polite, Dave) mischaracterization. We've tightened
up quite a few holes since the standard was approved, as you can see
by looking at the issues lists and the technical corrigendum. Sure,
those arguments get made -- every issue gets aired and considered --
but that doesn't mean they're given weight over those of reliability.
You might be disappointed by the aggressiveness with which that goal
is pursued, but don't forget that we're only just now leaving the
post-standardization period where only conservative changes are
possible.

> We pay for this every day, as buffer overflow stories make the
> headlines in the mainstream press.

What's the solution? I think
<http://www.animats.com/papers/languages/> is interesting, not quite
right for C++, and not detailed/complete enough to be a workable
standards proposal. It has potential, but I can see why it might have
generated objections. The objections might mean "the committee is
unreceptive and will never listen," but maybe they mean "some people
are intensely interested but there are important requirements that
your proposal doesn't accomodate." It's your choice, I guess.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 4:45:43 PM8/20/04
to
""Sergey P. Derevyago"" <non-ex...@iobox.com> wrote in message
news:4125BE8B...@iobox.com...

> "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.

It does, except in very few points. No?

Most of the time, you'd allow true parallel execution. When those truly
parallel folks need to synchronize with each other... that's when the fun
starts :o).

> 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:

[excellent quote from Butenhof snipped]

Of course. In that post, Butenhof gets into design issues and makes the
point that locking has its place as does lock-free.

By the way, the poster to whom Butenhof replies seems to confuse lock-free
with wait-free. (Lock-free: at least one thread makes progress at each step.
Wait-free: any thread makes progress in bounded time.) The literature is not
very helpful, frequently confusing the two terms or collapsing them
together.

> 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?

Friend templates, forwarding constructors, or template typedefs won't be
strategic reasons to choose a language. Portable MT support can be.


Andrei

Steve Clamage

unread,
Aug 20, 2004, 6:50:40 PM8/20/04
to
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...@sun.com

Alexander Terekhov

unread,
Aug 20, 2004, 6:50:56 PM8/20/04
to

Loïc Joly wrote:
[...]
> If you give us an link to an article that explains that, instead of just
> vague allegations that Java does it better, then poeple will be able to
> read this article and there might be enough people to understand that.

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf
(Final Draft, August 19, 2004, 10:11am)

Eat carefully. The cake is hot. ;-)

regards,
alexander.

David Abrahams

unread,
Aug 20, 2004, 7:01:28 PM8/20/04
to
na...@animats.com (John Nagle) writes:

---

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 7:01:48 PM8/20/04
to
"Dietmar Kuehl" <dietma...@yahoo.com> wrote in message
news:5b15f8fd.04081...@posting.google.com...
> som...@nowhere.com (Roshan Naik) 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).
>>
>> I would imagine that this requirement (if true) would be the biggest
>> impediment to ever having MT in the standard.
>
> 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.

Jim Hyslop, others, and myself already mentioned a reasonable behavior:
thread creation function always fails, and the thread-relating keywords are
ignored. Also, it would be nice if thread support could be detected
statically such that code can issue an error if needed.

That's the easy part.

I suggest we leave the bicycle shed alone and move on discussing systems
that *do* support threads. That's the hard part.


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 7:02:22 PM8/20/04
to
""Sergey P. Derevyago"" <non-ex...@iobox.com> wrote in message
news:412472B2...@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.

So the binding needs to come from the C++ standardization committee.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 7:04:54 PM8/20/04
to
""Loďc Joly"" <loic.act...@wanadoo.fr> wrote in message
news:cg1tnd$h5v$1...@news-reader1.wanadoo.fr...

>If you give us an link to an article that explains that, instead of just
vague allegations that Java does it better, then poeple will be able to
read this article and there might be enough people to understand that.<

About Java's new memory model:

http://www-106.ibm.com/developerworks/java/library/j-jtp03304/

About C++-related problems, there need to be 90 days after publication
(coming soon) such that Scott and I make our article (Doctor Dobb's Journal,
Jul/Aug 2004) available online.

> 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?

>What is "PL language" ?<

Sorry! It means "Programming Language language" :o). I saw that blunder
after posting. Also I forgot one "n" in Pennello.

David Abrahams

unread,
Aug 20, 2004, 7:05:44 PM8/20/04
to
jhy...@ieee.org (Jim Hyslop) writes:

> 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."

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.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

Peter Dimov

unread,
Aug 20, 2004, 7:27:20 PM8/20/04
to
SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2okpccF...@uni-berlin.de>...

[ about atomic<int> ]

> I personally consider such a setup ugly, but workable. Note, however, that
> that's not really a "pure" library approach. I'd much rather have some
> expressive type modifiers that allow me to devise in a typesafe manner
> memory barrier operations.

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.)

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
new value is zero.

I'm also not sure what do you mean by 'typesafe' in this context.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 8:54:07 PM8/20/04
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:4124C5ED...@web.de...

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf
(Final Draft, August 19, 2004, 10:11am)

Eat carefully. The cake is hot. ;-)

----------------

We need at least that amount of work and that level of precision (and
hopefully less restrictive semantics... we can always learn from their
mistakes) to wed threads with C++.

Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 20, 2004, 8:54:24 PM8/20/04
to
"Peter Dimov" <pdi...@gmail.com> wrote in message
news:abefd130.04082...@posting.google.com...

> SeeWebsit...@moderncppdesign.com ("Andrei Alexandrescu (See Website
> for Email)") wrote in message news:<2okpccF...@uni-berlin.de>...
>
> [ about atomic<int> ]
>
>> I personally consider such a setup ugly, but workable. Note, however,
>> that
>> that's not really a "pure" library approach. I'd much rather have some
>> expressive type modifiers that allow me to devise in a typesafe manner
>> memory barrier operations.
>
> 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.)

I am not that sure. If the standard has sufficiently granular barriers that
allow the programmer to convey to the compiler what's needed, the compiler
"understands" enough to implement the needed operation.

If, on the other hand, standard barriers are coarse, then indeed it becomes
harder for the optimizer to figure out what's needed.

> 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
> new value is zero.

I don't understand how shared_ptr gets away by incrementing a shared counter
without absolutely any barrier. Could you explain? Any operation on shared
memory needs a memory barrier, and the reference count is shared memory.

> I'm also not sure what do you mean by 'typesafe' in this context.

I mean, if we make concurrent behavior part of the type of a variable, we
can have the compiler guard it and maybe even enforce correct MT behavior
(as per Cormac Flanagan's work).


Andrei

Roshan Naik

unread,
Aug 20, 2004, 9:35:16 PM8/20/04
to

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

Hyman Rosen

unread,
Aug 21, 2004, 12:37:58 PM8/21/04
to
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.

Hyman Rosen

unread,
Aug 21, 2004, 12:38:24 PM8/21/04
to
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.

Hyman Rosen

unread,
Aug 21, 2004, 12:40:20 PM8/21/04
to
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.

Loïc Joly

unread,
Aug 21, 2004, 12:40:32 PM8/21/04
to
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.
>
>
> 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.

I have string class that uses COW. I want this class to be thread safe
(in the way defined by Herb Sutter in the September 2004 CUJ). I also
want to use it in monothread environment. And I don't want to use #if.
In this case, making those synchronisations no-op is the perfect choice.

--
Loïc

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 12:41:37 PM8/21/04
to
"Roshan Naik" <som...@nowhere.com> wrote in message
news:4124FF31...@nowhere.com...
> 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.

I think that's an excellent summary.

Both compile-time and run-time means can be easily provided to detect
whether a system supports MT. That's really *not* the issue.

I suggest we close here the discussion on what to do on systems that can't
do threads. That's easy. Leave that bicycle shed wherever. Let's focus now
on how to support threads, lest this thread will become a prime example of
how a valid cause gets drowned in discussing its most irrelevant detail ad
infinitum.

And please don't reply saying, "it's not as irrelevant as you think...."
etc. etc. It's not totally irrelevant, but there's way bigger fish to fry.
:o)


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 12:41:55 PM8/21/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:usmaio...@boost-consulting.com...
> dietma...@yahoo.com (Dietmar Kuehl) writes:
>
>> Andrei Alexandrescu 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.
>>
>> Actually, I doubt that many people in the C++ standardization commitee
>> believe that MT can be [entirely] handled by a library. It is just too
>> obvious that you e.g. need to provide support for exceptions in the
>> presence of multi-threading because multiple threads will throw
>> exceptions in parallel.
>
> And why does that neccessarily require much special support in the
> language *specification*? There isn't any global state associated
> with EH other than std::uncaught_exception.

So, excellent - let's count std::uncaught_exception in :o). And while we're
at it, maybe we make it more useful!

Dietmar Kuehl

unread,
Aug 21, 2004, 12:42:36 PM8/21/04
to
David Abrahams wrote:
> And why does that neccessarily require much special support in the
> language *specification*? There isn't any global state associated
> with EH other than std::uncaught_exception.

My understanding is that one approach to implement exception handling
involves an area of memory set aside to contain an exception being
throw which may be necessary e.g. to throw a 'bad_alloc' exception:
memory from the heap is likely to be unavailable. However, when the
heap is exhausted multiple threads may throw exceptions due to this
problem at once such that it would be insufficient to have just one
such memory or it would need to be protected against use from
multiple threads. I think the specification should be specific
about allowing multiple exceptions being thrown simultaneously.
Of course, whether they are propagated simultaneously or just one
propagates at a time while the others are blocked is another issue.

Another issue with respect to exception handling is the effect of
failing to catch an exception from a thread different than the
"main thread": an option would be the termination of the
corresponding thread rather than termination of the program. I
would expect that the thread is terminated, the current
specification unconditionally says that the program terminates.

.. and, of course, 'std::uncaught_exception()' may get thread
specific semantics. I didn't claim that there are much things
affected by multi-threading. However, it is sufficient if there
is minor detail like the result of 'std::uncaught_exception()'
in the various threads if one thread is throwing. The semantics
are obvious (only in the throwing thread it should yield 'true',
in all other threads it should yield 'false') but they have to
be spelled out.
--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 12:43:25 PM8/21/04
to
"Francis Glassborow" <fra...@robinton.demon.co.uk> wrote in message
news:gNgHd7MI...@robinton.demon.co.uk...
> I think trying to use a DR would actually weaken the argument as WG21 is
> now primarily in 'develop next release' mode. What would help would be a
> paper that described exactly what core support would enable the provision
> of an efficient (both in performance and ease of use) MT support library.
> Bring such a proposal to the Evolution group at Redmond and be willing to
> continue work on it afterwards and I think you will find us open minded.
> Just saying 'someone ought to do the work to provide this, unspecified,
> extension to the language will get nowhere. We have enough work to do
> already without taking on someone else's.

Thanks Francis for your lucid answers.

My hope is that this thread will increase awareness beyond a threshold
level. That level would be like, "YIKES! We are focusing on the wrong
problems, and there's this huge problem and competitive threat."

The Romanian proverb (what's with all these proverbs as of late) says:
"While the country's burning, the old lady takes her time to comb her hair."

One known fact in psychology is that when we have a lot of things to do, we
focus on what we already know how to do. (Prime example - answering email
when there are a lot of things on your plate...) For figuring out a
committee's workings, multiply that trend's acuity by the number of members.

I love your forwarding constructors. Sorry for picking on them :o). But they
are way less important in the big picture than MT support.


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 12:43:45 PM8/21/04
to
"John Nagle" <na...@animats.com> wrote in message
news:8x8Vc.6155$656....@newssvr27.news.prodigy.com...
> 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.

This will allow experts to write high-performance libraries of containers.
Templates are just as hard, and they're used the same way.

Dietmar Kuehl

unread,
Aug 21, 2004, 12:45:07 PM8/21/04
to
Roshan Naik wrote:

>
>
> 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.

However, it is not an error to use a mutex lock in a non-multi-threaded
program. It is perfectly OK and the mutex lock is actually allowed to
do nothing. Thus, a mutex lock in a single threaded program should not
cause any problem. Things become different when it comes down to stuff
like thread creation: this should indeed fail, best at compile time.

> 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.

Except that no runtime error will occur if I used a mutex lock which is
turned into a no-op. Since I'm in the business of library implementation
I know pretty well that I'm not going to create separate data structures
for all combinations of system support. For example, why should I tear
out the mutex locks from my data structures if they can equally well
turned into no-ops.

> 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.

I didn't claim such thing at all. All I said is that it is crucial of
allowing e.g. the thread synchronization directives in all cases, even
if the platform does not support multi-threading. These directives
will have no effect unless MT is supported.

> And as I said it makes no sense running MT programs on non MT
> systems.

If you imply that mutex locks cannot be turned into no-ops on non-MT
systems you wrong, irrespective of what you said. Whether it is useful
to have them in the code for non-MT systems may be a different issue
and apparently we disagree on the answer.

> So thats a worthless goal for the standard to try to make your MT
> programs run or even compile on non MT systems.

It is indeed worthless to have all MT directives on non-MT systems.
I didn't imply that I want all MT directives. However, the
synchronization directives I want, especially as they can be turned
quite easily into no-ops. ...and I want this to be done in the
standard for the same reason e.g. threading is desired in the
standard: there should be a standard approach to this kind of things,
even on non-MT systems.


--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

---

Roshan Naik

unread,
Aug 21, 2004, 12:45:38 PM8/21/04
to

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.
>

There are two parts to that ignoring versus compile time errors.
First the core language features for MT , and second Standard Library
portions.

Lets say the threads and locks related abstractions go into the header
<thread>
When users tries to #include <thread> in order to instantate threads and fire
off multiple
threads on a non-MT system, the compiler should preferrable to indicate a
clear
*compiler error* at compile time rather than at run time. This should be a
trivial to do
using compile time asserts.... on just not shipping a <thread> on that system
:-)

But in the case of core language features (like if they decided on new
keywords or
type modifiers or things of that nature) those obviously should be ignored at
compile time
instead of issuing errors.

-Roshan

David B. Held

unread,
Aug 21, 2004, 12:45:51 PM8/21/04
to
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

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 12:46:24 PM8/21/04
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:412533CA...@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?

> 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>. ;-)

Yah, and the hell will freeze over soon :o).


Andrei

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 1:00:34 PM8/21/04
to
"Peter Dimov" <pdi...@gmail.com> wrote in message
news:abefd130.04082...@posting.google.com...
> bou...@dev.null (Wil Evers) wrote in message
> news:<cg33nf$k48$1...@news.cistron.nl>...
>> > But volatile is not the only thing I worry about. CAS is another one.
>>
>> And CAS could be provided as a standard library facility too.
>
> 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".

Certain apps can require double-word CAS or single-word CAS - same as some
apps require 32-bits integers or 64-bits integers.

Andrei Alexandrescu (See Website for Email)

unread,
Aug 21, 2004, 1:04:35 PM8/21/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:uhdqzq...@boost-consulting.com...

>> 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."
>
> 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.

That's the spirit! I love stuff simple and rigurous as that. One thread is
implicitly created and started by the system.

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.


Andrei

Falk Tannhäuser

unread,
Aug 21, 2004, 1:04:45 PM8/21/04
to
Dietmar Kuehl wrote:

> som...@nowhere.com (Roshan Naik) 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).
>>

>>I would imagine that this requirement (if true) would be the biggest
>>impediment to ever having MT in the standard.
>
>

> 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 freestanding
(§ 1.4/7). So I suppose there could be 2 more kinds added (hosted with MT
and freestanding with MT).

Falk Tannhäuser

Roshan Naik

unread,
Aug 21, 2004, 1:05:05 PM8/21/04
to
>
> 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.

Roshan Naik

unread,
Aug 21, 2004, 1:08:03 PM8/21/04
to

"Andrei Alexandrescu (See Website for Email)" wrote:

> ""Sergey P. Derevyago"" <non-ex...@iobox.com> wrote in message
> news:412472B2...@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

James Kuyper

unread,
Aug 21, 2004, 1:09:25 PM8/21/04
to
nes...@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<4125eeb5$0$214$1472...@news.sunsite.dk>...
> "Wil Evers" <bou...@dev.null> wrote in message news:cg33nf$k48$1...@news.cistron.nl...
>
> | On the other hand, the standard C++ library already provides facilities that
> | cannot be implemented in conforming C++,
>
> what are you referring to?


Most of the examples I can think of are functions defined in the part of the C++
standard library that was inherited from C. These include fopen(), fclose(),
remove(), rename(), tmpfile(), tmpname(), fgetc(), fputc(), <csignal>, <csetjmp>,
abort(), exit(), clock(), time(), and the offsetof() macro.

It is loading more messages.
0 new messages