Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Feb 2023 18:45:06 -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:  <72CD283D-8669-4574-B9DA-3CEEB198FFF5@yahoo.com>
In-Reply-To: <EBED3F8F-00B1-4F77-88B1-5465774CE393@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> <EBED3F8F-00B1-4F77-88B1-5465774CE393@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
[I've updated the program so that which thread is reported
in the output and the scale of each value indicates which
thread the value is from (unless it runs for a very long
time). Thread 0 creates small values (unless it runs for a
very long time), thread 1: creates only huge values. Values
from the wrong thread are reported.]

On Feb 16, 2023, at 15:31, Mark Millard <marklmi@yahoo.com> wrote:

> 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.
>=20
> 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.
>=20
> 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
Thread 1: 34018092.000000 !=3D 4503599674389816
^C
# ./a.out
Thread 0: 4503599680497650.000000 !=3D 38453432
^C

So: the floating point values (left hand sides)
are the ones from the wrong thread and the
unsigned long long values (right hand sides) are
from the correct thread. So far this has been
uniform.

Also: which thread gets the odd value varies.


The new C++ source is:

// # g++12 -std=3Dc++20 -pedantic -g -O3 -pthread =
-Wl,-rpath=3D/usr/local/lib/gcc12 dbl_and_ull_multithread.cpp
// # ./a.out
// Thread [01]: double_value !=3D unsigned_long_long_value=20
// 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 int which_thr, unsigned long long n_init)
            {
                unsigned long long n       { n_init };
                double             n_as_dbl=3D n;

                while (n < bound) {
                    if (n_as_dbl !=3D (double)n) {
                        std::osyncstream output{std::cout};
                        output << "Thread "
                               << std::to_string(which_thr)
                               << ": "
                               << 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
                  , 0u
                  , 0ull
                  )
    };
    auto thread_1 {
        std::async( std::launch::async
                  , the_job
                  , 1u
                  , bound/2u
                  )
    };
    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?72CD283D-8669-4574-B9DA-3CEEB198FFF5>