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


Author: pdimov@gmail.com (Peter Dimov)
Date: Thu, 16 Sep 2004 15:19:29 GMT
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<usm9ksy6r.fsf@boost-consulting.com>...
> llewelly.at@xmission.dot.com (llewelly) writes:
>
> > If the library function wasn't specified to report failures, and yet
> >     it polled for cancellation, I'd use a stronger word than
> >     'mess'. :-)
>
> That is the primary argument I have with the proposed POSIX binding
> for C++ requires C library functions to start throwing cancellation.

It's the POSIX C binding that requires that.

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 13 Sep 2004 19:37:37 GMT
Raw View
llewelly.at@xmission.dot.com (llewelly) writes:

> ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
> [snip]
>> By implicit cancellation polling I mean polling for and reporting of
>> cancellation by library calls not directly related to it, which causes
>> all this mess.  I have no problem with provision for *explicit*
>> polling, e.g. pthread_testcancel.
> [snip]
>
> Suppose a future C++ w/threads defines all standard library functions
>     so as to not poll for cancellation, except for
>     pthread_testcancel().
>
> Then imagine some third-party library implementor calls
>     pthread_testcancel() in a library function.
>
> As far as the user of the library is concerned, that's implicit
>     cancellation. So it's a mess that can't be wholly avoided;
> it can only be minimized. (I do think that it should be minimized.)

What mess?  That seems fine to me as long as the library function
is specified to report other kinds of failures anyway.

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

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 14 Sep 2004 15:19:28 GMT
Raw View
llewelly.at@xmission.dot.com (llewelly) writes:

> dave@boost-consulting.com (David Abrahams) writes:
>
>> llewelly.at@xmission.dot.com (llewelly) writes:
>>
>>> ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
>>> [snip]
>>>> By implicit cancellation polling I mean polling for and reporting of
>>>> cancellation by library calls not directly related to it, which causes
>>>> all this mess.  I have no problem with provision for *explicit*
>>>> polling, e.g. pthread_testcancel.
>>> [snip]
>>>
>>> Suppose a future C++ w/threads defines all standard library functions
>>>     so as to not poll for cancellation, except for
>>>     pthread_testcancel().
>>>
>>> Then imagine some third-party library implementor calls
>>>     pthread_testcancel() in a library function.
>>>
>>> As far as the user of the library is concerned, that's implicit
>>>     cancellation. So it's a mess that can't be wholly avoided;
>>> it can only be minimized. (I do think that it should be minimized.)
>>
>> What mess?
>
> *shrug*
>
> Transfering an error from one reporting mechanism (say, exceptions)
>     to another (say, to a global record like errno) introduces
>     complication at the point where the error must be transferred,
>     and more complication where the error is handled. It's
>     traditional to refer to complication as 'a mess'.

Okay, but this is easily bottlenecked through a function that tests
for cancellation and throws if neccessary.  Sorry, I must just be
missing your point completely.

>> That seems fine to me as long as the library function
>> is specified to report other kinds of failures anyway.
>
> If the library function wasn't specified to report failures, and yet
>     it polled for cancellation, I'd use a stronger word than
>     'mess'. :-)

That is the primary argument I have with the proposed POSIX binding
for C++ requires C library functions to start throwing cancellation.

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

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





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Sat, 11 Sep 2004 02:05:06 GMT
Raw View
David Abrahams wrote:
> ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
>
>>>> The response to cancellation should be for the cancelled thread to
>>>> exit cleanly.  In the process of cleaning up resources it may well
>>>> need to make calls to system functions that poll for cancellation
>>>> requests, e.g. close().  If those functions re-report the
>>>> cancellation request, cleanup will fail.
>>>
>>> If you're going to call functions that might throw during unwinding,
>>> you always need to take special measures to prevent the exception from
>>> propagating.  It's no different even without the issue of thread
>>> cancellation.  I see no good reason to make special accomodations for
>>> cancellation exceptions.
>>
>> This is nothing to do with exception propagation and everything to do
>> with ensuring a clean exit.  Here's an example to illustrate why I
>> think re-reporting is such a bad idea:
<snip>
>>     try
>>     {
>>         watchdog_thread.start();
>>         bool result = copy_file_and_log(argv[1], argv[2], log);
>>         watchdog_thread.cancel();
>>         return result ? EXIT_SUCCESS : EXIT_FAILURE;
>>     }
>>     catch (cancellation &)
>>     {
>           disable_cancellation();

Well that fixes things for this program but I'm not convinced it's a
general solution.  What if log is defined inside the try block, so it
is destroyed and flushed before the cancellation exception is caught
and cancellation disabled?  Maybe I misunderstand how you want re-
reporting to work.

>>         log << "Copy took too long and was cancelled\n";
>>         return EXIT_FAILURE;
>>     }
>> }
>>
>> Suppose the copy takes a long time and the watchdog thread cancels
>> the main thread.  The cancellation exception is caught in main,
>> which returns the appropriate error code.  Now log's destructor
>> runs, but when it attempts to flush the log, cancellation is
>> re-reported and this fails.  Why should it fail?
>
> What is "this?"  cancellation, log flushing, or what?
> Why shouldn't it fail?

Log flushing fails.  There's no reason why it can't be flushed
so it's perverse to make it fail.

<snip>
>>>> Explicit calls in the destructor would be phenomenally expensive, so
>>>> alternately the library could check the call stack to see whether a
>>>> destructor is in there before reporting cancellation (and if it is,
>>>> disabling cancellation and retrying the system call).  The way it's
>>>> delivered doesn't make a difference.
>>>
>>> That's an enormous amount of complication to impose upon the language
>>> to just provide an incomplete solution for one kind of problem.
>>
>> Exactly!
>
> ??

Let me put the pieces together for you.  Suppose we allow implicit
polling for cancellation.  Then we can choose between specifying one
of the following:

1. Cancellation-polling functions throw a cancellation exception (or
   return ECANCELLED which will probably be translated into such an
   exception) if a cancellation request has been made on the thread,
   regardless of whether the exception can be caught.  This seems to
   me to make it impossible to write robust code, but maybe I'm wrong.

2. Cancellation is disabled when running destructors and functions
   whose exception specification does not include cancellation.  This
   can be implemented by:

   a) Generating code to disable cancellation at the beginning of
      these functions and enable it at the end of them (assume disable
      calls are counted so they can nest).  This is clearly too
      expensive in terms of code size and running time.

   b) In the polling functions, checking whether the exception can be
      handled before reporting it.  As you say, "an enormous amount of
      complication".

I already stated my conclusion:

>>>> I seriously wonder whether implicit cancellation polling is worth-
>>>> while.
>>>
>>> ??
>>
>> By implicit cancellation polling I mean polling for and reporting of
>> cancellation by library calls not directly related to it, which causes
>> all this mess.  I have no problem with provision for *explicit*
>> polling, e.g. pthread_testcancel.
>
> Oh.  Yeah, I don't have a strong opinion on that one.

It looks like we may have been talking at cross-purposes, then.

--
Ben Hutchings
In a hierarchy, every employee tends to rise to his level of incompetence.

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Sat, 11 Sep 2004 03:54:22 GMT
Raw View
ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:

> David Abrahams wrote:
>> ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
>>
>>>>> The response to cancellation should be for the cancelled thread to
>>>>> exit cleanly.  In the process of cleaning up resources it may well
>>>>> need to make calls to system functions that poll for cancellation
>>>>> requests, e.g. close().  If those functions re-report the
>>>>> cancellation request, cleanup will fail.
>>>>
>>>> If you're going to call functions that might throw during unwinding,
>>>> you always need to take special measures to prevent the exception from
>>>> propagating.  It's no different even without the issue of thread
>>>> cancellation.  I see no good reason to make special accomodations for
>>>> cancellation exceptions.
>>>
>>> This is nothing to do with exception propagation and everything to do
>>> with ensuring a clean exit.  Here's an example to illustrate why I
>>> think re-reporting is such a bad idea:
> <snip>
>>>     try
>>>     {
>>>         watchdog_thread.start();
>>>         bool result = copy_file_and_log(argv[1], argv[2], log);
>>>         watchdog_thread.cancel();
>>>         return result ? EXIT_SUCCESS : EXIT_FAILURE;
>>>     }
>>>     catch (cancellation &)
>>>     {
>>           disable_cancellation();
>
> Well that fixes things for this program but I'm not convinced it's a
> general solution.  What if log is defined inside the try block, so it
> is destroyed and flushed before the cancellation exception is caught
> and cancellation disabled?  Maybe I misunderstand how you want re-
> reporting to work.

If it flushes in its destructor, and flushing could throw an
exception, the destructor should take steps to deal with it.  Either
disable_cancellation or catch the exception.  You can also
disable_cancellation just before exiting the try block, which will
prevent flushing from failing due to cancellation (but not
neccessarily due to other reasons).

>>>         log << "Copy took too long and was cancelled\n";
>>>         return EXIT_FAILURE;
>>>     }
>>> }
>>>
>>> Suppose the copy takes a long time and the watchdog thread cancels
>>> the main thread.  The cancellation exception is caught in main,
>>> which returns the appropriate error code.  Now log's destructor
>>> runs, but when it attempts to flush the log, cancellation is
>>> re-reported and this fails.  Why should it fail?
>>
>> What is "this?"  cancellation, log flushing, or what?
>> Why shouldn't it fail?
>
> Log flushing fails.  There's no reason why it can't be flushed
> so it's perverse to make it fail.

It could fail anyway if the disk was full.

> <snip>
>>>>> Explicit calls in the destructor would be phenomenally expensive, so
>>>>> alternately the library could check the call stack to see whether a
>>>>> destructor is in there before reporting cancellation (and if it is,
>>>>> disabling cancellation and retrying the system call).  The way it's
>>>>> delivered doesn't make a difference.
>>>>
>>>> That's an enormous amount of complication to impose upon the language
>>>> to just provide an incomplete solution for one kind of problem.
>>>
>>> Exactly!
>>
>> ??
>
> Let me put the pieces together for you.  Suppose we allow implicit
> polling for cancellation.  Then we can choose between specifying one
> of the following:
>
> 1. Cancellation-polling functions throw a cancellation exception (or
>    return ECANCELLED which will probably be translated into such an
>    exception) if a cancellation request has been made on the thread,
>    regardless of whether the exception can be caught.  This seems to
>    me to make it impossible to write robust code, but maybe I'm
>    wrong.

I think you're wrong.  It's the same situation as with functions that
can report out-of-memory.  They don't check to see whether the
exception can be caught before throwing.  That doesn't prevent the
writing of code that's robust in the face of memory exhaustion.

> 2. Cancellation is disabled when running destructors and functions
>    whose exception specification does not include cancellation.  This
>    can be implemented by:
>
>    a) Generating code to disable cancellation at the beginning of
>       these functions and enable it at the end of them (assume disable
>       calls are counted so they can nest).  This is clearly too
>       expensive in terms of code size and running time.
>
>    b) In the polling functions, checking whether the exception can be
>       handled before reporting it.  As you say, "an enormous amount of
>       complication".

And if it can't be handled you throw, or you don't throw?  Isn't "not
handling" the exception exactly what you need in order to allow the
thread to terminate?  It seems to me that throwing might be just what
the doctor ordered.  Having to put in a catch(cancellation) block just
to get the thread to terminate seems a little perverse to me.

>>> By implicit cancellation polling I mean polling for and reporting of
>>> cancellation by library calls not directly related to it, which causes
>>> all this mess.  I have no problem with provision for *explicit*
>>> polling, e.g. pthread_testcancel.
>>
>> Oh.  Yeah, I don't have a strong opinion on that one.
>
> It looks like we may have been talking at cross-purposes, then.

I don't have an opinion about that one, either ;-)

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

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 9 Sep 2004 08:02:09 GMT
Raw View
pdimov@gmail.com (Peter Dimov) writes:

> David Abrahams <dave@boost-consulting.com> wrote in message news:<ur7pduai5.fsf@boost-consulting.com>...
>> pdimov@gmail.com (Peter Dimov) writes:
>>
>> > Interesting. I didn't realize that you are talking about C++ code
>> > that is correct in a single-threaded environment.
>>
>> Yes.  And that should be correct in a sane MT environment.
>
> This requirement isn't that obvious as it might appear.

Sorry, what I meant was, "I'm talking about code that is correct in a
single-threaded environment, and would be correct in a sane MT
environment."

> The library needs to be tested in the new environment. Just
> expecting that it "should work" is wrong in practice, although what
> you propose is undeniably theoretically sound.

I'm not sure I agree.  There are some components that you can deduce
are correct in a sane MT environment.  std::vector is one example.
That std::allocator is threadsafe is part of my definition of "sane MT
environment."

>> > My point was, essentially, that this code is broken in any
>> > existing MT environment that supports cancelation.
>>
>> Depends what you mean by "supports cancellation," I guess.
>
> Well, I am not familiar with non-POSIX cancelation models, but I'm
> willing to learn.

I'm not deeply familiar with POSIX, but was under the impression that
C++ bindings w.r.t. thread cancellation were not set in stone yet.
Wrong?

>> > Your point is that this can be avoided in the future C++ MT
>> > environment.
>>
>> I'm not sure that was my point.
>
> Did I misunderstand again? You were saying that if nothrow functions
> stay nothrow and report cancelation via an error code (ECANCELED),
> this would not violate the implied exception safety guarantees in the
> calling C++ code, and hence, this code should stay correct. No?

Yes, provided that it was in other ways thread-friendly (e.g. no
implicit data sharing).

> This is true, of course, but there is a cost/benefit tradeoff.
> ECANCELED is less convenient than an exception,

It depends how (in)convenient it is to make the exception-based code
correct, doesn't it?

> does not reflect existing POSIX practice, and an exception doesn't
> "break existing code" in the usual sense, i.e. on a recompile.

That makes it worse, no?  I think I'd rather have the compilation
error.

> It only breaks code on porting, where breakage isn't that
> unexpected.

Designing tests to root out that breakage would be a nightmare, so
expectedness doesn't really help, it seems to me.

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

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 9 Sep 2004 08:02:42 GMT
Raw View
ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:

> David Abrahams wrote:
>> Alexander Terekhov <terekhov@web.de> writes:
>>
>>> David Abrahams wrote:
>>>
>>> [... 'ECANCELED' ...]
>>>
>>>> The C++ code, if correct in a non-threading environment, has to be
>>>> able to deal with that.
>>>
>>> How?
>>>
>>> You know that 'stickiness' won't work; cancel delivery shall
>>> disable cancellation.
>>
>> I don't see why that should be the case.
>
> The response to cancellation should be for the cancelled thread to
> exit cleanly.  In the process of cleaning up resources it may well
> need to make calls to system functions that poll for cancellation
> requests, e.g. close().  If those functions re-report the
> cancellation request, cleanup will fail.

If you're going to call functions that might throw during unwinding,
you always need to take special measures to prevent the exception from
propagating.  It's no different even without the issue of thread
cancellation.  I see no good reason to make special accomodations for
cancellation exceptions.

>>> Even completely ignoring the issue of cancel on unwinding path... at
>>> best, each 'correct' C++ library would 'translate' it to some
>>> library specific nonstandard exception.
>>
>> Yeah; it might.  So?
>>
>>> I think that it's quite clear that even with ECANCELED you'd have to
>>> modify your C/C++ library code and make it 'cancel aware/safe'.
>>
>> Not to me, yet.
>
> Cancellation should never be delivered to cleanup code.

Just like every other exception.

> So somehow it has to be disabled in every destructor.

No, you just deal with it the same way you deal with other
possibly-throwing functions in destructors.

If you only care about destructors, you *can* have the cancellation
mechanism can check uncaught_exception; there's no need for 2-phase
EH... but it *still* doesn't solve anything completely.  Destructors
aren't the whole story; you'd also want to suppress cancellation in
catch blocks.

> Explicit calls in the destructor would be phenomenally expensive, so
> alternately the library could check the call stack to see whether a
> destructor is in there before reporting cancellation (and if it is,
> disabling cancellation and retrying the system call).  The way it's
> delivered doesn't make a difference.

That's an enormous amount of complication to impose upon the language
to just provide an incomplete solution for one kind of problem.

> I seriously wonder whether implicit cancellation polling is worth-
> while.

??

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

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





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Thu, 9 Sep 2004 08:02:25 GMT
Raw View
Alexander Terekhov wrote:
> Ben Hutchings wrote:
> [...]
>> Cancellation should never be delivered to cleanup code.
>
> Never say never. ;-)
>
>>                                                         So somehow it
>> has to be disabled in every destructor.  Explicit calls in the
>> destructor would be phenomenally expensive, so alternately the library
>> could check the call stack to see whether a destructor is in there
>
> The 'library' shall check whether a matching handler is in there. ES,
> no_cancel {} and no_throw {} shall simply act as a 'fence' for the
> search phase.
<snip>

Please distinguish between "shall" and "should".  You know that this
is not actually possible in some existing exception implementations,
and the addition of two keywords plus two-phase exception handling to
the standard language for such a little gain is unlikely.  (Much as I
appreciate the value of two-phase EH when it comes to debugging!)

--
Ben Hutchings
We get into the habit of living before acquiring the habit of thinking.
                                                              - Albert Camus

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





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Thu, 9 Sep 2004 21:59:31 GMT
Raw View
David Abrahams wrote:
> ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:
>
>> David Abrahams wrote:
>>> Alexander Terekhov <terekhov@web.de> writes:
>>>
>>>> David Abrahams wrote:
>>>>
>>>> [... 'ECANCELED' ...]
>>>>
>>>>> The C++ code, if correct in a non-threading environment, has to be
>>>>> able to deal with that.
>>>>
>>>> How?
>>>>
>>>> You know that 'stickiness' won't work; cancel delivery shall
>>>> disable cancellation.
>>>
>>> I don't see why that should be the case.
>>
>> The response to cancellation should be for the cancelled thread to
>> exit cleanly.  In the process of cleaning up resources it may well
>> need to make calls to system functions that poll for cancellation
>> requests, e.g. close().  If those functions re-report the
>> cancellation request, cleanup will fail.
>
> If you're going to call functions that might throw during unwinding,
> you always need to take special measures to prevent the exception from
> propagating.  It's no different even without the issue of thread
> cancellation.  I see no good reason to make special accomodations for
> cancellation exceptions.

This is nothing to do with exception propagation and everything to do
with ensuring a clean exit.  Here's an example to illustrate why I
think re-reporting is such a bad idea:

// Assume necessary headers included.

// Assume cancellation is delivered as an exception, not an error
// code, though my point holds either way.

bool copy_file(const char * in_name, const char * out_name)
{
    std::ifstream in(in_name);
    std::ofstream out(out_name);
    std::string line;
    while (std::getline(in, line))
        out << line;
    return bool(in) && bool(out);
}

bool copy_file_and_log(const char * in_name, const char * out_name,
                       std::ostream & log)
{
    log << "Attempting copy of " << in_name << " to " << out_name << "\n";
    bool result = copy_file(in_name, out_name);
    log << "Copy " << (result ? "failed" : "completed") << "\n";
    return result;
}

// Cancels the specified thread after the timeout
void watchdog(int timeout, thread_id thread);

int main(int argc, char ** argv)
{
    if (argc != 3)
    {
        std::cerr << "Wrong number of arguments\n";
        return EXIT_FAILURE;
    }

    std::ofstream log("log", std::ios::app);
    thread watchdog_thread(std::bind(watchdog, 10, current_thread_id()));

    try
    {
        watchdog_thread.start();
        bool result = copy_file_and_log(argv[1], argv[2], log);
        watchdog_thread.cancel();
        return result ? EXIT_SUCCESS : EXIT_FAILURE;
    }
    catch (cancellation &)
    {
        log << "Copy took too long and was cancelled\n";
        return EXIT_FAILURE;
    }
}

Suppose the copy takes a long time and the watchdog thread cancels the
main thread.  The cancellation exception is caught in main, which
returns the appropriate error code.  Now log's destructor runs, but
when it attempts to flush the log, cancellation is re-reported and
this fails.  Why should it fail?

>>>> Even completely ignoring the issue of cancel on unwinding path... at
>>>> best, each 'correct' C++ library would 'translate' it to some
>>>> library specific nonstandard exception.
>>>
>>> Yeah; it might.  So?
>>>
>>>> I think that it's quite clear that even with ECANCELED you'd have to
>>>> modify your C/C++ library code and make it 'cancel aware/safe'.
>>>
>>> Not to me, yet.
>>
>> Cancellation should never be delivered to cleanup code.
>
> Just like every other exception.

You're missing the point.  I'm saying that not only should a
cancellation exception not *escape* cleanup code, but it should never
be delivered to it, because this will make it impossible to write
robust cleanup code.

<snip>
>> Explicit calls in the destructor would be phenomenally expensive, so
>> alternately the library could check the call stack to see whether a
>> destructor is in there before reporting cancellation (and if it is,
>> disabling cancellation and retrying the system call).  The way it's
>> delivered doesn't make a difference.
>
> That's an enormous amount of complication to impose upon the language
> to just provide an incomplete solution for one kind of problem.

Exactly!

>> I seriously wonder whether implicit cancellation polling is worth-
>> while.
>
> ??

By implicit cancellation polling I mean polling for and reporting of
cancellation by library calls not directly related to it, which causes
all this mess.  I have no problem with provision for *explicit*
polling, e.g. pthread_testcancel.

--
Ben Hutchings
It is easier to write an incorrect program than to understand a correct one.

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 10 Sep 2004 17:09:50 GMT
Raw View
ben-public-nospam@decadentplace.org.uk (Ben Hutchings) writes:

>>> The response to cancellation should be for the cancelled thread to
>>> exit cleanly.  In the process of cleaning up resources it may well
>>> need to make calls to system functions that poll for cancellation
>>> requests, e.g. close().  If those functions re-report the
>>> cancellation request, cleanup will fail.
>>
>> If you're going to call functions that might throw during unwinding,
>> you always need to take special measures to prevent the exception from
>> propagating.  It's no different even without the issue of thread
>> cancellation.  I see no good reason to make special accomodations for
>> cancellation exceptions.
>
> This is nothing to do with exception propagation and everything to do
> with ensuring a clean exit.  Here's an example to illustrate why I
> think re-reporting is such a bad idea:
>
> // Assume necessary headers included.
>
> // Assume cancellation is delivered as an exception, not an error
> // code, though my point holds either way.
>
> bool copy_file(const char * in_name, const char * out_name)
> {
>     std::ifstream in(in_name);
>     std::ofstream out(out_name);
>     std::string line;
>     while (std::getline(in, line))
>         out << line;
>     return bool(in) && bool(out);
> }
>
> bool copy_file_and_log(const char * in_name, const char * out_name,
>                        std::ostream & log)
> {
>     log << "Attempting copy of " << in_name << " to " << out_name << "\n";
>     bool result = copy_file(in_name, out_name);
>     log << "Copy " << (result ? "failed" : "completed") << "\n";
>     return result;
> }
>
> // Cancels the specified thread after the timeout
> void watchdog(int timeout, thread_id thread);
>
> int main(int argc, char ** argv)
> {
>     if (argc != 3)
>     {
>         std::cerr << "Wrong number of arguments\n";
>         return EXIT_FAILURE;
>     }
>
>     std::ofstream log("log", std::ios::app);
>     thread watchdog_thread(std::bind(watchdog, 10, current_thread_id()));
>
>     try
>     {
>         watchdog_thread.start();
>         bool result = copy_file_and_log(argv[1], argv[2], log);
>         watchdog_thread.cancel();
>         return result ? EXIT_SUCCESS : EXIT_FAILURE;
>     }
>     catch (cancellation &)
>     {
          disable_cancellation();
>         log << "Copy took too long and was cancelled\n";
>         return EXIT_FAILURE;
>     }
> }
>
> Suppose the copy takes a long time and the watchdog thread cancels
> the main thread.  The cancellation exception is caught in main,
> which returns the appropriate error code.  Now log's destructor
> runs, but when it attempts to flush the log, cancellation is
> re-reported and this fails.  Why should it fail?

What is "this?"  cancellation, log flushing, or what?
Why shouldn't it fail?

>>>>> I think that it's quite clear that even with ECANCELED you'd have to
>>>>> modify your C/C++ library code and make it 'cancel aware/safe'.
>>>>
>>>> Not to me, yet.
>>>
>>> Cancellation should never be delivered to cleanup code.
>>
>> Just like every other exception.
>
> You're missing the point.  I'm saying that not only should a
> cancellation exception not *escape* cleanup code, but it should never
> be delivered to it, because this will make it impossible to write
> robust cleanup code.

That's why you're allowed to disable cancellation.  Cancellations are
different from anything else that might throw an exception in that the
condition is entirely, and correctly, suppressible in code.  You can
say "don't throw any cancellations" without compromising the integrity
of your program.  You can't do that with out-of-memory, end-of-file,
or most other exceptions.  That's the only excuse I can see for
giving cancellations special status w.r.t. checking whether unwinding
is in progress.  But I'm not convinced it's a good enough excuse.

> <snip>
>>> Explicit calls in the destructor would be phenomenally expensive, so
>>> alternately the library could check the call stack to see whether a
>>> destructor is in there before reporting cancellation (and if it is,
>>> disabling cancellation and retrying the system call).  The way it's
>>> delivered doesn't make a difference.
>>
>> That's an enormous amount of complication to impose upon the language
>> to just provide an incomplete solution for one kind of problem.
>
> Exactly!

??

>>> I seriously wonder whether implicit cancellation polling is worth-
>>> while.
>>
>> ??
>
> By implicit cancellation polling I mean polling for and reporting of
> cancellation by library calls not directly related to it, which causes
> all this mess.  I have no problem with provision for *explicit*
> polling, e.g. pthread_testcancel.

Oh.  Yeah, I don't have a strong opinion on that one.

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

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Fri, 3 Sep 2004 00:49:31 GMT
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<uacwa9c9j.fsf@boost-consulting.com>...
> pdimov@gmail.com (Peter Dimov) writes:
>
> > dave@boost-consulting.com (David Abrahams) wrote in message news:<uy8jvla0m.fsf@boost-consulting.com>...
> >> terekhov@web.de (Alexander Terekhov) writes:
> >>
> >> > David Abrahams wrote:
> >> > [...]
> >> >> I realize you're obsessed with 2-phase EH. I even think it's cool.
> >> >> But it doesn't solve any problems here.
> >> >
> >> > Sure it does. throw() ES (less restrictive stuff with the same
> >> > effect aside for a moment) would "turn off" cancellation. No
> >> > cancel, no problem. Oder?
> >>
> >> What problem are you solving?  If you can add a throw() ES, you can
> >> also add
> >>
> >>      cancellation_disabler guard;
> >>
> >> to the function implementation.  You don't need 2-phase ES for that.
> >
> > Convenience. The other part of Alexander's evil scheme to take over
> > C++ exception handling (*) is implicit throw() on every destructor.
>
> That only adds convenience for destructors.  There are other nothrow
> regions that won't automatically be helped.  My point is that although
> it would certainly be nicer to have 2-phase EH, it doesn't *solve* any
> problems, at least not completely.

Partial solutions that at least allow me to get the job done can be
good enough. Especially compared with waiting for full solutions that
never materialize.

The nice thing about 2-phase EH + throw() queries are that they are a
general feature that is not limited to cancelation. With one throw()
you can disable not only cancelation, but whatever else comes up in
the future. And by adding a throw() wherever needed, existing C++ code
can take advantage of EH queries without explicit modifications.

I know that you knew that already. ;-)

> >> Obviously you're not concerned with the same things I am.  A C++
> >> library with no shared data, that can throw, and that currently uses
> >> the 'C' library, could be perfectly cancellation-safe as long as the
> >> 'C' library doesn't start throwing cancellation exceptions from
> >> otherwise-nonthrowing functions.  I don't want to declare that C++
> >> library broken in a MT environment.
> >
> > I'm not sure how that can be. A nothrow region is typically supposed
> > to never fail, i.e. always reach the end, or bad things tend to
> > happen. If it can fail due to the thread being canceled and not due to
> > an unexpected exception being thrown, it seems to me that those bad
> > things will still happen.
>
> That is exactly my point.  That's why I don't want previously
> nonthrowing 'C' library functions to start throwing when used from
> C++.

But you are fine with these same "nonthrowing functions" stopping dead
(possibly invoking some pthread cleanup handlers, although I don't see
how your blissfully-thread-unaware C++ code will contain them). Which
is what they do today when a thread is canceled. "Oder"?

> Many C++ libraries call 'C' library functions in nothrow regions
> under the assumption that they're not going to throw.

They also typically assume that these functions will return.

> If we allow
> those functions to start throwing in a MT environment, the C++ library
> will be broken in that environment.  The only alternative to modifying
> the C++ library's source will be to wrap uses of the C++ library in
> cancellation-disablers.

Your C++ library is already broken in threaded environments that
support cancelation. Nobody can survive a TerminateThread, which is
what cancelation looks like to C++ code that can't see it (because it
is not a C++ exception).

> > Whether the cancelation is an "in-band" or an "out-of-band"
> > exception
>
> What do you mean?

An "out of band" exception is something that interrupts your code and
unwinds the stack in a manner that you can't see or interact with.
Examples are cancelation and longjmp.

> > it still unwinds the stack and generally acts the same as a C++
> > exception w.r.t. bad things, with the exception (sorry) of not
> > cleaning up half of the resources in the latter case.
>
> Not if it never gets thrown.

In other words, you advocate that C++ shall not support thread
cancelation in any way, shape or form. Either that, or I'm
misunderstanding what you're saying.

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





Author: Stanley Friesen <sarima@friesen.net>
Date: Fri, 3 Sep 2004 17:32:32 GMT
Raw View
pdimov@gmail.com (Peter Dimov) wrote:
>
>Therefore, the target thread should enable cancelation when it is
>ready to deal with a cancelation request, and disable it when it is
>not. This can be made automatic based on some "is it ready" heuristic
>(which better be right) but that's a separate question.

The problem with this is the Windows problem of unkillable processes
that require rebooting to get rid of.  There MUST be some way to
override this, or there will be threads that hang inside the "not ready"
state and cannot be killed.

In Unix there is the regular KILL signal, that can be handled by the
receiving process, and there is an uncatchable one that absolutely
terminates any process. This is one approach that at least reduces the
frequency of unkillable tasks.
--
The peace of God be with you.

Stanley Friesen

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





Author: David Abrahams <dave@boost-consulting.com>
Date: Fri, 3 Sep 2004 22:47:31 GMT
Raw View
pdimov@gmail.com (Peter Dimov) writes:

>> >
>> > I'm not sure how that can be. A nothrow region is typically supposed
>> > to never fail, i.e. always reach the end, or bad things tend to
>> > happen. If it can fail due to the thread being canceled and not due to
>> > an unexpected exception being thrown, it seems to me that those bad
>> > things will still happen.
>>
>> That is exactly my point.  That's why I don't want previously
>> nonthrowing 'C' library functions to start throwing when used from
>> C++.
>
> But you are fine with these same "nonthrowing functions" stopping
> dead (possibly invoking some pthread cleanup handlers, although I
> don't see how your blissfully-thread-unaware C++ code will contain
> them). Which is what they do today when a thread is
> canceled. "Oder"?

Odor?

If they stop dead they have to do it in roughly the same way they
would do it due to some other failure condition that can arise --
i.e., they have to leave invariants intact and return some error code.
The C++ code, if correct in a non-threading environment, has to be
able to deal with that.  So, yeah, I've got no problem with that.  Not
sure about the cleanup handlers part.

>> Many C++ libraries call 'C' library functions in nothrow regions
>> under the assumption that they're not going to throw.
>
> They also typically assume that these functions will return.

Exactly.  ?? Odor?

>> If we allow those functions to start throwing in a MT environment,
>> the C++ library will be broken in that environment.  The only
>> alternative to modifying the C++ library's source will be to wrap
>> uses of the C++ library in cancellation-disablers.
>
> Your C++ library is already broken in threaded environments that
> support cancelation. Nobody can survive a TerminateThread, which is
> what cancelation looks like to C++ code that can't see it (because it
> is not a C++ exception).

I don't know what TerminateThread is, but even Butenhof will tell you
that there are no safe cancellations other than those that can be
subverted.  Cancellations are a *request*.  They don't terminate or
unwind you summarily.

>> > Whether the cancelation is an "in-band" or an "out-of-band"
>> > exception
>>
>> What do you mean?
>
> An "out of band" exception is something that interrupts your code and
> unwinds the stack in a manner that you can't see or interact with.
> Examples are cancelation and longjmp.

C++ cancellation can never be allowed to do that.

>> > it still unwinds the stack and generally acts the same as a C++
>> > exception w.r.t. bad things, with the exception (sorry) of not
>> > cleaning up half of the resources in the latter case.
>>
>> Not if it never gets thrown.
>
> In other words, you advocate that C++ shall not support thread
> cancelation in any way, shape or form. Either that, or I'm
> misunderstanding what you're saying.

You're misunderstanding.

Cancellation exceptions shall be normal C++ exceptions.  Ultimately
they are initiated by polling for a pending cancellation request.
They can be thrown from std:: C++ functions that are already allowed
to throw.  Cancellation error codes can be returned from standard 'C'
library functions that are already allowed to return error codes.

Simple.  There are a few subtleties w.r.t. whether and how the
cancellation request is "sticky".  I suggest you read the c++-pthreads
discussion that Alexander has been referring to which goes into more
detail; if you already have, I'm surprised that you're
misunderstanding my position so severely.

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

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





Author: Stanley Friesen <sarima@friesen.net>
Date: Sat, 4 Sep 2004 22:56:29 GMT
Raw View
David Abrahams <dave@boost-consulting.com> wrote:

>pdimov@gmail.com (Peter Dimov) writes:
>> But you are fine with these same "nonthrowing functions" stopping
>> dead (possibly invoking some pthread cleanup handlers, although I
>> don't see how your blissfully-thread-unaware C++ code will contain
>> them). Which is what they do today when a thread is
>> canceled. "Oder"?
>
>Odor?
>
>If they stop dead they have to do it in roughly the same way they
>would do it due to some other failure condition that can arise --
>i.e., they have to leave invariants intact and return some error code.
>The C++ code, if correct in a non-threading environment, has to be
>able to deal with that.  So, yeah, I've got no problem with that.  Not
>sure about the cleanup handlers part.

I think if you look back in the context of this discussion, the C
functions in question use a non-C++ "exception" to handle terminate
requests, so the net result from the point of view of the C++ function
that called them is that they never actually return - the C function
apparently just terminates the thread.
>
>>> Many C++ libraries call 'C' library functions in nothrow regions
>>> under the assumption that they're not going to throw.
>>
>> They also typically assume that these functions will return.
>
>Exactly.  ?? Odor?

And the currently existing C functions *don't* return under these
conditions.
>>
>> Your C++ library is already broken in threaded environments that
>> support cancelation. Nobody can survive a TerminateThread, which is
>> what cancelation looks like to C++ code that can't see it (because it
>> is not a C++ exception).
>
>I don't know what TerminateThread is, but even Butenhof will tell you
>that there are no safe cancellations other than those that can be
>subverted.  Cancellations are a *request*.  They don't terminate or
>unwind you summarily.

Admitted, but in the presence of buggy programs, they are a occasionally
necessity to avoid a permanently blocked task.
>>
>> An "out of band" exception is something that interrupts your code and
>> unwinds the stack in a manner that you can't see or interact with.
>> Examples are cancelation and longjmp.
>
>C++ cancellation can never be allowed to do that.
>
One of the issues being discussed is how the C++ mechanism interacts
with the *already* *existing* mechanism in some C libraries, that
*don't* give the C++ a chance to interact with it.
>
>> In other words, you advocate that C++ shall not support thread
>> cancelation in any way, shape or form. Either that, or I'm
>> misunderstanding what you're saying.
>
>You're misunderstanding.
>
>Cancellation exceptions shall be normal C++ exceptions.  Ultimately
>they are initiated by polling for a pending cancellation request.
>They can be thrown from std:: C++ functions that are already allowed
>to throw.  Cancellation error codes can be returned from standard 'C'
>library functions that are already allowed to return error codes.

Then what about those C library functions that don't return when a
cancellation request is received while they are running?

--
The peace of God be with you.

Stanley Friesen

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Sat, 4 Sep 2004 22:57:21 GMT
Raw View
David Abrahams <dave@boost-consulting.com> wrote in message news:<usm9zm2ik.fsf@boost-consulting.com>...
> pdimov@gmail.com (Peter Dimov) writes:
>
> >> > I'm not sure how that can be. A nothrow region is typically supposed
> >> > to never fail, i.e. always reach the end, or bad things tend to
> >> > happen. If it can fail due to the thread being canceled and not due to
> >> > an unexpected exception being thrown, it seems to me that those bad
> >> > things will still happen.
> >>
> >> That is exactly my point.  That's why I don't want previously
> >> nonthrowing 'C' library functions to start throwing when used from
> >> C++.
> >
> > But you are fine with these same "nonthrowing functions" stopping
> > dead (possibly invoking some pthread cleanup handlers, although I
> > don't see how your blissfully-thread-unaware C++ code will contain
> > them). Which is what they do today when a thread is
> > canceled. "Oder"?
>
> Odor?
>
> If they stop dead they have to do it in roughly the same way they
> would do it due to some other failure condition that can arise --
> i.e., they have to leave invariants intact and return some error code.
> The C++ code, if correct in a non-threading environment, has to be
> able to deal with that.  So, yeah, I've got no problem with that.  Not
> sure about the cleanup handlers part.

Interesting. I didn't realize that you are talking about C++ code that
is correct in a single-threaded environment. My point was,
essentially, that this code is broken in any existing MT environment
that supports cancelation. Your point is that this can be avoided in
the future C++ MT environment.

> Cancellation exceptions shall be normal C++ exceptions.  Ultimately
> they are initiated by polling for a pending cancellation request.
> They can be thrown from std:: C++ functions that are already allowed
> to throw.  Cancellation error codes can be returned from standard 'C'
> library functions that are already allowed to return error codes.

Good enough for me.

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





Author: Ben Hutchings <ben-public-nospam@decadentplace.org.uk>
Date: Mon, 6 Sep 2004 15:21:56 GMT
Raw View
Stanley Friesen wrote:
> pdimov@gmail.com (Peter Dimov) wrote:
>>
>>Therefore, the target thread should enable cancelation when it is
>>ready to deal with a cancelation request, and disable it when it is
>>not. This can be made automatic based on some "is it ready" heuristic
>>(which better be right) but that's a separate question.
>
> The problem with this is the Windows problem of unkillable processes
> that require rebooting to get rid of.  There MUST be some way to
> override this, or there will be threads that hang inside the "not ready"
> state and cannot be killed.
<snip>

Thread cancellation - the orderly termination of threads by other
threads - is an entirely separate issue from forcible process
termination.  Processes can become unkillable as a result of kernel or
driver bugs (generally the latter) that cause a thread to become stuck
in an interruptible part of a system call.  This is a problem on
Windows, Unix and probably any operating system with imperfect
drivers.

By the way, if by unkillable you meant unkillable using Task Manager I
suggest you use real process management tools instead of GUI toys. ;-)

--
Ben Hutchings
Kids!  Bringing about Armageddon can be dangerous.  Do not attempt it in
your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'

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





Author: David Abrahams <dave@boost-consulting.com>
Date: Tue, 7 Sep 2004 20:02:03 GMT
Raw View
pdimov@gmail.com (Peter Dimov) writes:

> Interesting. I didn't realize that you are talking about C++ code
> that is correct in a single-threaded environment.

Yes.  And that should be correct in a sane MT environment.

> My point was, essentially, that this code is broken in any existing
>MT environment that supports cancelation.

Depends what you mean by "supports cancellation," I guess.

> Your point is that this can be avoided in the future C++ MT
> environment.

I'm not sure that was my point.


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

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





Author: David Abrahams <dave@boost-consulting.com>
Date: Tue, 7 Sep 2004 22:17:24 GMT
Raw View
Alexander Terekhov <terekhov@web.de> writes:

> David Abrahams wrote:
>
> [... 'ECANCELED' ...]
>
>> The C++ code, if correct in a non-threading environment, has to be
>> able to deal with that.
>
> How?
>
> You know that 'stickiness' won't work; cancel delivery shall
> disable cancellation.

I don't see why that should be the case.

> Even completely ignoring the issue of cancel on unwinding path... at
> best, each 'correct' C++ library would 'translate' it to some
> library specific nonstandard exception.

Yeah; it might.  So?

> I think that it's quite clear that even with ECANCELED you'd have to
> modify your C/C++ library code and make it 'cancel aware/safe'.

Not to me, yet.

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

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





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Wed, 8 Sep 2004 04:09:21 GMT
Raw View
David Abrahams wrote:
> Alexander Terekhov <terekhov@web.de> writes:
>
>> David Abrahams wrote:
>>
>> [... 'ECANCELED' ...]
>>
>>> The C++ code, if correct in a non-threading environment, has to be
>>> able to deal with that.
>>
>> How?
>>
>> You know that 'stickiness' won't work; cancel delivery shall
>> disable cancellation.
>
> I don't see why that should be the case.

The response to cancellation should be for the cancelled thread to
exit cleanly.  In the process of cleaning up resources it may well
need to make calls to system functions that poll for cancellation
requests, e.g. close().  If those functions re-report the cancellation
request, cleanup will fail.

>> Even completely ignoring the issue of cancel on unwinding path... at
>> best, each 'correct' C++ library would 'translate' it to some
>> library specific nonstandard exception.
>
> Yeah; it might.  So?
>
>> I think that it's quite clear that even with ECANCELED you'd have to
>> modify your C/C++ library code and make it 'cancel aware/safe'.
>
> Not to me, yet.

Cancellation should never be delivered to cleanup code.  So somehow it
has to be disabled in every destructor.  Explicit calls in the
destructor would be phenomenally expensive, so alternately the library
could check the call stack to see whether a destructor is in there
before reporting cancellation (and if it is, disabling cancellation
and retrying the system call).  The way it's delivered doesn't make a
difference.

I seriously wonder whether implicit cancellation polling is worth-
while.

--
Ben Hutchings
Life is what happens to you while you're busy making other plans.
                                                               - John Lennon

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Wed, 8 Sep 2004 17:55:08 GMT
Raw View
David Abrahams <dave@boost-consulting.com> wrote in message news:<ur7pduai5.fsf@boost-consulting.com>...
> pdimov@gmail.com (Peter Dimov) writes:
>
> > Interesting. I didn't realize that you are talking about C++ code
> > that is correct in a single-threaded environment.
>
> Yes.  And that should be correct in a sane MT environment.

This requirement isn't that obvious as it might appear. The library
needs to be tested in the new environment. Just expecting that it
"should work" is wrong in practice, although what you propose is
undeniably theoretically sound.

> > My point was, essentially, that this code is broken in any existing
> > MT environment that supports cancelation.
>
> Depends what you mean by "supports cancellation," I guess.

Well, I am not familiar with non-POSIX cancelation models, but I'm
willing to learn.

> > Your point is that this can be avoided in the future C++ MT
> > environment.
>
> I'm not sure that was my point.

Did I misunderstand again? You were saying that if nothrow functions
stay nothrow and report cancelation via an error code (ECANCELED),
this would not violate the implied exception safety guarantees in the
calling C++ code, and hence, this code should stay correct. No?

This is true, of course, but there is a cost/benefit tradeoff.
ECANCELED is less convenient than an exception, does not reflect
existing POSIX practice, and an exception doesn't "break existing
code" in the usual sense, i.e. on a recompile. It only breaks code on
porting, where breakage isn't that unexpected.

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Tue, 31 Aug 2004 04:22:46 GMT
Raw View
bouncer@dev.null (Wil Evers) wrote in message news:<41310b48$0$43451$e4fe514c@news.xs4all.nl>...
>
> Every time I tried to implement something close to the obvious idea of
> stopping a thread by throwing an exception, I failed, and I believe I now
> know why.  It is because there is nothing exceptional about a cancellation
> request.  A cancellation request should not be treated as a run-time error
> that suddenly bubbles up from somewhere deep down the implementation
> details of a higher-level abstraction.

An exception is not "exceptional", and it is not a "runtime error". An
exception is a long-distance return mechanism that unwinds the stack
until caught.

> Instead, it should be viewed as a
> regular event, not different from any of the other kinds of events the
> target thread is expected to handle.  This implies that the target thread
> should only deal with a cancellation request when it is ready to do so.

Therefore, the target thread should enable cancelation when it is
ready to deal with a cancelation request, and disable it when it is
not. This can be made automatic based on some "is it ready" heuristic
(which better be right) but that's a separate question.

> Obviously, when it is unwinding the stack because of some other exception,
> it is not.

"Obviously" aside (should be "typically"), this applies to arbitrary
secondary exceptions. Cancelation exceptions are not unique in this
regard.

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Tue, 31 Aug 2004 21:19:57 GMT
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<u3c24spp5.fsf@boost-consulting.com>...
> terekhov@web.de (Alexander Terekhov) writes:
>
> > David Abrahams wrote:
> > [...]
> >> Anyway, the additional provisions neccessary are simple: 'C' standard
> >> library functions don't throw; ...
> >
> > I agree that additional provisions necessary are simple: both 'C'
> > and 'C++' standard library functions... and async-cancel-regions
> > don't throw UNEXPECTED std::thread_cancel_request exceptions.
> >
> > Two-phase EH, you know.
>
> I realize you're obsessed with 2-phase EH. I even think it's cool.
> But it doesn't solve any problems here.  Even if 2-phase EH searches
> up the stack and finds a handler that matches thread_cancel_request,
> it doesn't mean that the intervening code was written to expect a
> cancel request from otherwise nonthrowing 'C' library functions.

It can be used to implement a heuristic that achieves a reasonable
"hit rate", although I'd design it so that it looks for a throw().
Finer-grained exception guarantees that discriminate on exception type
aren't as useful as they appear. ;-)

This is of course not limited to cancelations. It is a general
mechanism that a function can use to determine whether it should
operate in "never fail, just do your best" mode. It can be abused; in
new code it's better to just introduce two functions. But when the API
is set in stone, as the standard C library is...

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Tue, 31 Aug 2004 21:20:05 GMT
Raw View
aaa@bbb.com ("aaa@bbb.com") wrote in message news:<cgu46o02fju@news4.newsguy.com>...
> Andrei Alexandrescu (See Website for Email) wrote:
>
> >>If there is no CAS for that data type on that CPU, the implementation
> >>should be with the mutex.
> >
> >
> > I am not sure about this... there are implementations for which CAS is
> > central and mutexing would imply a redesign. I don't think we can just
> > abstract all that away.
> >
> > For example, say you want to do an atomic rmw operation on an integer. With
> > CAS it's simple. Without CAS, you need a mutex. But the mutex needs to be
> > stored with the integer. Now, can you modify the location (class etc.) where
> > that integer is stored such that you plant the mutex in there? Etc. etc.
>
> I don't understand the problem here.
>
> E.g. atomic<long long> would be an object of 8 bytes size if the CAS
> works for that datatype on that machine, while it would be 12 bytes size
> if on that machine a mutex is needed for the atomic operations, which
> would be (at least) something like [...]

The problem is that if atomic<> is implemented with a mutex, I often
wouldn't want to use it... except in those rare situations where my
mutex-based code would be the same as the atomic<>-generated one.

For example, shared_ptr<> needs to maintain two reference counts.
Three possible implementations are

- atomics only, when CAS is available;
- atomics + a rarely used mutex, when only atomic add is available;
- mutex + two ordinary variables otherwise.

An atomic<> that automatically falls back to a mutex+long is of no
help.

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 31 Aug 2004 21:21:22 GMT
Raw View
terekhov@web.de (Alexander Terekhov) writes:

> David Abrahams wrote:
> [...]
>> I realize you're obsessed with 2-phase EH. I even think it's cool.
>> But it doesn't solve any problems here.
>
> Sure it does. throw() ES (less restrictive stuff with the same
> effect aside for a moment) would "turn off" cancellation. No
> cancel, no problem. Oder?

What problem are you solving?  If you can add a throw() ES, you can
also add

     cancellation_disabler guard;

to the function implementation.  You don't need 2-phase ES for that.

>>                                         Even if 2-phase EH searches
>> up the stack and finds a handler that matches thread_cancel_request,
>> it doesn't mean that the intervening code was written to expect a
>> cancel request from otherwise nonthrowing 'C' library functions.
>
> If the intervening code was not written to expect a cancel request
> from otherwise nonthrowing 'C' library functions (I mean POSIX
> cancellation points) then such code is simply cancel-unsafe. I can
> live with it.

Obviously you're not concerned with the same things I am.  A C++
library with no shared data, that can throw, and that currently uses
the 'C' library, could be perfectly cancellation-safe as long as the
'C' library doesn't start throwing cancellation exceptions from
otherwise-nonthrowing functions.  I don't want to declare that C++
library broken in a MT environment.

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

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Wed, 1 Sep 2004 16:20:45 GMT
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<uy8jvla0m.fsf@boost-consulting.com>...
> terekhov@web.de (Alexander Terekhov) writes:
>
> > David Abrahams wrote:
> > [...]
> >> I realize you're obsessed with 2-phase EH. I even think it's cool.
> >> But it doesn't solve any problems here.
> >
> > Sure it does. throw() ES (less restrictive stuff with the same
> > effect aside for a moment) would "turn off" cancellation. No
> > cancel, no problem. Oder?
>
> What problem are you solving?  If you can add a throw() ES, you can
> also add
>
>      cancellation_disabler guard;
>
> to the function implementation.  You don't need 2-phase ES for that.

Convenience. The other part of Alexander's evil scheme to take over
C++ exception handling (*) is implicit throw() on every destructor.

> Obviously you're not concerned with the same things I am.  A C++
> library with no shared data, that can throw, and that currently uses
> the 'C' library, could be perfectly cancellation-safe as long as the
> 'C' library doesn't start throwing cancellation exceptions from
> otherwise-nonthrowing functions.  I don't want to declare that C++
> library broken in a MT environment.

I'm not sure how that can be. A nothrow region is typically supposed
to never fail, i.e. always reach the end, or bad things tend to
happen. If it can fail due to the thread being canceled and not due to
an unexpected exception being thrown, it seems to me that those bad
things will still happen. Whether the cancelation is an "in-band" or
an "out-of-band" exception, it still unwinds the stack and generally
acts the same as a C++ exception w.r.t. bad things, with the exception
(sorry) of not cleaning up half of the resources in the latter case.

(*) And the world. (**)
(**) Not necessarily in that order.

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 1 Sep 2004 17:00:53 GMT
Raw View
pdimov@gmail.com (Peter Dimov) writes:

> dave@boost-consulting.com (David Abrahams) wrote in message news:<uy8jvla0m.fsf@boost-consulting.com>...
>> terekhov@web.de (Alexander Terekhov) writes:
>>
>> > David Abrahams wrote:
>> > [...]
>> >> I realize you're obsessed with 2-phase EH. I even think it's cool.
>> >> But it doesn't solve any problems here.
>> >
>> > Sure it does. throw() ES (less restrictive stuff with the same
>> > effect aside for a moment) would "turn off" cancellation. No
>> > cancel, no problem. Oder?
>>
>> What problem are you solving?  If you can add a throw() ES, you can
>> also add
>>
>>      cancellation_disabler guard;
>>
>> to the function implementation.  You don't need 2-phase ES for that.
>
> Convenience. The other part of Alexander's evil scheme to take over
> C++ exception handling (*) is implicit throw() on every destructor.

That only adds convenience for destructors.  There are other nothrow
regions that won't automatically be helped.  My point is that although
it would certainly be nicer to have 2-phase EH, it doesn't *solve* any
problems, at least not completely.

>> Obviously you're not concerned with the same things I am.  A C++
>> library with no shared data, that can throw, and that currently uses
>> the 'C' library, could be perfectly cancellation-safe as long as the
>> 'C' library doesn't start throwing cancellation exceptions from
>> otherwise-nonthrowing functions.  I don't want to declare that C++
>> library broken in a MT environment.
>
> I'm not sure how that can be. A nothrow region is typically supposed
> to never fail, i.e. always reach the end, or bad things tend to
> happen. If it can fail due to the thread being canceled and not due to
> an unexpected exception being thrown, it seems to me that those bad
> things will still happen.

That is exactly my point.  That's why I don't want previously
nonthrowing 'C' library functions to start throwing when used from
C++.  Many C++ libraries call 'C' library functions in nothrow regions
under the assumption that they're not going to throw.  If we allow
those functions to start throwing in a MT environment, the C++ library
will be broken in that environment.  The only alternative to modifying
the C++ library's source will be to wrap uses of the C++ library in cancellation-disablers.

> Whether the cancelation is an "in-band" or an "out-of-band"
> exception

What do you mean?

> it still unwinds the stack and generally acts the same as a C++
> exception w.r.t. bad things, with the exception (sorry) of not
> cleaning up half of the resources in the latter case.

Not if it never gets thrown.

> (*) And the world. (**)
> (**) Not necessarily in that order.

Don't you mean "Oder?"  Or is it "odor?"

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

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





Author: bouncer@dev.null (Wil Evers)
Date: Sat, 28 Aug 2004 23:54:20 GMT
Raw View
In article <abefd130.0408270629.35a9f210@posting.google.com>, Peter Dimov
wrote:

> POSIX cancelation requests _are_ exceptions. They unwind the stack
> just like exceptions do. They invoke "destructors" just like
> exceptions do. "Mapping" them to C++ exceptions does create problems
> for implementations where this is not already the case, but the
> alternative would be a disaster. Just think about all the RAII objects
> that would be left undestroyed on the stack each time a thread is
> canceled.

That disastrous alternative is real: it's the situation I currently have to
live with.  The LinuxThreads cancellation implementation I'm using knows
nothing about the C++ stack unwinding machinery, and vice versa - I can
have pthread-style thread cancellation, I can have C++ exceptions, but I
can't have both.  Looking back at various attempts I made to deal with this
situation, I now tend to think of this apparently shocking incompatibility
as a blessing in disguise.

Every time I tried to implement something close to the obvious idea of
stopping a thread by throwing an exception, I failed, and I believe I now
know why.  It is because there is nothing exceptional about a cancellation
request.  A cancellation request should not be treated as a run-time error
that suddenly bubbles up from somewhere deep down the implementation
details of a higher-level abstraction.  Instead, it should be viewed as a
regular event, not different from any of the other kinds of events the
target thread is expected to handle.  This implies that the target thread
should only deal with a cancellation request when it is ready to do so.
Obviously, when it is unwinding the stack because of some other exception,
it is not.

- Wil

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 29 Aug 2004 22:26:17 GMT
Raw View
<aaa@bbb.com> wrote in message news:cgrkri02vtb@news1.newsguy.com...
> First of all thanks Andrei for having raised the MT subject which I
> strongly agree it's of utmost importance for C++.

Thank you, and for adding your points as well.

> At a higher level of performance penalty we should have a way to provide
> atomic increment (by 1), decrement (by 1), then atomic add and sub (by
> +-n) and then atomic exchange.
>
> At a higher level of performance penalty we should have the CAS

I think increment or decrement are about the same speed as
adding/subtracting anything... moreover, many processors simply implement
them all with CAS.

> and I don't know if more is needed.

<nod and wink>

> Of course if the CPU does not provide atomic increment, the implementation
> on that compiler will be with CAS. If the data is too big for a CAS, it
> will have a mutex. Templates with partial specialization with CAS for the
> CASable types and mutexes in the general case should do the job.
[snip]

I think that's a promising approach, however the primitives should also be
exposed such that users create new algorithms using them.

>> That's a good point to raise. I think CAS's spec should be "any POD of up
>> to pointer size at least". That makes things hard, but not impossible. A
>> more expressive CAS is "any POD of up to twice the pointer size".
>
> Why should the standard specify this?
> Some CPU would might not be able to provide that, so you wouldn't be able
> to create a standard-conforming C++ compiler on that CPU... am I missing
> something?

My point was the following. There are algorithms for which word-size CAS is
enough. There are others for which double-word CAS is needed.

Now, if someone is writing a library, they might decide:

a) I require double-word CAS
b) I require single-word CAS
c) I only require locking

A program should also (as you mention) be able to use CAS if available, and
fall-back on locks if not. These should be features available to all
programmers, not (only) used inside the standard library classes. So what we
could use is:

namespace std {
    namespace threads {
        template <unsigned size>
        struct cas_available {
            static const bool value = /implementation defined/;
        };
    }
}

Then compile-time polymorphism can be used to select one approach or the
other.

This sounds like the "optional features" that people used to be scared of,
but I think it's about time to bite the bullet. In fact, it's not at all
different from many algorithms (such as many compression ones) that require
one integral of exactly 32 bits on the target platform, and achieve that
with a ton of #if-#elses, the last one being:

..
#else
#error "Unsupported platform: need a 32-bit integral type"
#endif

With cas_available as above, now programmers can safely choose to only
compile on platforms that support certain capabilities, or if their design
allows, compile on all platforms with a decrease in performance.

> If there is no CAS for that data type on that CPU, the implementation
> should be with the mutex.

I am not sure about this... there are implementations for which CAS is
central and mutexing would imply a redesign. I don't think we can just
abstract all that away.

For example, say you want to do an atomic rmw operation on an integer. With
CAS it's simple. Without CAS, you need a mutex. But the mutex needs to be
stored with the integer. Now, can you modify the location (class etc.) where
that integer is stored such that you plant the mutex in there? Etc. etc.

Anyway, great points and good food for thought...


Andrei


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 30 Aug 2004 17:29:30 GMT
Raw View
terekhov@web.de (Alexander Terekhov) writes:

> David Abrahams wrote:
> [...]
>> Anyway, the additional provisions neccessary are simple: 'C' standard
>> library functions don't throw; ...
>
> I agree that additional provisions necessary are simple: both 'C'
> and 'C++' standard library functions... and async-cancel-regions
> don't throw UNEXPECTED std::thread_cancel_request exceptions.
>
> Two-phase EH, you know.

I realize you're obsessed with 2-phase EH. I even think it's cool.
But it doesn't solve any problems here.  Even if 2-phase EH searches
up the stack and finds a handler that matches thread_cancel_request,
it doesn't mean that the intervening code was written to expect a
cancel request from otherwise nonthrowing 'C' library functions.

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

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





Author: pasa@lib.hu ("Balog Pal")
Date: Mon, 30 Aug 2004 17:58:35 GMT
Raw View
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsiteForEmail@moderncppdesign.com> wrote in message

> namespace std {
>     namespace threads {
>         template <unsigned size>
>         struct cas_available {
>             static const bool value = /implementation defined/;
>         };
>     }
> }
>
> Then compile-time polymorphism can be used to select one approach or the
> other.

> This sounds like the "optional features" that people used to be scared of,
> but I think it's about time to bite the bullet. In fact, it's not at all
> different from many algorithms (such as many compression ones) that
require
> one integral of exactly 32 bits on the target platform, and achieve that
> with a ton of #if-#elses, the last one being:

Scared or not, I storngly believe the preprocessor must ALSO support
selection. I know a big deal of programmers who can easily see through a few
#ifdef-s but faint on the simplest example of template-based compile-time
polymorphism.

Is there any reason not to include a few predefined macros like __FILE__ is
currently?

> > If there is no CAS for that data type on that CPU, the implementation
> > should be with the mutex.
>
> I am not sure about this... there are implementations for which CAS is
> central and mutexing would imply a redesign. I don't think we can just
> abstract all that away.

That is still the best way to have it.   As discussed before, it is
*possible* to have a rich set of primitives.  Meaning any platform
supporting MT must be capable to make them work with the desired semantics.
The only difference being the speed of execution -- as some primitives may
be implemented in a single processor instruction, others in a couple, yet
others drag in using a mutex.

A program bilt on those primitives is always portable with the sme
semantics -- though it may be suboptimal in performance without a more
direct support.   The speed difference may or may not be important. And
there's a route to have alternative implemetations, using different
primitives, selected by again portable preoprocessor macros or TMP.

> For example, say you want to do an atomic rmw operation on an integer.
With
> CAS it's simple. Without CAS, you need a mutex. But the mutex needs to be
> stored with the integer. Now, can you modify the location (class etc.)
where
> that integer is stored such that you plant the mutex in there? Etc. etc.

With CAS it's simple, you can go for it, and think 'most systems I plan for
will have direct support anyway'.  On the rest there will be an emulated
CAS, using some builtin mutex.
Redesigning the algorithm could possibly save a plenty of those mutex
operations.

But that redesign is neither forced nor rendered impossible by the language.

Another note to the discussion on atomic primitives.  I'm not sure we can
just stamp so some primitives 'weak' based on their consensus facor being
low.  As there are algorithms we need other kind of consensus than presented
in the proof.

The simplest example is refcounting. Which works pretty well (and wait-free)
on any number of threads even with the simplest DEC instruction that doesn't
even provide the result value, only a zero flag indicating the result is
zero/nonzero. Where the protocol guarantees any thread obrained an 'inc' on
the counter before ability to use, and release shall only select exactly one
thread to dispose of the abandoned object.

[IOW we have counter at value 3. And three threads that have to decrement
the value. And on thread that made it drop to 0 shall do X (delete the
object), while other shall do Y (nothing). The problem does not map to 'we
three threads must select one to do X and everyone knows who he is'  The
threads doing Y shall not care who will do X.  Certainly that works fine for
any number beyond 3.]

We also shall note the paper says it limits scope to linearizable concurrent
systems (just before 2.3), IUC an Intel system with a system-wide #LOCK has
properties not taken into account.

Paul


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





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 26 Aug 2004 07:31:34 GMT
Raw View
In article <cgi4m5$2cup$1@news.cc.tut.fi>, jive <jive@nospam.invalid>
writes
>Main
>thing about threads should be that they are as transparent to the programmer
>as possible. My vote goes to the library implementotion with a slight twist
>to the actual syntax of the language.

IOWs you think that a pure library solution would not be the best we
could do. If we are going to apply any sort of 'twist' to the syntax of
C++ we need to get it right, we are already living with far too many
quirks resulting from failure to get it entirely right in the past. MT
is bad enough without having any unforeseen quirks arising because of a
syntax 'twist'.


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

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





Author: bouncer@dev.null (Wil Evers)
Date: Thu, 26 Aug 2004 19:28:35 GMT
Raw View
In article <abefd130.0408250417.78ced8ac@posting.google.com>, Peter Dimov
wrote:

>> >> > 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.
>> >>
>> >> The nasty part is not about what should happen when such an exception
>> >> is thrown; it is about where and when these exceptions are thrown.
>> >
>> > Whenever a cancelation point is invoked and a cancelation request is
>> > active? It's all spelled out in detail in POSIX.
>>
>> I know.  But do you really want that to happen while unwinding the stack
>> because of some other exception?
>
> Why is this so different from throwing an ordinary C++ exception while
> unwinding the stack because of an already thrown exception? Once you
> accept the "revolutionary" idea that a thread cancelation is an
> ordinary throw, the problems seem to just disappear.
>
> Your statement would now translate to: "Do you really want 'throw' to
> throw an exception while unwinding the stack because of some other
> exception?" Well yes, I do. I wouldn't have invoked a throw if I
> didn't.

Well, it may not be you who invoked the 'throw'.  In the pthreads/c++
mapping case, the cancellation exception may originate from the C library
stub for a blocking system call, such as write().  And that write() may
have been called from the destructor of some streambuf, invoked by the
stack unwinding machinery as a result of some other exception.  Bang,
you're dead.

The problem with mapping cancellation requests to C++ exceptions is that it
changes the behaviour of functions that are currently not expected to throw.
IMO, that could result in a long period of instability - at least without
additional provisions; the question is what those provisions should be.

But you're right, as such, this problem has nothing to do with threads.
Similar trouble would result if, say, vector<T>::swap() would suddenly be
licensed to throw.

- Wil

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

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 26 Aug 2004 20:37:40 GMT
Raw View
bouncer@dev.null (Wil Evers) writes:

> Well, it may not be you who invoked the 'throw'.  In the pthreads/c++
> mapping case, the cancellation exception may originate from the C library
> stub for a blocking system call, such as write().  And that write() may
> have been called from the destructor of some streambuf, invoked by the
> stack unwinding machinery as a result of some other exception.  Bang,
> you're dead.
>
> The problem with mapping cancellation requests to C++ exceptions is that it
> changes the behaviour of functions that are currently not expected to throw.
> IMO, that could result in a long period of instability - at least without
> additional provisions; the question is what those provisions should be.

That was my argument in the discussion at
http://www.codesourcery.com/archives/c++-pthreads/threads.html.  Some
people seemed to think that no code written under the assumption that
some 'C' standard library function can't throw can possibly be correct
when running in a thread other than the main one.  That seems very
wrong to me, but I lack the experience to argue it with authority.

Anyway, the additional provisions neccessary are simple: 'C' standard
library functions don't throw; instead they report cancellation using
the same mechanism by which they report other failures-to-complete --
errno or whatever.  The political problem was that these same people
didn't like the idea that the cancellation could be ignored.  The way
I see it, even cancellation exceptions can be swallowed, and
regardless there's no way to ensure that a cancellation request is
honored, so there's little benefit in insisting that this code use
exceptions.

> But you're right, as such, this problem has nothing to do with threads.
> Similar trouble would result if, say, vector<T>::swap() would suddenly be
> licensed to throw.

Right.

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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 27 Aug 2004 02:24:15 GMT
Raw View
"Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
news:Hub+ltDvwYLBFwkq@robinton.demon.co.uk...
> In article <cgi4m5$2cup$1@news.cc.tut.fi>, jive <jive@nospam.invalid>
> writes
>>Main
>>thing about threads should be that they are as transparent to the
>>programmer
>>as possible. My vote goes to the library implementotion with a slight
>>twist
>>to the actual syntax of the language.
>
> IOWs you think that a pure library solution would not be the best we could
> do. If we are going to apply any sort of 'twist' to the syntax of C++ we
> need to get it right, we are already living with far too many quirks
> resulting from failure to get it entirely right in the past. MT is bad
> enough without having any unforeseen quirks arising because of a syntax
> 'twist'.

Just to set the record straight - when I keep on saying "the language must
be changed" I am referring to the semantics, not the syntax. Beyond
semantics, a solution that looks entirely like function calls is fine.

Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 27 Aug 2004 02:25:31 GMT
Raw View
""jive"" <jive@nospam.invalid> wrote in message
news:cgi4m5$2cup$1@news.cc.tut.fi...
> 1) To whom the standard is actually addressed to? If compiler vendors and
> OS
> suppliers are the target audience, then I think this is not the right
> attitude. If the standard is supposed to provide the ultimate programming
> reference, it is way too complex already.

The standard establishes the semantics of the language in the most precise
terms such that it serves a reference point for programmers about what they
can expect, and for implementers about what they need to implement.

> 2) Is there a war or a rivalry going on between Java and C++? If C++
> standard is going to the direction "one world one language"? There are
> troubled times ahead. I personally think that for a job you need the right
> tool not swiss army knife. Average programmer is hardly McGyver.

No. There is a rivalry between Java and C# though :o).

I guess you could be referring to my mentioning that Java has a strategic
advantage over C++. "Rivalry" has something silly with it. If Java can do
portable MT (and now add lock-free MT to that) and C++ cannot, that simply
means that entire application domains are accessible to Java and not to C++.
Look what happened with reflection. Java has acquired a lot of market share
on server-side programming specifically because of that strategic advantage.
If we don't do anything about threads, Java will displace C++ in more areas.
MT is not a petty issue like multiple inheritance or even const. I haven't
heard of any project manager making a decision based on such things. But MT
enables a whole problem domain.

> 3) Where is the line between the concurrent programming and the
> multithread
> programming?

Depends on whom you are listening to :o). The terms are used interchangeably
by many. In general, MT is a more precise term in that it specifies multiple
threads of execution, each having its own private stack, inside the same
memory space. Concurrent programming is to many a broader term that could
mean MT programming, multiple processes, even distributed programming.

> What I think I try to say is, that the programmer doesn't wan't to deal
> with
> low level primitives and such. This I've noticed while trying to tell
> people
> how to program with C++. My dream is that there would be a keyword like
> 'const' to tell that a member, object or variable is thread-safe. The
> keyword could be the same 'restrict' as in C99.
> (9888:1999 6.7.3/7). The special association in this case would be
> compiler
> generated and enforced memory barrier between threads.
>
> How this is achieved is at least to me irrelevant( i.e. implementation
> dependent ).

Hopefully it will be like that in 50 years or more. As of now, optimizer
technology is not there yet. What we can do today is to offer either good
programmer control and performance at the expence of simplicity, or
simplicity at the expense of performance.

> Thread creation could be implemented as a templatised function taking the
> thread image as a functor as the firts parameter and a memory management
> handle as another. Single thread environment could use syntax like:
[snip]

That's the last thing that we need to worry about. It's actually the
first-to-last. Last is what to do on systems that don't support threads :o).

> Main
> thing about threads should be that they are as transparent to the
> programmer
> as possible. My vote goes to the library implementotion with a slight
> twist
> to the actual syntax of the language.

IMHO that's not the main thing about threads. I think the main thing is that
the compiler is aware enough of threading constructs so that it can reason
about correctness. Ideally, we'd transform race detection and deadlocking
into a typechecking issue.

Things can be done without any twist to the syntax of the language. The
changes in semantics, however, must be profound.


Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 27 Aug 2004 02:26:15 GMT
Raw View
"Jim Hyslop" <jhyslop@ieee.org> wrote in message
news:412B592F.8080706@ieee.org...
> Hyman Rosen wrote:
>
>> Sergey P. Derevyago wrote:
>>
>>> IMHO POSIX C++ binding is the way to go.
>>
>>
>> Concurrency must be defined by the language. It is
>> impossible to add concurrency to C++ via nothing but
>> a library.
> You and Andrei have both made this statement. Could you provide some
> references to background reading to support this? I have to admit I'm not
> all that familiar with the low-level issues.

It's actually a tad harder than it might seem. There are two parts to it:
one is understanding what guarantees you want/need to establish about how
threads interact with memory. Second, a simple perusal of the C++ standard
will show that C++'s semantics (notably observable behavior) are not
appropriate for defining said guarantees.

While doing that, it's instructive to see how Java 1 tried and failed at it:
http://www.cs.umd.edu/~pugh/java/memoryModel/


Andrei


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





Author: do-not-spam-benh@bwsint.com (Ben Hutchings)
Date: Fri, 27 Aug 2004 02:41:39 GMT
Raw View
"Edward Diener" wrote:
<snip>
> I was more interested in [Andrei Alexandrescu's] idea that somehow
> processors themselves can re-order writes to memory in such a way
> that subsequent reads of that memory will not yield the new value. I
> do not think that can happen on any CPU once the write has been
> completed, and I do not care how one defines "memory".
<snip>

Indeed, but multiple threads sharing memory may run on multiple
processors simultaneously, and synchronising all memory access between
those processors would be a terrible drag on performance.
Multiprocessor systems may seem somewhat exotic but they are becoming
increasingly common as it becomes harder to crank up the speed of
individual processors.  More and more of us are going to have to learn
how to write code that makes good use of multiple processors, and this
is why it is so important that the standard should address
multithreading.

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





Author: bouncer@dev.null (Wil Evers)
Date: Wed, 25 Aug 2004 04:27:01 GMT
Raw View
In article <abefd130.0408230654.1ed8d10@posting.google.com>, Peter Dimov
wrote:

> bouncer@dev.null (Wil Evers) wrote in message
> news:<4127515d$0$78772$e4fe514c@news.xs4all.nl>...
>
>> In article <abefd130.0408200546.1133f67b@posting.google.com>, Peter Dimov
>> wrote:
>>
>> > 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.
>>
>> That could easily be solved by an atomic_traits<> template with
>> specializations for types that have hardware-supported atomic operations.
>
> Depends on how you define "solved", I guess. How can atomic_traits<>
> help you write portable lock-free code?

atomic_traits<T> could be used as a compile-time device that selects between
hardware-supported atomic operations and your own mutex-based logic,
avoiding the (presumably inferior) mutex-protected T fallback.

>> > 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.
>>
>> The nasty part is not about what should happen when such an exception is
>> thrown; it is about where and when these exceptions are thrown.
>
> Whenever a cancelation point is invoked and a cancelation request is
> active? It's all spelled out in detail in POSIX.

I know.  But do you really want that to happen while unwinding the stack
because of some other exception?

- Wil

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

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





Author: jive@nospam.invalid ("jive")
Date: Thu, 26 Aug 2004 00:05:35 GMT
Raw View
> Great point. That's a problem for compiler writers. "Let'em eat cake!!!"
:o)

Because I consider myself as a novice around these posters here, I disguise
my
opinions as questions. So be patient :)

1) To whom the standard is actually addressed to? If compiler vendors and OS
suppliers are the target audience, then I think this is not the right
attitude. If the standard is supposed to provide the ultimate programming
reference, it is way too complex already.

2) Is there a war or a rivalry going on between Java and C++? If C++
standard is going to the direction "one world one language"? There are
troubled times ahead. I personally think that for a job you need the right
tool not swiss army knife. Average programmer is hardly McGyver.

3) Where is the line between the concurrent programming and the multithread
programming?

What I think I try to say is, that the programmer doesn't wan't to deal with
low level primitives and such. This I've noticed while trying to tell people
how to program with C++. My dream is that there would be a keyword like
'const' to tell that a member, object or variable is thread-safe. The
keyword could be the same 'restrict' as in C99.
(9888:1999 6.7.3/7). The special association in this case would be compiler
generated and enforced memory barrier between threads.

How this is achieved is at least to me irrelevant( i.e. implementation
dependent ).

Thread creation could be implemented as a templatised function taking the
thread image as a functor as the firts parameter and a memory management
handle as another. Single thread environment could use syntax like:

std::thread<std::main( void )>;

 int std::main( void )
{
 .
 .
 .
}

where the call is partial specialisation of the 'invocator' -function. Main
thing about threads should be that they are as transparent to the programmer
as possible. My vote goes to the library implementotion with a slight twist
to the actual syntax of the language.

> bool std::uncaught_exception() {
>   return std::uncaught_exception_count() > 0;
> }

And I would really want to see the value of a semaphore :)

> Can I patent it? :o)

Hopefully not...

- jive


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





Author: pdimov@gmail.com (Peter Dimov)
Date: Thu, 26 Aug 2004 00:05:35 GMT
Raw View
bouncer@dev.null (Wil Evers) wrote in message news:<412b218d$0$43451$e4fe514c@news.xs4all.nl>...
> In article <abefd130.0408230654.1ed8d10@posting.google.com>, Peter Dimov
> wrote:
>
> > bouncer@dev.null (Wil Evers) wrote in message
> > news:<4127515d$0$78772$e4fe514c@news.xs4all.nl>...
> >
> >> In article <abefd130.0408200546.1133f67b@posting.google.com>, Peter Dimov
> >> wrote:
> >>
> >> > 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.
> >>
> >> That could easily be solved by an atomic_traits<> template with
> >> specializations for types that have hardware-supported atomic operations.
> >
> > Depends on how you define "solved", I guess. How can atomic_traits<>
> > help you write portable lock-free code?
>
> atomic_traits<T> could be used as a compile-time device that selects between
> hardware-supported atomic operations and your own mutex-based logic,
> avoiding the (presumably inferior) mutex-protected T fallback.

Technically, yes, it could. But if you try to illustrate this with an
example, you'll see that portability isn't worth the price. The
current status quo - providing portable higher level library
components (shared_ptr, lock_free_queue) that are implemented in a
platform-specific way - seems better. Of course you can't do that in
Java. ;-)

> >> > 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.
> >>
> >> The nasty part is not about what should happen when such an exception is
> >> thrown; it is about where and when these exceptions are thrown.
> >
> > Whenever a cancelation point is invoked and a cancelation request is
> > active? It's all spelled out in detail in POSIX.
>
> I know.  But do you really want that to happen while unwinding the stack
> because of some other exception?

Why is this so different from throwing an ordinary C++ exception while
unwinding the stack because of an already thrown exception? Once you
accept the "revolutionary" idea that a thread cancelation is an
ordinary throw, the problems seem to just disappear.

Your statement would now translate to: "Do you really want 'throw' to
throw an exception while unwinding the stack because of some other
exception?" Well yes, I do. I wouldn't have invoked a throw if I
didn't.

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Fri, 27 Aug 2004 19:20:13 GMT
Raw View
bouncer@dev.null (Wil Evers) wrote in message news:<cgku0q$jf4$1@news.cistron.nl>...
> In article <abefd130.0408250417.78ced8ac@posting.google.com>, Peter Dimov
> wrote:
>
> >> >> > 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.
> >> >>
> >> >> The nasty part is not about what should happen when such an exception
> >> >> is thrown; it is about where and when these exceptions are thrown.
> >> >
> >> > Whenever a cancelation point is invoked and a cancelation request is
> >> > active? It's all spelled out in detail in POSIX.
> >>
> >> I know.  But do you really want that to happen while unwinding the stack
> >> because of some other exception?
> >
> > Why is this so different from throwing an ordinary C++ exception while
> > unwinding the stack because of an already thrown exception? Once you
> > accept the "revolutionary" idea that a thread cancelation is an
> > ordinary throw, the problems seem to just disappear.
> >
> > Your statement would now translate to: "Do you really want 'throw' to
> > throw an exception while unwinding the stack because of some other
> > exception?" Well yes, I do. I wouldn't have invoked a throw if I
> > didn't.
>
> Well, it may not be you who invoked the 'throw'.  In the pthreads/c++
> mapping case, the cancellation exception may originate from the C library
> stub for a blocking system call, such as write().  And that write() may
> have been called from the destructor of some streambuf, invoked by the
> stack unwinding machinery as a result of some other exception.  Bang,
> you're dead.

I agree, and your subsequent quote

> But you're right, as such, this problem has nothing to do with threads.
> Similar trouble would result if, say, vector<T>::swap() would suddenly be
> licensed to throw.

means that I've nothing to add. :-)

> The problem with mapping cancellation requests to C++ exceptions is that it
> changes the behaviour of functions that are currently not expected to throw.
> IMO, that could result in a long period of instability - at least without
> additional provisions; the question is what those provisions should be.

POSIX cancelation requests _are_ exceptions. They unwind the stack
just like exceptions do. They invoke "destructors" just like
exceptions do. "Mapping" them to C++ exceptions does create problems
for implementations where this is not already the case, but the
alternative would be a disaster. Just think about all the RAII objects
that would be left undestroyed on the stack each time a thread is
canceled.

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Tue, 24 Aug 2004 02:46:03 GMT
Raw View
bouncer@dev.null (Wil Evers) wrote in message news:<4127515d$0$78772$e4fe514c@news.xs4all.nl>...
> In article <abefd130.0408200546.1133f67b@posting.google.com>, Peter Dimov
> wrote:
>
> > 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.
>
> That could easily be solved by an atomic_traits<> template with
> specializations for types that have hardware-supported atomic operations.

Depends on how you define "solved", I guess. How can atomic_traits<>
help you write portable lock-free code?

> > 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.
>
> The nasty part is not about what should happen when such an exception is
> thrown; it is about where and when these exceptions are thrown.

Whenever a cancelation point is invoked and a cancelation request is
active? It's all spelled out in detail in POSIX.

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





Author: seh@panix.com ("Steven E. Harris")
Date: Tue, 24 Aug 2004 02:51:21 GMT
Raw View
terekhov@web.de (Alexander Terekhov) writes:

>   void lock() throw() {
>     if (m_lock_status.swap(1, msync::ccacq))
>       while (m_lock_status.swap(-1, msync::ccacq))
>         m_retry_event.wait();
>   }

Doesn't the repeated swapping in of -1 possibly cause a spurious event
wakeup when only two threads overlap in desired ownership of the same
lock?

Consider:

Thread A attempts lock:
  status: 0 => 1 (returns 0)

Thread B attempts lock:
  status: 1 => 1 (returns 1)
  status: 1 => -1 (returns 1)
  wait

Thread A unlocks:
  status: -1 => 0 (returns -1)
  signal

Thread B awakens:
  status: 0 => -1 (returns 0)


Now Thread B holds the lock, but the lock status still notes
contention, meaning that when Thread B releases the lock, it must
signal the event:

Thread B unlocks:
  status: -1 => 0 (returns -1)
  signal


I'm wondering if it's worth trying to optimize away the spurious
signal at the end, like this:

void lock() throw() {
  if (m_lock_status.swap(1, msync::ccacq)) {
    for ( ; ; ) {
        unsigned int const prev =
            m_lock_status.swap(-1, msync::ccacq);
        if ( 0 == prev ) {
            m_lock_status.swap(1, msync::???);
            break;
        }
        else
            m_retry_event.wait();
    }
  }
}


Oh, but that wouldn't work if there was another thread waiting, as the
following unlock() call would not note contention and signal the
event:


Thread A attempts lock:
  status: 0 => 1 (returns 0)

Thread B attempts lock:
  status: 1 => 1 (returns 1)
  status: 1 => -1 (returns 1)
  wait

Thread C attempts lock:
  status: -1 => 1 (returns -1)
  status: 1 => -1 (returns 1)
  wait

Thread A unlocks:
  status: -1 => 0 (returns -1)
  signal

Thread B awakens:
  status: 0 => -1 (returns 0)
  [new scheme here:]
  status: -1 => 1 (returns -1)

Thread B unlocks:
  status: 1 => 0 (returns 1)


Thread C is then left waiting when B should have signaled. It seems
that the occasionally spurious signal on unlock is a necessary
trade-off for correctness.

--
Steven E. Harris

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





Author: bouncer@dev.null (Wil Evers)
Date: Tue, 24 Aug 2004 20:08:56 GMT
Raw View
In article <u8yc75o5n.fsf@boost-consulting.com>, David Abrahams wrote:

> bouncer@dev.null (Wil Evers) writes:
>
>> As the moderator suggested: if
>> you're interested in the hard part, please check the archives of
>> c++-pthreads mailing list -
>>
>>   http://www.codesourcery.com/archives/c++-pthreads/threads.html
>
> The only hard things there are "political," (**) not technical.

I'm not sure about that.  The thing I remember is that some of the
participants seemed to think that it's OK to let exceptions escape from
destructors.  I never thought of that as a political problem.

> The political difficulties are:
>
>   1. That there's already some precedent somewhere for throwing
>      exceptions for thread cancellation from 'C' library functions.
>      That's a suboptimal choice at best, but it's hard to swim against
>      the tide.

That would be the way to go if compatibility with POSIX threads is
considered important, and I can see how one might call that a 'political'
goal.  On the other hand, we all know how to map a set of specific
exceptions to error return codes and vice versa, so I tend to think of this
as a minor issue.

Besides, I'd say that it's time for the C++ community to accept that in a
mixed-language environment, exceptions may originate from modules written
in other languages.

>   2. Some people believe strongly that it should be possible to ensure
>      that thread cancellation requests can never be ignored and always
>      lead to thread termination in finite time.  That's just
>      impossible to do in general without corrupting program state
>      (i.e. crashing), but these people aren't convinced.

Well, POSIX threads has pthread_setcancelstate(), which allows the program
to selectively disable cancellation for specific regions of code, and I
don't remember anyone suggesting that this function should not be included
in the C++ mapping.  However, I do remember that some of the participants
objected strongly to the possibility that a cancellation exception could
end up in a catch block without being rethrown, effectively preventing the
thread from terminating immediately.

I agree that in general, it is impossible to guarantee that a single
cancellation exception always leads to thread termination without
corrupting the program as a whole.

- Wil

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

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





Author: bouncer@dev.null (Wil Evers)
Date: Tue, 24 Aug 2004 23:47:07 GMT
Raw View
In article <2ot3phFe21t4U1@uni-berlin.de>, Andrei Alexandrescu (See Website
for Email wrote:

> I believe what's reasonable and doable is:
>
> a) Any thread API function (such as sleeping, locking a mutex, waiting for
> an asynchronous result) will throw an exception when thread cancelation
> has been requested. This way, a thread that has proper exception handling
> and uses some synchronization routine will finish properly. I wonder if
> CAS should be part of this group... what are other people's thoughts?
>
> b) A thread that hangs in a loop without calling any thread API function
> will not be stoppable.
>
> I think that's entirely reasonable. After all, you can't claim peaceful
> termination of a ST process that just hangs in a loop.

That's basically what POSIX calls deferred cancellation mode.  Noteable
differences are:

* mutex operations are not cancellation points (this suggests CAS shouldn't
be a cancellation point either)
* most (all?) blocking system calls, including those unrelated to threads,
are cancellation points.

- Wil

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

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





Author: pasa@lib.hu ("Balog Pal")
Date: Sat, 21 Aug 2004 22:19:31 GMT
Raw View
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:2okvldFbs24tU1@uni-berlin.de...

> Things become different when it comes down to stuff
> like thread creation: this should indeed fail, best at compile time.

It shouldn't fail at compile time.   Thread creation is a function that can
legally fail on systems with support for threads.  The system may run out of
resources, or out of quota to create yet another thread, possibly even the
first.  Prgrams shall be written to handle that situation, and it covers the
case when it always fail.

Also it is reasonable to expect a program to have fallback strategy, say you
write an interactive program, and able to send some tasks like file download
or lengthy caclulations to background -- if a thread cannot be created the
user is informed, and it stays in the main thread, etc.

Also you can have a set of sources where some functions you do not intend to
call, they shall not prevent the compilation.   Like programs having fopen
compiles on system without files, you just get 'access denied' or some other
error for any possible filename.

Though I'd expect a quality implemetation to issue a warning.  Like I get
one compiling with RTTI turned off, when the compiler discovers a
dynamic_cast.    That may or may not be an actual problem, the compiler
shall not decide that instead of the programmer.

Paul


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 22 Aug 2004 00:39:47 GMT
Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:

> "David Abrahams" <dave@boost-consulting.com> wrote in message
> news:uhdqzqcrz.fsf@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.

Yeah.  FWIW this wasn't my idea.  I've heard it bandied about the
committee in the past.

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

Metaprogramming like

      std::max_threads == 1

??

It's simple, but is that really a metaprogramming technique? ;-)
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 22 Aug 2004 00:39:55 GMT
Raw View
"Alexander Terekhov" <terekhov@web.de> wrote in message
news:4127A8E3.2A99331F@web.de...
>
> "Andrei Alexandrescu (See Website for Email)" wrote:
> [...]
>> > Also, variable-level visibility qualifiers may be inefficient even on
>> > hardware that supports "everything". Consider a typical shared_ptr
>> > reference count. It doesn't need any kind of barrier on increment and
>> > needs a "conditional" barrier on decrement, depending on whether the

(Incorrect quote btw...)

> For example (not really optimal but good enough for an illustration),
>
> http://www.terekhov.de/pthread_refcount_t/experimental/refcount.cpp
[snip]

Cool. That's how CAS implements atomic integer RMW operations.

> And it doesn't need any barriers at all (even for decrements) if
> managed object is immutable (i.e. shared_ptr shall use is_const<> ;-) ).
>
>> I don't understand how shared_ptr gets away by incrementing a shared
>> counter
>> without absolutely any barrier.
>
> Why would you need some barrier on increment?

Not sure how Peter does it. You'd need a barrier at least on some
architecture to read the counter even if you use CAS.


Andrei


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 22 Aug 2004 03:44:51 GMT
Raw View
dietmar_kuehl@yahoo.com (Dietmar Kuehl) writes:

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

Yes, that's one technique.  However, it's not mandated by the
standard, so there's no reason the standard should have to say
anything special about it.  There are better techniques,
e.g. construct the exception on the stack (unwinding doesn't have to
happen the way you think ;->).

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

I don't think it's neccessary to spell it out, but now we're
splitting hairs.  There are much bigger problems in the language spec
w.r.t. MT than exception handling.  Andrei's been pointing some of
them out in this thread.

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

Yeah, OK.  There are some minor adjustments needed.  Let's worry
about the hard stuff first; these are easy.

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

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 22 Aug 2004 03:45:14 GMT
Raw View
loic.actarus.joly@wanadoo.fr (Lo=EFc Joly) writes:

> If you have the following code :
>
> a=3D1;
> f();
> b=3D2;
>
> And you do not have access to the source code for f(), there is no way
> you can knows if reordering the assignements around the call to f()
> might change or not the observable behaviour of the program (a and b
> might be aliased...).
>
> Therefore, you are not allowed to do it, and if f really is a
> synchronisation primitive, this apply but just as the special case of
> a more generic rule.
>
> Is there any flaw in this way of thinking ?

Reordering can happen at link time or even at runtime, when all the
instructions can be seen (e.g. by a JIT compiler).  It's all allowed
by the C++ abstract machine.

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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 22 Aug 2004 04:49:10 GMT
Raw View
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:2oku37Fbq02fU1@uni-berlin.de...
> 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.

Great point. That's a problem for compiler writers. "Let'em eat cake!!!" :o)

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

Excellent point again, and easy to implement. A nice touch would be - if
another thread is waiting for the return of the asynchronously-called
function, then the waiting function throws a copy of the exception thrown in
that asynchronously-called function.

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

Ja. Ideally, again, we'd fix std::uncaught_exception() such that it does
something useful. Another thread suggested a number of possible changes, the
simplest being "unsigned int std::uncaught_exception_count()".

If that function is provided, I will be glad to contribute a new
implementation of std::uncaught_exception:

bool std::uncaught_exception() {
  return std::uncaught_exception_count() > 0;
}

Can I patent it? :o)

Andrei


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





Author: pasa@lib.hu ("Balog Pal")
Date: Sun, 22 Aug 2004 04:56:23 GMT
Raw View
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsiteForEmail@moderncppdesign.com> wrote in message

> > IMHO it's more like  asking the general to fly from flower to flower
like
> > a  bee.
>
> Not sure I understand.

The King used that figure in The Little Prince explaining why it is his
fault hen he issues an 'unreasonable' (really more like impossible) order.

As members pointed out no one feels enough power in himself to start the
action. Like any one termite may feel it is impossible to construct a castle
that big -- once it is started they can keep putting little spot of cement
until the thing ges created after all.

IMO it is pretty reasonable other people said recently -- you could start
the rock'n'roll on the upcoming meeting.   There isn't much time left to
write some solid and detaild proposal, but that is not needed either.

An outline very well do, that shows the areas of work, certainly the already
discovered questions and answers are good to be collected.   (The formal,
fine grain and detailed description of elements like a memory model can be
obtained later from other existing documents. )   And a good rationale at
the start on 'why this stuff is really so needed', you can paste it together
from your recent posts.

Having that the committee may assign resources to the task -- unfortunately
I don't know what is the regular way to deal with such issues.  If the
outline shows it's a really big chunk of work, maybe a separate group or
section gets created.

Even if all that happes is a 'well, we see the first step, we'd like to see
some more fleshed out by the next meeting', is a great progress.  Unless I
musunderstood David Abrahams is ready to take over organizing the
development.

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

:)

> > Is there anything more essential in core? ...
> And exceptions.

Yeah, as pointed out on another thread uncaught_exception() must be defined
for situations when multiple threads throw at once.

Also the other special functions defined in the core must be revisited. Like
what how terminate works issued on one thread while others still executing.
exit() is even more interesting...

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

I wasn't advocating, just summarized what I read on a plenty of threads on
that subject. James Kanze had a good rundown why volatile is not good
neither necessary in current situations. Certainly that applied to the
volatile as it is today.

I recall your article on how volatile/tainted can be used in a cool new way.
It is really neat. But i have a strong gut feeling it wouldn't work. At
least for the implicit membar semantics on volatile I have in mind (implicit
loadbar before, storebar after). Not for non-atomics.
And if the semantics would turn a volatile object int atomic by some magic,
it would still not work. [But note I'm writing this from the top of my head
without rereading the article...it may be far off.]

But that is not a question to decide here and now -- I mean the
resolution --, certainly the 'what to do with volatile' is one certain pont
to address.
IIRC currently an implementation is free to assing semantics to volatile,
and std says nothing beside it participating in observable behavior.
If any new semantic is to be defined byt the standard it must be checked for
conflicts with existing stuff out there -- contradicting semantics may break
a plenty of current code.

And the good way of evaluation IMHO is to present code examples, problems
and solutions, then check thoroughly that the problem is really solved with
the proposed semantics.  (or going the other way -- deducing the semantics
needed in order to make the solution working.)

Somewhere you're right that, I consider the threading issues where ABP is
needed, even extend it t VMABP (very much...)  as practice shows how easy it
is to slip, to think something is working while it is not.  Even brilliant
people and those with quite experience in the field tend to miss things time
to time. So the working approach here is to have worked out algorithms, and
in the field restrict to use those algorithms just checking the code really
implements it correctly.    The cyclone around DCLP must teach us that
lesson.

And while I'm eager to have any and all the support from compiler and type
system, I grew skeptic wrt auto stuff in threading.   I've seen those
attempts fail miserably, doing tons of not necessary work while still
missing the important point.   And bringing in the 'idiot factor'.  The
containers in the early java tried to climb that mountain.   Since then I
read some fine atricles on why was that a wrong approach.  Unfortunately
those articles do not reach all the people who sit down and write
applications with threads (after all it is so sexy to la\unch another
thread, even without a clear on its purpose), and think everything is
alright. Then possibly add some 'synctronised'   and after a time make
everything and the pussycat 'synctronised'. Still possibly leaving the
program broken.

Though that's just crying, as *I* do not expect any magic to make my
problems away, and put attenton aside I really do welcome any help from the
compiler.  Even if it is not complete, just usable for a plenty of real life
situations. Some tainted qualifyer  that really does nothing but slap my
hand if I forget to  pay attention (like const) may prove golden.
I'm not sure volatile can be recycled for that purpose, we sahll lokk after
it.  And for a new addition to the language the regular cost/benefit
analysis shall come forth.

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

CAS is not present on intel 80386 and down, also on SPARC V8 and down.
Certainly those are not today's processors, but ones fully capable running
MT systems. IMHO we can't build on having CAS as a direct processor
instruction anywhere threading exist and is used.    However IMHO we can
really expect to have it on most systems.
Also, I strongly believe some atomic instruction doing load/store the same
time is essential to write a correct mutex or semaphore, and CAS can be
written using it.
So C++ could hve a builtin CAS primitive with defined semantics, that will
work everywhere, just being not really efficient on some systems.

But then, if we have CAS that way, why not have the rest of primitives?
inc/dec indeed can be done via CAS, but that solution is way slower compared
to native.  Why not have it the same way as CAS, described above.

In real-life code atomic inc/dec of a counter is a pretty much used
instruction, and one "ordinary" library writers will definitely use. Soem as
a broken ++ctr.  And others start writing ther own inc using CAS.  having it
in std, and supported by compiler magic to give the best implemetation on
the target build would be a great achivement.

Also from the practical point of view of the user of those primitives I'd
expect facilities to query the implemetation for how those instructions are
implemented. Using preprocessor, possibly also at runtime.
Also a quality implementation shoul issue a warning if a primitive is useg
that is emulated inefficiently.  (I know the standard currently have no
totation of desired warnings or warnings at all, that's just a side note.)

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

AFAIK having just membar, CAS and an atomic type it is possible to write any
and all the sync primitives, so it would put C++ back on track being usable
as a portable assy of these times. ;-)

To address Nagle's point here, whan a system is designed it is important to
have the bricks of the needed grain.    It's like the story of C-style
casts, those do too much.  It would be bad to add only boulders to C++, say
starting at mutex. No-one told it is easier to work with the lowest level
stuff, not that unaware people have to.  But not giving the appropriate
tools prevent the creation of really portable and also really usable
libraries. For in-house use as for worldwide use the same way.

Back to CAS, Alex has a good point we face an ugly problem of what types can
be applied to CAS, and other primitives.

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

LOL, good to see you gave in to the pressure. ;)

I'm in for anything that can be done via mail or like stuff.

Paul




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





Author: eldiener@earthlink.net ("Edward Diener")
Date: Sun, 22 Aug 2004 04:57:18 GMT
Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> ""Edward Diener"" <eldiener@earthlink.net> wrote in message
> news:KUaVc.3193$2L3.2439@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."]

Regarding your joke, "And the doctor says: So if doing X gives you pain,
don't do it." But what does that have to do with the price of tea in Romania
<g> ?

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

OK, I very much appreciate your explanation and let us say that the
instructions can be re-ordered by the C++ compiler. My previous comment
about the death of MT programming was rash and poorly expressed. I was more
interested in your idea that somehow processors themselves can re-order
writes to memory in such a way that subsequent reads of that memory will not
yield the new value. I do not think that can happen on any CPU once the
write has been completed, and I do not care how one defines "memory". If
that were the case, then 'x = 5; if x == 5 { etc. }' would fail and so would
procedural computer programming on that machine.

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

OK, I understand your point. You want some C++ semantics for doing lock-free
MT programming. Such semantics would also have to ensure atomicity so that
an assignment to memory couldn't be interrupted by another process in the
middle of the instruction. If you are arguing for lock-free MT versus the
more normal locking mechanisms we all know and love ( or hate ) such as
critical sections, mutexes, semaphores, signalled events etc., please point
me to something I can read which justifies it as a better way to do MT. I do
not get DDJ anymore so I did not see your and Mr. Meyers' article there. I
assume some understanding from that article brought on the request for a
change in C++ to add semantics for lock-free MT.

Edward Diener

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





Author: bouncer@dev.null (Wil Evers)
Date: Sun, 22 Aug 2004 05:14:50 GMT
Raw View
In article <2okpccFbrqqkU1@uni-berlin.de>, Andrei Alexandrescu (See Website
for Email wrote:

> "Wil Evers" <bouncer@dev.null> wrote in message
> news:cg33nf$k48$1@news.cistron.nl...

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

Agreed.  I wasn't thinking about asynchronous thread cancellation; I banned
that from my brain years ago.

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

That's the easy (and obvious) part.  As the moderator suggested: if you're
interested in the hard part, please check the archives of c++-pthreads
mailing list -

  http://www.codesourcery.com/archives/c++-pthreads/threads.html

- Wil

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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 22 Aug 2004 05:37:31 GMT
Raw View
""Lo   c Joly"" <loic.actarus.joly@wanadoo.fr> wrote in message
news:cg82tr$t2e$1@news-reader3.wanadoo.fr...
Andrei Alexandrescu (See Website for Email) wrote:
>>I agree with that if what you say is true, and you do not have to argue
>>further about it. However I am either not following your argument, or
>>multi-threaded computer programming is essentially dead if what you say is
>>irrevocably true. Somehow I do not think the latter can be the case, so do
>>you care to try again ? If not, please point me to some article which
>>explains this. I am not buying it until I am convinced.
>
> 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.

>It is somewhat against my current belief about reordering or observable
behaviour. <

One's understanding should only derive from the standard, which tells
nothing about the issues you mention below.

>If you have the following code :

a=1;
f();
b=2;

And you do not have access to the source code for f(), there is no way
you can knows if reordering the assignements around the call to f()
might change or not the observable behaviour of the program (a and b
might be aliased...).<

That is incorrect. The compiler and linker combo might have access to a lot
of things, including to the "source" code of an already-compiled function.

Then again, the standard doesn't say what's possible and what's not possible
given what's visible and what's not visible. The standard defines observable
behavior for a single-threaded abstract machine. Within the confines of that
machine, everything's fair game.

In particular, newer compilers perform link-time inlining.


Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 22 Aug 2004 06:37:21 GMT
Raw View
""Edward Diener"" <eldiener@earthlink.net> wrote in message
news:uMHVc.30928$nx2.17552@newsread2.news.atl.earthlink.net...
>> [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."]
>
> Regarding your joke, "And the doctor says: So if doing X gives you pain,
> don't do it." But what does that have to do with the price of tea in
> Romania
> <g> ?

:o) The connection of my joke was that I presented three reasons, but the
first one smashed the issue to the ground so vigurously, there's no need for
the other two.

> OK, I very much appreciate your explanation and let us say that the
> instructions can be re-ordered by the C++ compiler. My previous comment
> about the death of MT programming was rash and poorly expressed. I was
> more
> interested in your idea that somehow processors themselves can re-order
> writes to memory in such a way that subsequent reads of that memory will
> not
> yield the new value. I do not think that can happen on any CPU once the
> write has been completed, and I do not care how one defines "memory". If
> that were the case, then 'x = 5; if x == 5 { etc. }' would fail and so
> would
> procedural computer programming on that machine.

That is correct, and I hope I worded things carefully that the reordering is
visible to another thread, not to the current thread. Otherwise... ST itself
would be dead :o).

> OK, I understand your point. You want some C++ semantics for doing
> lock-free
> MT programming. Such semantics would also have to ensure atomicity so that
> an assignment to memory couldn't be interrupted by another process in the
> middle of the instruction. If you are arguing for lock-free MT versus the
> more normal locking mechanisms we all know and love ( or hate ) such as
> critical sections, mutexes, semaphores, signalled events etc., please
> point
> me to something I can read which justifies it as a better way to do MT. I
> do
> not get DDJ anymore so I did not see your and Mr. Meyers' article there. I
> assume some understanding from that article brought on the request for a
> change in C++ to add semantics for lock-free MT.

I am not arguing in favor of lock-free over locked. Execution semantics must
be changed in any case. Granted, the changes are easier to perform if only
giving access to locked programming. But really, if all we'd provide would
be a mutex, a lock, and a thread_start... they'd all laugh at us.

For relevant papers, see:

Maged M. Michael
High Performance Dynamic Lock-Free Hash Tables and List-Based Sets pdf
SPAA 2002 The 14th Annual ACM Symposium on Parallel Algorithms and
Architectures, pages 73-82, August 2002.
http://www.research.ibm.com/people/m/michael/spaa-2002.pdf

and the papers that it cites. Also, Michael's more recent papers
(http://www.research.ibm.com/people/m/michael/pubs.htm) are all very
relevant.


Andrei


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 23 Aug 2004 00:47:21 GMT
Raw View
bouncer@dev.null (Wil Evers) writes:

> In article <2okpccFbrqqkU1@uni-berlin.de>, Andrei Alexandrescu (See Website
> for Email wrote:
>
>> "Wil Evers" <bouncer@dev.null> wrote in message
>> news:cg33nf$k48$1@news.cistron.nl...
>
>>> 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;
>
> Agreed.  I wasn't thinking about asynchronous thread cancellation; I banned
> that from my brain years ago.
>
>> 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.
>
> That's the easy (and obvious) part.  As the moderator suggested: if you're
> interested in the hard part, please check the archives of c++-pthreads
> mailing list -
>
>   http://www.codesourcery.com/archives/c++-pthreads/threads.html
>
> - Wil

The only hard things there are "political," (**) not technical.  The
political difficulties are:

  1. That there's already some precedent somewhere for throwing
     exceptions for thread cancellation from 'C' library functions.
     That's a suboptimal choice at best, but it's hard to swim against
     the tide.

  2. Some people believe strongly that it should be possible to ensure
     that thread cancellation requests can never be ignored and always
     lead to thread termination in finite time.  That's just
     impossible to do in general without corrupting program state
     (i.e. crashing), but these people aren't convinced.

So if someone can tackle the political problems, we can get on with
implementing the obvious <wink> technical solutions.

(**) in quotes because I don't mean to imply anything pejorative

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

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Fri, 20 Aug 2004 23:27:20 GMT
Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2okpccFbrqqkU1@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.

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 00:54:24 GMT
Raw View
"Peter Dimov" <pdimov@gmail.com> wrote in message
news:abefd130.0408201501.7b3093e8@posting.google.com...
> SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website
> for Email)") wrote in message news:<2okpccFbrqqkU1@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 16:41:37 GMT
Raw View
"Roshan Naik" <someone@nowhere.com> wrote in message
news:4124FF31.4D054252@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 16:41:55 GMT
Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:usmaiollw.fsf@boost-consulting.com...
> dietmar_kuehl@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!

Andrei


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





Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Sat, 21 Aug 2004 16:42:36 GMT
Raw View
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:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 16:43:25 GMT
Raw View
"Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
news:gNgHd7MIiIJBFwz2@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 16:43:45 GMT
Raw View
"John Nagle" <nagle@animats.com> wrote in message
news:8x8Vc.6155$656.1985@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.

Andrei


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





Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Sat, 21 Aug 2004 16:45:07 GMT
Raw View
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:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 16:46:24 GMT
Raw View
"Alexander Terekhov" <terekhov@web.de> wrote in message
news:412533CA.82703A04@web.de...
> Well, LL/SC is actually superior to CAS (LL/SC is ABA-proof), but
> is less portable than CAS.  And i386 doesn't have CAS, BTW.

What's wrong with CMPXCHG8?

> 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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 17:00:34 GMT
Raw View
"Peter Dimov" <pdimov@gmail.com> wrote in message
news:abefd130.0408200546.1133f67b@posting.google.com...
> bouncer@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 21 Aug 2004 17:04:35 GMT
Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uhdqzqcrz.fsf@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


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





Author: kuyper@wizard.net (James Kuyper)
Date: Sat, 21 Aug 2004 17:09:25 GMT
Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<4125eeb5$0$214$14726298@news.sunsite.dk>...
> "Wil Evers" <bouncer@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.

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





Author: bouncer@dev.null (Wil Evers)
Date: Sat, 21 Aug 2004 18:18:45 GMT
Raw View
In article <4125eeb5$0$214$14726298@news.sunsite.dk>, Thorsten Ottosen
wrote:

> "Wil Evers" <bouncer@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?

The one that surprised me most is (section 20.3.3, clause 8):

  For templates greater, less, greater_equal, and less_equal, the
  specializations for any pointer type yield a total order, even if
  the builtin operators <, >, <=, >= do not.

I'm sure there are many others.

- Wil

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

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





Author: brangdon@cix.co.uk (Dave Harris)
Date: Sat, 21 Aug 2004 18:18:58 GMT
Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website
for Email)") wrote (abridged):
> > 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.

Isn't it more that they expect the production of a library to clarify what
is needed from the language?

-- Dave Harris, Nottingham, UK

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





Author: bouncer@dev.null (Wil Evers)
Date: Sat, 21 Aug 2004 18:19:08 GMT
Raw View
In article <abefd130.0408200546.1133f67b@posting.google.com>, Peter Dimov
wrote:

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

That could easily be solved by an atomic_traits<> template with
specializations for types that have hardware-supported atomic operations.

[snip]

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

The nasty part is not about what should happen when such an exception is
thrown; it is about where and when these exceptions are thrown.

- Wil

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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 19:01:53 GMT
Raw View
""Balog Pal"" <pasa@lib.hu> wrote in message
news:41246302@andromeda.datanet.hu...
> ""Andrei Alexandrescu (See Website for Email)""
> <SeeWebsiteForEmail@moderncppdesign.com> wrote in message
>
>> 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.

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

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


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





Author: bouncer@dev.null (Wil Evers)
Date: Thu, 19 Aug 2004 22:33:57 GMT
Raw View
In article <2oig7mFb30cmU1@uni-berlin.de>, Andrei Alexandrescu (See Website
for Email wrote:

> "Alexander Terekhov" <terekhov@web.de> wrote in message
> news:4123BD01.BCF1DC67@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]

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 19 Aug 2004 22:34:17 GMT
Raw View
dietmar_kuehl@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 22:34:35 GMT
Raw View
""Lo   c Joly"" <loic.actarus.joly@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


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





Author: eldiener@earthlink.net ("Edward Diener")
Date: Fri, 20 Aug 2004 03:30:59 GMT
Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> ""Edward Diener"" <eldiener@earthlink.net> wrote in message
> news:gtUUc.27242$nx2.6338@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.

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.

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 03:31:30 GMT
Raw View
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:5b15f8fd.0408190513.4317cbbb@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 03:31:49 GMT
Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:un00rqcwl.fsf@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


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 20 Aug 2004 03:35:35 GMT
Raw View
===================================== 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
bouncer@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 16:32:52 GMT
Raw View
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:5b15f8fd.0408190434.76e5c31f@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


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 20 Aug 2004 16:33:05 GMT
Raw View
SeeWebsiteForEmail@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 16:33:15 GMT
Raw View
"Wil Evers" <bouncer@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 16:34:25 GMT
Raw View
""Edward Diener"" <eldiener@earthlink.net> wrote in message
news:KUaVc.3193$2L3.2439@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


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





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Fri, 20 Aug 2004 16:35:58 GMT
Raw View
In article <2oktlmFbos5jU1@uni-berlin.de>, "Andrei Alexandrescu (See
Website for Email)" <SeeWebsiteForEmail@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

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Fri, 20 Aug 2004 16:37:14 GMT
Raw View
bouncer@dev.null (Wil Evers) wrote in message news:<cg33nf$k48$1@news.cistron.nl>...
> In article <2oig7mFb30cmU1@uni-berlin.de>, Andrei Alexandrescu (See Website
> for Email wrote:
>
> > "Alexander Terekhov" <terekhov@web.de> wrote in message
> > news:4123BD01.BCF1DC67@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.

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





Author: pasa@lib.hu ("Balog Pal")
Date: Fri, 20 Aug 2004 16:37:34 GMT
Raw View
""Edward Diener"" <eldiener@earthlink.net> wrote in message
news:KUaVc.3193$2L3.2439@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


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 20 Aug 2004 19:06:25 GMT
Raw View
SeeWebsiteForEmail@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

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





Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Fri, 20 Aug 2004 20:43:30 GMT
Raw View
"Wil Evers" <bouncer@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


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 20 Aug 2004 20:45:00 GMT
Raw View
nagle@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 20:45:43 GMT
Raw View
""Sergey P. Derevyago"" <non-existent@iobox.com> wrote in message
news:4125BE8B.8FAAA40@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


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 20 Aug 2004 23:01:28 GMT
Raw View
nagle@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 23:01:48 GMT
Raw View
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:5b15f8fd.0408190416.392b6ecf@posting.google.com...
> someone@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 23:02:22 GMT
Raw View
""Sergey P. Derevyago"" <non-existent@iobox.com> wrote in message
news:412472B2.C6BFB163@iobox.com...
> C++ is not a niche programming language so it must not copy Java MT
> design.
> IMHO POSIX C++ binding is the way to go.

Java's not niche either, but I won't spread myself too thin.

I agree that a POSIX C++ binding would be good. The problem is, C++ has so
complex semantics, the pthreads people (who are, as a community, less
experts in C++'s subtleties) won't attempt.

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


Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 20 Aug 2004 23:04:54 GMT
Raw View
""Lo   c Joly"" <loic.actarus.joly@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.


Andrei


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 20 Aug 2004 23:05:44 GMT
Raw View
jhyslop@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

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





Author: eldiener@earthlink.net ("Edward Diener")
Date: Thu, 19 Aug 2004 04:00:43 GMT
Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
> ""Craig Henderson"" <"."@eu.uu.net> wrote in message
> news:41235a93$0$20252$ed9e5944@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.

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 04:39:50 GMT
Raw View
"Alexander Terekhov" <terekhov@web.de> wrote in message
news:4123BD01.BCF1DC67@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


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





Author: news@news.astraweb.com ("News Subsystem")
Date: Thu, 19 Aug 2004 04:59:01 GMT
Raw View
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  gregs@trawna.com
  Trawna Publications  http://www.trawna.com/

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





Author: schnitkerAffenschaukel@sigma-c.com (Uwe Schnitker)
Date: Thu, 19 Aug 2004 08:02:07 GMT
Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2ohnh2FasgsbU1@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

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





Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Thu, 19 Aug 2004 14:39:33 GMT
Raw View
"John Nagle" <nagle@animats.com> wrote in message news:bJQUc.7526$iW.416@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


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





Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Thu, 19 Aug 2004 14:42:00 GMT
Raw View
someone@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:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 15:47:54 GMT
Raw View
"Jim Hyslop" <jhyslop@ieee.org> wrote in message
news:4124340A.3050809@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


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





Author: pasa@lib.hu ("Balog Pal")
Date: Thu, 19 Aug 2004 15:48:53 GMT
Raw View
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsiteForEmail@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



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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 16:53:58 GMT
Raw View
"llewelly" <llewelly.at@xmission.dot.com> wrote in message
news:86acwr5ku5.fsf@Zorthluthik.local.bar...
> news@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 18:38:35 GMT
Raw View
""Edward Diener"" <eldiener@earthlink.net> wrote in message
news:gtUUc.27242$nx2.6338@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 18:39:01 GMT
Raw View
""News Subsystem"" <news@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


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





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 19 Aug 2004 18:39:56 GMT
Raw View
In article <30381f67.0408182333.68f1af39@posting.google.com>, Uwe
Schnitker <schnitkerAffenschaukel@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

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





Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Thu, 19 Aug 2004 18:40:05 GMT
Raw View
jhyslop@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:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

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





Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Thu, 19 Aug 2004 18:40:31 GMT
Raw View
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).
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Thu, 19 Aug 2004 18:40:53 GMT
Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2ohmicFasf02U1@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?

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





Author: seh@panix.com ("Steven E. Harris")
Date: Thu, 19 Aug 2004 18:41:32 GMT
Raw View
nagle@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=B9 the settled dust? Surely macros
are one of Lisp's greatest strengths, not a cause for any decline in
popularity or "relevance."


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

--=20
Steven E. Harris

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





Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 19 Aug 2004 18:42:52 GMT
Raw View
SeeWebsiteForEmail@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 23 Aug 2004 02:56:50 GMT
Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:u8yc75o5n.fsf@boost-consulting.com...
> The only hard things there are "political," (**) not technical.  The
> political difficulties are:
>
>  1. That there's already some precedent somewhere for throwing
>     exceptions for thread cancellation from 'C' library functions.
>     That's a suboptimal choice at best, but it's hard to swim against
>     the tide.
>
>  2. Some people believe strongly that it should be possible to ensure
>     that thread cancellation requests can never be ignored and always
>     lead to thread termination in finite time.  That's just
>     impossible to do in general without corrupting program state
>     (i.e. crashing), but these people aren't convinced.
>
> So if someone can tackle the political problems, we can get on with
> implementing the obvious <wink> technical solutions.

I guess the hard part is to present people under (2) a viable compromise.

I believe what's reasonable and doable is:

a) Any thread API function (such as sleeping, locking a mutex, waiting for
an asynchronous result) will throw an exception when thread cancelation has
been requested. This way, a thread that has proper exception handling and
uses some synchronization routine will finish properly. I wonder if CAS
should be part of this group... what are other people's thoughts?

b) A thread that hangs in a loop without calling any thread API function
will not be stoppable.

I think that's entirely reasonable. After all, you can't claim peaceful
termination of a ST process that just hangs in a loop.


Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 23 Aug 2004 15:50:13 GMT
Raw View
"Roshan Naik" <someone@nowhere.com> wrote in message
news:4126BE7A.93C58FF2@nowhere.com...
> Question 1: how far does volatile go ?
> -------------------
> wouldn't ...
>
>    (volatile int) b = 6;
>    (volatile int) a = 5;
>
> fix the problem you mention ?

You mean:

(volatile int&) b = 6;
(volatile int&) a = 5;

It will fix the problem in the current thread, in that now you are
guaranteed that in the current thread b will be assigned to before a. It
won't guarantee (1) that other threads will see the same order; (2) the
non-volatile reads and writes are in any way ordered, even in the current
thread. The article (second part, DDJ Aug 2004) mentions both problems.

> I would imagine that compilers (today) aren't going to place a memory
> barrier between the
> statements
> (in either of above case) ...but should it for MT programs ? Perhaps
> yes(in my limited
> wisdom).

That would slow down the program down to a crawl.

> If not then how is volatile (or output functions) being guaranteeing
> observable behavior today
> ?

Depends on the platform, the standard says.

> Aside from the instruction(memory ?) ordering problem the DDj article
> pointed out (as I
> understand)
> that updates to data (pInstance) on one processor are not necessarily
> visible to other
> processor's.
>
> So  does that mean two independent problems...
>   - instruction ordering,
>   - memory (or cache ?) coherency
>   - (and maybe a third..) memory ordering
>
> ?

It's the memory reads and writes that are important. The issues you mention
are all causes of the lack of causality between reads and writes among
various threads, which is causing all of the headache.

> Question 3 : instruction v/s  memory ordering
> ------------------------------------------------------
>
> Now, very often i see people referring to "memory ordering" being referred
> to and then
> providing
> examples dealing with instruction ordering.
>
> Cuz (as I understand) regardless of the compiler or processor doing things
> "right", the memory
>
> subsystem has its own mind on how those updates will be really done. So
> telling the processor
> anything
> seems like waste. I am thinking perhaps these two terms (instruction /
> memory ordering )
> should be used more carefully...and precisely.

It's not that bad. Instruction ordering is irrelevant as long as it doesn't
produce reorderings of reads and writes. Most of the time, the compiler does
instruction reordering. Then there comes the hardware that reorders memory
accesses again.

Mentally, I think of it that way (and simplify my life a lot in the
process): Between your source code and the electrons there is an entity that
reorders all it wants as long as it stays within observable behavior. Then I
need to only focus on understanding observable behavior and (according to
it) what legal executions of my code are possible.

> So is it right to say that asking the processor to update memory in a
> certain order has no
> bearing
> on how the memory is finally updated by the memory subsystem in a
> multiprocessor subsystem ?

That is correct (on some systems). Historically, the speed gap inside the
memory hierarhcy (processor registers - L1 cache - L2 cache - DRAM - disk)
is increasing exponentially. (By 2010, if the current trends go forth,
formatting an HDD will take a week. I guess new disk drivers will format
on-the-fly as needed.) Therefore, drastic measures must be taken to
streamline communication within the memory hierarchy. Burst updates from
cache to RAM are an effective one.


Andrei


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





Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 23 Aug 2004 15:51:44 GMT
Raw View
pasa@lib.hu ("Balog Pal") writes:

> Even if all that happes is a 'well, we see the first step, we'd like to see
> some more fleshed out by the next meeting', is a great progress.  Unless I
> musunderstood David Abrahams is ready to take over organizing the
> development.

Hahahahahahahahahaha!

Well, so far I'm intrigued by the problem and that's about all.

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

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





Author: pdimov@gmail.com (Peter Dimov)
Date: Mon, 23 Aug 2004 15:56:03 GMT
Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<cg8l72$pt3$1@news.astound.net>...
> Alexander Terekhov wrote:
> > [...]
> > Why would you need some barrier on increment?
>
> Thread 1 loads count from memory and increments it.  It gets written to
> cache but not to memory [yet].  Thread 2, on a different processor,
> loads the same count from memory and increments it.  They each write the
> same value to memory.  Are you saying this won't happen, and why?

It won't happen because the increment is still atomic. A memory
barrier gives much stronger guarantees:

thread 1:

  write X
  atomic-inc Y

thread 2:

  atomic-inc Y
  read X

With an increment that is also a (full) memory barrier, thread 2 will
see the value of X that thread 1 wrote.

I think. :-)

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 23 Aug 2004 17:49:42 GMT
Raw View
"John Nagle" <nagle@animats.com> wrote in message
news:dVoWc.7150$QJ3.2685@newssvr21.news.prodigy.com...
> Sergey P. Derevyago wrote:
>> Andrei, this statement can easily be inverted: MT programming has so
>> complex
>> semantics, the C++ people won't attempt...
>> We're trying to introduce some standard MT support into C++. If some
>> "C++'s
>> subtleties" don't allow us to introduce good MT support we'd better throw
>> them
>> out of C++ rather than throw the pthreads people out of the process.
>
>     Agreed.  Threads are necessary.  The more elaborate forms of
> "generic programming" are optional.  If push comes to shove, it's
> clear what has to go.

Whoa, whoa. Hold it right there. You can't remove anything related to
generic programming :o).

Now seriously, I see GP and MT largely orthogonal and possibly
complementary, so fundamentally I don't see a way in which they could
interfere.


Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 23 Aug 2004 22:07:25 GMT
Raw View
"Roshan Naik" <someone@nowhere.com> wrote in message
news:412A4F93.9EAE31F4@nowhere.com...
>> "Roshan Naik" <someone@nowhere.com> wrote in message
>> news:4126BE7A.93C58FF2@nowhere.com...
>> > Question 1: how far does volatile go ?
>> > -------------------
>> > wouldn't ...
>> >
>> >    (volatile int) b = 6;
>> >    (volatile int) a = 5;
>> >
>> > fix the problem you mention ?
>>
>> You mean:
>>
>> (volatile int&) b = 6;
>> (volatile int&) a = 5;
>>
>
> Hmm ! So i guess this idiom wont work in C. As I understand C
> doesnt have references. So it may need some more acrobatics
> if only some reads and writes to the variables need to be deemed
> observable behavior.

It's trivial to transform the code above to use pointers.

> "Andrei Alexandrescu (See Website for Email)" wrote:
>
>> It will fix the problem in the current thread, in that now you are
>> guaranteed that in the current thread b will be assigned to before a. It
>> won't guarantee (1) that other threads will see the same order; (2) the
>> non-volatile reads and writes are in any way ordered, even in the current
>> thread. The article (second part, DDJ Aug 2004) mentions both problems.
>
> Yes. I read those two conlcusions (1 & 2). But the meaning of (1) wasnt
> clear
> at all due to lack of a precise example. Do you mean other threads
> executing the
>
> same (volatile marked) portion of code or other threads executing some
> other
> piece
> of code ? If so how can that come about ? I have been trying to warp my
> mind
> trying
> to think of what that means.

It's very hard to talk about what threads could do in a language that has a
single-threaded abstract machine. We can contemplate our navels all year
long. This ends the whole discussion on C++ volatile's merits rather
abruptly.

In short: volatile won't cut it. At all. Java 1 tried to redefine it so that
it does. It still didn't. Java 1.5 defined one that does. (But that's too
restrictive.)

> Hopefully when you read this email message the text is in the same order
> as I
> typed it

I did. I snipped most of it because it drives from an untrue conjecture.
Volatile won't help.


Andrei


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Wed, 18 Aug 2004 05:36:48 GMT
Raw View
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-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pasa@lib.hu ("Balog Pal")
Date: Wed, 18 Aug 2004 14:17:52 GMT
Raw View
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsiteForEmail@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.



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





Author: "."@eu.uu.net ("Craig Henderson")
Date: Wed, 18 Aug 2004 14:43:55 GMT
Raw View
""Andrei Alexandrescu (See Website for Email)""
<SeeWebsiteForEmail@moderncppdesign.com> wrote in message
news:2ofbepFa2tpoU1@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


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





Author: tom_usenet@hotmail.com (tom_usenet)
Date: Wed, 18 Aug 2004 16:52:24 GMT
Raw View
On Wed, 18 Aug 2004 05:36:48 GMT,
SeeWebsiteForEmail@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

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





Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Wed, 18 Aug 2004 16:54:23 GMT
Raw View
""Balog Pal"" <pasa@lib.hu> wrote in message news:412356f9@andromeda.datanet.hu...
| ""Andrei Alexandrescu (See Website for Email)""
| <SeeWebsiteForEmail@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


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





Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Wed, 18 Aug 2004 17:17:20 GMT
Raw View
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:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

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





Author: seh@panix.com ("Steven E. Harris")
Date: Wed, 18 Aug 2004 17:20:47 GMT
Raw View
SeeWebsiteForEmail@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Wed, 18 Aug 2004 18:54:16 GMT
Raw View
""Craig Henderson"" <"."@eu.uu.net> wrote in message
news:41235a93$0$20252$ed9e5944@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Wed, 18 Aug 2004 18:54:32 GMT
Raw View
"tom_usenet" <tom_usenet@hotmail.com> wrote in message
news:6uh6i0tbr0j0urbnocg5t9ucb5gfpr8gr3@4ax.com...
> On Wed, 18 Aug 2004 05:36:48 GMT,
> SeeWebsiteForEmail@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Wed, 18 Aug 2004 18:54:41 GMT
Raw View
""Thorsten Ottosen"" <nesotto@cs.auc.dk> wrote in message
news:4123699d$0$73951$14726298@news.sunsite.dk...
> ""Balog Pal"" <pasa@lib.hu> wrote in message
> news:412356f9@andromeda.datanet.hu...
> | ""Andrei Alexandrescu (See Website for Email)""
> | <SeeWebsiteForEmail@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


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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Wed, 18 Aug 2004 20:45:25 GMT
Raw View
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:5b15f8fd.0408180300.6413ef48@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


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





Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Wed, 18 Aug 2004 23:06:07 GMT
Raw View
In article <2ohmicFasf02U1@uni-berlin.de>,
 SeeWebsiteForEmail@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

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





Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 01:40:25 GMT
Raw View
""Sergey P. Derevyago"" <non-existent@iobox.com> wrote in message
news:41233B8F.1ACAAB6E@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


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





Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Thu, 19 Aug 2004 01:48:56 GMT
Raw View
| ""Thorsten Ottosen"" <nesotto@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


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