public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "qrczak at knm dot org dot pl" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/20099] -pthreads should imply -fno-threadsafe-statics
Date: Mon, 21 Feb 2005 12:04:00 -0000	[thread overview]
Message-ID: <20050220214309.17205.qmail@sourceware.org> (raw)
In-Reply-To: <20050220004607.20099.davids@webmaster.com>


------- Additional Comments From qrczak at knm dot org dot pl  2005-02-20 21:43 -------
> >Static locals in C++ are an equivalent to pthread_once in C/POSIX.
> 
> Even in the single-threaded case, C++ leaves it undefined what happens if you
> reenter a function that invokes a static initializer from that static
> initializer. To argue that this means it should be defined for the
> multi-threaded case is absurd.

There is a fundamental difference between the second access made from the same
or from a different thread.

Access from the same thread means that there is a contradiction in the program:
the data depends on itself. This is always a bug. The implementation may be
helpful and detect this (gcc4 throws exception recursive_init), but in general
undefined behavior is consistent with the philosophy of C/C++. The same applies
to recursive pthread_once and to a recursive mutex (except that with mutexes you
have an option to allow recursive locking).

Access from a different thread most often means that the timing was unfortunate
and two threads happened to try to perform initialization on first use almost
simultaneously, closer in time than the time needed for the initialization.
While there is a remote possibility that the threads were not independent, the
second thread was a worker spawned by the first one, the first one will wait for
the second one to finish its work, the second one will wait for the first one to
complete the initialization, and we will have a deadlock - almost always this is
not the case, this is just unfortunate timing, and the first thread will
complete initialization while the second one is waiting. It makes no sense to
optimize for the case of a bug which causes undefined behavior, so the language
assumes that there is no bug and arranges the program to run according to the
obvious intended semantics of independent threads simultaneously accessing a
lazily initialized variable: the second thread waits for the first to complete
the initialization, as if it got there some time later. The same applies to
pthread_once and to a mutex.

Obviously the C++ standard sees only the first scenario, a single thread, so it
just declares reentering a static local initializer invalid. But there is no
conceptual problem with "reentering" the initializer from a different thread -
it just have to wait until the first one finishes. A hypothetical multithreaded
C++ should state this as the semantics of static locals.

Look at the semantics of Glasgow Haskell which combines lazy evaluation with
threads. When the given lazy variable is reentered, if this is the same thread
which started computing its value, we have a cyclic dependency and the runtime
detects this as an error; and if this is a different thread, the second thread
waits for the first one to complete computing the value, because almost always
this is just an unfortunate timing and this is the obvious way to resolve it.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20099


  parent reply	other threads:[~2005-02-20 21:43 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-20 13:52 [Bug c++/20099] New: " davids at webmaster dot com
2005-02-20 14:17 ` [Bug c++/20099] " pinskia at gcc dot gnu dot org
2005-02-20 14:18 ` pinskia at gcc dot gnu dot org
2005-02-20 14:18 ` davids at webmaster dot com
2005-02-20 14:22 ` pinskia at gcc dot gnu dot org
2005-02-20 15:07 ` davids at webmaster dot com
2005-02-20 15:11 ` davids at webmaster dot com
2005-02-20 15:37 ` pinskia at gcc dot gnu dot org
2005-02-20 17:07 ` qrczak at knm dot org dot pl
2005-02-20 17:15 ` davids at webmaster dot com
2005-02-20 18:12 ` qrczak at knm dot org dot pl
2005-02-21  9:29 ` davids at webmaster dot com
2005-02-21 12:04 ` qrczak at knm dot org dot pl [this message]
2005-02-21 15:45 ` gniccolai at yahoo dot com
2005-02-21 16:34 ` davids at webmaster dot com
2005-02-22 15:59 ` gniccolai at yahoo dot com
2005-02-23 11:55 ` davids at webmaster dot com
2005-02-23 11:57 ` qrczak at knm dot org dot pl
2005-02-23 12:26 ` pinskia at gcc dot gnu dot org
2005-02-23 12:28 ` davids at webmaster dot com
2005-02-24 15:28 ` gniccolai at yahoo dot com
2005-02-24 20:00 ` gniccolai at yahoo dot com
2005-02-24 22:02 ` qrczak at knm dot org dot pl
2005-02-25  1:37 ` davids at webmaster dot com
2005-02-25  1:41 ` qrczak at knm dot org dot pl
2005-02-25  3:30 ` davids at webmaster dot com
2005-02-25  4:37 ` qrczak at knm dot org dot pl
2005-02-25  8:06 ` davids at webmaster dot com

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050220214309.17205.qmail@sourceware.org \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).