mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-07 10:54:01 +00:00
Revert "[libc++] Speed up classic locale (#72112)"
Looks like it broke the ASAN build: https://lab.llvm.org/buildbot/#/builders/168/builds/17053/steps/9/logs/stdio
This reverts commit f8afc53d64
.
This commit is contained in:
parent
983a2757b0
commit
4e0c48b907
@ -1,12 +1,11 @@
|
|||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
TEST_NOINLINE double istream_numbers();
|
TEST_NOINLINE double istream_numbers();
|
||||||
|
|
||||||
double istream_numbers(std::locale* loc) {
|
double istream_numbers() {
|
||||||
const char* a[] = {"-6 69 -71 2.4882e-02 -100 101 -2.00005 5000000 -50000000",
|
const char* a[] = {"-6 69 -71 2.4882e-02 -100 101 -2.00005 5000000 -50000000",
|
||||||
"-25 71 7 -9.3262e+01 -100 101 -2.00005 5000000 -50000000",
|
"-25 71 7 -9.3262e+01 -100 101 -2.00005 5000000 -50000000",
|
||||||
"-14 53 46 -6.7026e-02 -100 101 -2.00005 5000000 -50000000"};
|
"-14 53 46 -6.7026e-02 -100 101 -2.00005 5000000 -50000000"};
|
||||||
@ -15,73 +14,17 @@ double istream_numbers(std::locale* loc) {
|
|||||||
double f1 = 0.0, f2 = 0.0, q = 0.0;
|
double f1 = 0.0, f2 = 0.0, q = 0.0;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
std::istringstream s(a[i]);
|
std::istringstream s(a[i]);
|
||||||
if (loc)
|
|
||||||
s.imbue(*loc);
|
|
||||||
s >> a1 >> a2 >> a3 >> f1 >> a4 >> a5 >> f2 >> a6 >> a7;
|
s >> a1 >> a2 >> a3 >> f1 >> a4 >> a5 >> f2 >> a6 >> a7;
|
||||||
q += (a1 + a2 + a3 + a4 + a5 + a6 + a7 + f1 + f2) / 1000000;
|
q += (a1 + a2 + a3 + a4 + a5 + a6 + a7 + f1 + f2) / 1000000;
|
||||||
}
|
}
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocaleSelector {
|
|
||||||
std::locale* imbue;
|
|
||||||
std::locale old;
|
|
||||||
static std::mutex mutex;
|
|
||||||
|
|
||||||
LocaleSelector(benchmark::State& state) {
|
|
||||||
std::lock_guard guard(mutex);
|
|
||||||
switch (state.range(0)) {
|
|
||||||
case 0: {
|
|
||||||
old = std::locale::global(std::locale::classic());
|
|
||||||
imbue = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1: {
|
|
||||||
old = std::locale::global(std::locale::classic());
|
|
||||||
thread_local std::locale loc("en_US.UTF-8");
|
|
||||||
imbue = &loc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
old = std::locale::global(std::locale::classic());
|
|
||||||
static std::locale loc("en_US.UTF-8");
|
|
||||||
imbue = &loc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
old = std::locale::global(std::locale("en_US.UTF-8"));
|
|
||||||
imbue = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~LocaleSelector() {
|
|
||||||
std::lock_guard guard(mutex);
|
|
||||||
std::locale::global(old);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::mutex LocaleSelector::mutex;
|
|
||||||
|
|
||||||
static void BM_Istream_numbers(benchmark::State& state) {
|
static void BM_Istream_numbers(benchmark::State& state) {
|
||||||
LocaleSelector sel(state);
|
|
||||||
double i = 0;
|
double i = 0;
|
||||||
while (state.KeepRunning())
|
while (state.KeepRunning())
|
||||||
benchmark::DoNotOptimize(i += istream_numbers(sel.imbue));
|
benchmark::DoNotOptimize(i += istream_numbers());
|
||||||
}
|
}
|
||||||
BENCHMARK(BM_Istream_numbers)->DenseRange(0, 3)->UseRealTime()->Threads(1)->ThreadPerCpu();
|
|
||||||
|
|
||||||
static void BM_Ostream_number(benchmark::State& state) {
|
|
||||||
LocaleSelector sel(state);
|
|
||||||
while (state.KeepRunning()) {
|
|
||||||
std::ostringstream ss;
|
|
||||||
if (sel.imbue)
|
|
||||||
ss.imbue(*sel.imbue);
|
|
||||||
ss << 0;
|
|
||||||
benchmark::DoNotOptimize(ss.str().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(BM_Ostream_number)->DenseRange(0, 3)->UseRealTime()->Threads(1)->ThreadPerCpu();
|
|
||||||
|
|
||||||
|
BENCHMARK(BM_Istream_numbers)->RangeMultiplier(2)->Range(1024, 4096);
|
||||||
BENCHMARK_MAIN();
|
BENCHMARK_MAIN();
|
||||||
|
@ -849,7 +849,6 @@ set(files
|
|||||||
__utility/integer_sequence.h
|
__utility/integer_sequence.h
|
||||||
__utility/is_pointer_in_range.h
|
__utility/is_pointer_in_range.h
|
||||||
__utility/move.h
|
__utility/move.h
|
||||||
__utility/no_destroy.h
|
|
||||||
__utility/pair.h
|
__utility/pair.h
|
||||||
__utility/piecewise_construct.h
|
__utility/piecewise_construct.h
|
||||||
__utility/priority_tag.h
|
__utility/priority_tag.h
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <__memory/shared_ptr.h> // __shared_count
|
#include <__memory/shared_ptr.h> // __shared_count
|
||||||
#include <__mutex/once_flag.h>
|
#include <__mutex/once_flag.h>
|
||||||
#include <__type_traits/make_unsigned.h>
|
#include <__type_traits/make_unsigned.h>
|
||||||
#include <__utility/no_destroy.h>
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef _LIBCPP___UTILITY_NO_DESTROY_H
|
|
||||||
#define _LIBCPP___UTILITY_NO_DESTROY_H
|
|
||||||
|
|
||||||
#include <__config>
|
|
||||||
#include <__utility/forward.h>
|
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
||||||
# pragma GCC system_header
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
||||||
|
|
||||||
struct __uninitialized_tag {};
|
|
||||||
|
|
||||||
// This class stores an object of type _Tp but never destroys it.
|
|
||||||
//
|
|
||||||
// This is akin to using __attribute__((no_destroy)), except that it is possible
|
|
||||||
// to control the lifetime of the object with more flexibility by deciding e.g.
|
|
||||||
// whether to initialize the object at construction or to defer to a later
|
|
||||||
// initialization using __emplace.
|
|
||||||
template <class _Tp>
|
|
||||||
struct __no_destroy {
|
|
||||||
_LIBCPP_HIDE_FROM_ABI explicit __no_destroy(__uninitialized_tag) {}
|
|
||||||
_LIBCPP_HIDE_FROM_ABI ~__no_destroy() {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... _Args>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI explicit __no_destroy(_Args&&... __args) : __obj_(std::forward<_Args>(__args)...) {}
|
|
||||||
|
|
||||||
template <class... _Args>
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp& __emplace(_Args&&... __args) {
|
|
||||||
new (&__obj_) _Tp(std::forward<_Args>(__args)...);
|
|
||||||
return __obj_;
|
|
||||||
}
|
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp& __get() { return __obj_; }
|
|
||||||
_LIBCPP_HIDE_FROM_ABI _Tp const& __get() const { return __obj_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
union {
|
|
||||||
_Tp __obj_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
|
||||||
|
|
||||||
#endif // _LIBCPP___UTILITY_NO_DESTROY_H
|
|
@ -2042,7 +2042,6 @@ module std_private_utility_move [system] {
|
|||||||
export std_private_type_traits_is_nothrow_move_constructible
|
export std_private_type_traits_is_nothrow_move_constructible
|
||||||
export std_private_type_traits_remove_reference
|
export std_private_type_traits_remove_reference
|
||||||
}
|
}
|
||||||
module std_private_utility_no_destroy [system] { header "__utility/no_destroy.h" }
|
|
||||||
module std_private_utility_pair [system] {
|
module std_private_utility_pair [system] {
|
||||||
header "__utility/pair.h"
|
header "__utility/pair.h"
|
||||||
export std_private_ranges_subrange_fwd
|
export std_private_ranges_subrange_fwd
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include <__utility/no_destroy.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
@ -82,8 +81,9 @@ locale_t __cloc() {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct releaser {
|
struct release
|
||||||
void operator()(locale::facet* p) { p->__release_shared(); }
|
{
|
||||||
|
void operator()(locale::facet* p) {p->__release_shared();}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
@ -155,11 +155,7 @@ public:
|
|||||||
{return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
|
{return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
|
||||||
const locale::facet* use_facet(long id) const;
|
const locale::facet* use_facet(long id) const;
|
||||||
|
|
||||||
void acquire();
|
private:
|
||||||
void release();
|
|
||||||
static __no_destroy<__imp> classic_locale_imp_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void install(facet* f, long id);
|
void install(facet* f, long id);
|
||||||
template <class F> void install(F* f) {install(f, f->id.__get());}
|
template <class F> void install(F* f) {install(f, f->id.__get());}
|
||||||
template <class F> void install_from(const __imp& other);
|
template <class F> void install_from(const __imp& other);
|
||||||
@ -504,7 +500,7 @@ locale::__imp::__imp(const __imp& other, facet* f, long id)
|
|||||||
name_("*")
|
name_("*")
|
||||||
{
|
{
|
||||||
f->__add_shared();
|
f->__add_shared();
|
||||||
unique_ptr<facet, releaser> hold(f);
|
unique_ptr<facet, release> hold(f);
|
||||||
facets_ = other.facets_;
|
facets_ = other.facets_;
|
||||||
for (unsigned i = 0; i < other.facets_.size(); ++i)
|
for (unsigned i = 0; i < other.facets_.size(); ++i)
|
||||||
if (facets_[i])
|
if (facets_[i])
|
||||||
@ -523,7 +519,7 @@ void
|
|||||||
locale::__imp::install(facet* f, long id)
|
locale::__imp::install(facet* f, long id)
|
||||||
{
|
{
|
||||||
f->__add_shared();
|
f->__add_shared();
|
||||||
unique_ptr<facet, releaser> hold(f);
|
unique_ptr<facet, release> hold(f);
|
||||||
if (static_cast<size_t>(id) >= facets_.size())
|
if (static_cast<size_t>(id) >= facets_.size())
|
||||||
facets_.resize(static_cast<size_t>(id+1));
|
facets_.resize(static_cast<size_t>(id+1));
|
||||||
if (facets_[static_cast<size_t>(id)])
|
if (facets_[static_cast<size_t>(id)])
|
||||||
@ -541,78 +537,89 @@ locale::__imp::use_facet(long id) const
|
|||||||
|
|
||||||
// locale
|
// locale
|
||||||
|
|
||||||
// We don't do reference counting on the classic locale.
|
// This class basically implements __attribute__((no_destroy)), which isn't supported
|
||||||
// It's never destroyed anyway, but atomic reference counting may be very
|
// by GCC as of writing this.
|
||||||
// expensive in parallel applications. The classic locale is used by default
|
template <class T>
|
||||||
// in all streams. Note: if a new global locale is installed, then we lose
|
struct __no_destroy {
|
||||||
// the benefit of no reference counting.
|
template <class... Args>
|
||||||
__no_destroy<locale::__imp> locale::__imp::classic_locale_imp_(__uninitialized_tag{}); // initialized below in classic()
|
explicit __no_destroy(Args&&... args) {
|
||||||
|
T* obj = reinterpret_cast<T*>(&buf);
|
||||||
|
new (obj) T(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
T& get() { return *reinterpret_cast<T*>(&buf); }
|
||||||
|
T const& get() const { return *reinterpret_cast<T const*>(&buf); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
alignas(T) byte buf[sizeof(T)];
|
||||||
|
};
|
||||||
|
|
||||||
const locale& locale::classic() {
|
const locale& locale::classic() {
|
||||||
static const __no_destroy<locale> classic_locale(__private_tag{}, [] {
|
static const __no_destroy<locale> c(__private_tag{}, &make<__imp>(1u));
|
||||||
// executed exactly once on first initialization of `classic_locale`
|
return c.get();
|
||||||
locale::__imp::classic_locale_imp_.__emplace(1u);
|
|
||||||
return &locale::__imp::classic_locale_imp_.__get();
|
|
||||||
}());
|
|
||||||
return classic_locale.__get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
locale& locale::__global() {
|
locale& locale::__global() {
|
||||||
static __no_destroy<locale> g(locale::classic());
|
static __no_destroy<locale> g(locale::classic());
|
||||||
return g.__get();
|
return g.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void locale::__imp::acquire() {
|
locale::locale() noexcept
|
||||||
if (this != &locale::__imp::classic_locale_imp_.__get())
|
: __locale_(__global().__locale_)
|
||||||
__add_shared();
|
{
|
||||||
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
void locale::__imp::release() {
|
locale::locale(const locale& l) noexcept
|
||||||
if (this != &locale::__imp::classic_locale_imp_.__get())
|
: __locale_(l.__locale_)
|
||||||
__release_shared();
|
{
|
||||||
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
locale::locale() noexcept : __locale_(__global().__locale_) { __locale_->acquire(); }
|
locale::~locale()
|
||||||
|
{
|
||||||
locale::locale(const locale& l) noexcept : __locale_(l.__locale_) { __locale_->acquire(); }
|
__locale_->__release_shared();
|
||||||
|
}
|
||||||
locale::~locale() { __locale_->release(); }
|
|
||||||
|
|
||||||
const locale&
|
const locale&
|
||||||
locale::operator=(const locale& other) noexcept
|
locale::operator=(const locale& other) noexcept
|
||||||
{
|
{
|
||||||
other.__locale_->acquire();
|
other.__locale_->__add_shared();
|
||||||
__locale_->release();
|
__locale_->__release_shared();
|
||||||
__locale_ = other.__locale_;
|
__locale_ = other.__locale_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
locale::locale(const char* name)
|
locale::locale(const char* name)
|
||||||
: __locale_(name ? new __imp(name)
|
: __locale_(name ? new __imp(name)
|
||||||
: (__throw_runtime_error("locale constructed with null"), nullptr))
|
: (__throw_runtime_error("locale constructed with null"), nullptr))
|
||||||
{
|
{
|
||||||
__locale_->acquire();
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
locale::locale(const string& name) : __locale_(new __imp(name)) { __locale_->acquire(); }
|
locale::locale(const string& name)
|
||||||
|
: __locale_(new __imp(name))
|
||||||
|
{
|
||||||
|
__locale_->__add_shared();
|
||||||
|
}
|
||||||
|
|
||||||
locale::locale(const locale& other, const char* name, category c)
|
locale::locale(const locale& other, const char* name, category c)
|
||||||
: __locale_(name ? new __imp(*other.__locale_, name, c)
|
: __locale_(name ? new __imp(*other.__locale_, name, c)
|
||||||
: (__throw_runtime_error("locale constructed with null"), nullptr))
|
: (__throw_runtime_error("locale constructed with null"), nullptr))
|
||||||
{
|
{
|
||||||
__locale_->acquire();
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
locale::locale(const locale& other, const string& name, category c)
|
locale::locale(const locale& other, const string& name, category c)
|
||||||
: __locale_(new __imp(*other.__locale_, name, c))
|
: __locale_(new __imp(*other.__locale_, name, c))
|
||||||
{
|
{
|
||||||
__locale_->acquire();
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
locale::locale(const locale& other, const locale& one, category c)
|
locale::locale(const locale& other, const locale& one, category c)
|
||||||
: __locale_(new __imp(*other.__locale_, *one.__locale_, c))
|
: __locale_(new __imp(*other.__locale_, *one.__locale_, c))
|
||||||
{
|
{
|
||||||
__locale_->acquire();
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
@ -628,7 +635,7 @@ locale::__install_ctor(const locale& other, facet* f, long id)
|
|||||||
__locale_ = new __imp(*other.__locale_, f, id);
|
__locale_ = new __imp(*other.__locale_, f, id);
|
||||||
else
|
else
|
||||||
__locale_ = other.__locale_;
|
__locale_ = other.__locale_;
|
||||||
__locale_->acquire();
|
__locale_->__add_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
locale
|
locale
|
||||||
|
Loading…
Reference in New Issue
Block a user