Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Feb 2023 15:31:13 -0800
From:      Mark Millard <marklmi@yahoo.com>
To:        "kd@freebsd.org" <kd@FreeBSD.org>, "wma@freebsd.org" <wma@FreeBSD.org>, dev-commits-src-main@freebsd.org
Cc:        Warner Losh <imp@bsdimp.com>
Subject:   Re: git: 6926e2699ae5 - main - arm: Add support for using VFP in kernel [new: bad floating point data with multi-threading, not a crash]
Message-ID:  <EBED3F8F-00B1-4F77-88B1-5465774CE393@yahoo.com>
In-Reply-To: <402AEA29-B895-4031-99A0-876A39C02157@yahoo.com>
References:  <3A143148-895F-472B-9AFB-5F1AA0FD1FA0@yahoo.com> <782B252E-60AC-4036-BD74-46B95A31B337@yahoo.com> <4F9A3687-9577-4419-AE1B-D02A4C9212ED@yahoo.com> <402AEA29-B895-4031-99A0-876A39C02157@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
I start this message as independent of the prior crash reports:
this is not a crash report. It is a messed-up floating point
data report instead.

I have a simple C++ program that creates 2 independent threads,
each working on just local variables, where it appears that
after a while one thread ends up with a floating point value
from the other thread.

The two threads each just have loops incrementing a unsigned
long long and a double by 1 in the range where no information
is lost, initializing to zero. The cross-check for failure is
if it finds an example of n_as_dbl !=3D (double)n . An example
build-then-run showing a failure is:

# g++12 -std=3Dc++20 -pedantic -g -O3 -pthread =
-Wl,-rpath=3D/usr/local/lib/gcc12 dbl_and_ull_multithread.cpp
# ./a.out
95534435.000000 !=3D 95531411
^C

(The program would run for a very long time unless both threads
observe such a failure in a shorter time frame. So the normal
exit is to use control-C (SIGINT).)

So far, the values printed are always similar instead of
random data showing up. This is part of what suggests
that data from the wrong thread has shown up.



Because libc++ does not yet have <syncstream> I build with using
libstdc++. I have demonstrated the problem via libc++ (clang++
and g++12) as well, calling std::abort instead of outputting.
(But that crashes armv7 FreeBSD during the attempt to produce
the core file.)

The C++ program source and how-to-use-comment is:
(whitespace details might not be preserved)

// # g++12 -std=3Dc++20 -pedantic -g -O3 -pthread =
-Wl,-rpath=3D/usr/local/lib/gcc12 dbl_and_ull_multithread.cpp
// # ./a.out
// double_value !=3D unsigned_long_long_value
// Use control-C to stop it.

#include <limits>     // std::numeric_limits
#include <future>     // std::future, std::async, std::launch::async
#include <string>     // std::to_string
#include <syncstream> // std::osyncstream
#include <iostream>   // std::cout

int main(void) {

    static_assert(std::numeric_limits<double>::radix=3D=3D2,"double's =
radix is not 2 and is unhandled");

    constexpr unsigned int ull_width { std::numeric_limits<unsigned long =
long>::digits };
    constexpr unsigned int dbl_width { =
std::numeric_limits<double>::digits };
    constexpr unsigned int use_width { (dbl_width<ull_width) ? dbl_width =
: ull_width };

    constexpr unsigned long long bound { (1ull<<use_width)-1ull };

    auto the_job {
        [](){
                unsigned long long n       { 0ull };
                double             n_as_dbl=3D n;

                while (n < bound) {
                    if (n_as_dbl !=3D (double)n) {
                        std::osyncstream output{std::cout};
                        output << std::to_string(n_as_dbl) // =
questionable if still same?
                               << " !=3D "
                               << std::to_string(n)
                               << "\n";
                        break;
                    }

                    n++;
                    n_as_dbl+=3D 1.0;
                }
            }
    };

    auto thread_0 {
        std::async( std::launch::async
                  , the_job
                  )
    };
    auto thread_1 {
        std::async( std::launch::async
                  , the_job
                  )
    };
    thread_0.wait();
    thread_1.wait();

    return 0;
}

=3D=3D=3D
Mark Millard
marklmi at yahoo.com




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?EBED3F8F-00B1-4F77-88B1-5465774CE393>