From 80d96550ba34e355602687f5797a53c9281099cf Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Mon, 26 Aug 2019 15:35:08 +0300 Subject: [PATCH] ThreadPthread: better hardware_concurrency implementation GitOrigin-RevId: 4cccfcbf5f6ad5e1293993ff111b8021bb5c70a1 --- tdutils/CMakeLists.txt | 1 + .../td/utils/port/detail/ThreadPthread.cpp | 92 +++++++++++++++++++ tdutils/td/utils/port/detail/ThreadPthread.h | 40 ++------ 3 files changed, 103 insertions(+), 30 deletions(-) create mode 100644 tdutils/td/utils/port/detail/ThreadPthread.cpp diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 307ca238..7acd7821 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -75,6 +75,7 @@ set(TDUTILS_SOURCE td/utils/port/detail/Poll.cpp td/utils/port/detail/Select.cpp td/utils/port/detail/ThreadIdGuard.cpp + td/utils/port/detail/ThreadPthread.cpp td/utils/port/detail/WineventPoll.cpp ${TDMIME_AUTO} diff --git a/tdutils/td/utils/port/detail/ThreadPthread.cpp b/tdutils/td/utils/port/detail/ThreadPthread.cpp new file mode 100644 index 00000000..8590be27 --- /dev/null +++ b/tdutils/td/utils/port/detail/ThreadPthread.cpp @@ -0,0 +1,92 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/utils/port/detail/ThreadPthread.h" + +#if TD_THREAD_PTHREAD +#include +#include +#include +#include + +namespace td { +namespace detail { +unsigned ThreadPthread::hardware_concurrency() { +// Linux and MacOs +#if defined(_SC_NPROCESSORS_ONLN) + { + auto res = sysconf(_SC_NPROCESSORS_ONLN); + if (res > 0) { + return narrow_cast(res); + } + } +#endif + +// *BSD +#if defined(HW_AVAILCPU) && defined(CTL_HW) + { + int mib[2]; + int res{0}; + size_t len = sizeof(res); + mib[0] = CTL_HW; + mib[1] = HW_AVAILCPU; + len = sizeof(res); + if (sysctl(mib, 2, &res, &len, NULL, 0) == 0 && res != 0) { + return res; + } + } +#endif + +#if defined(HW_NCPU) && defined(CTL_HW) + { + int mib[2]; + int res{0}; + size_t len = sizeof(res); + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + len = sizeof(res); + if (sysctl(mib, 2, &res, &len, NULL, 0) == 0 && res != 0) { + return res; + } + } +#endif + + // Just in case + return 8; +} +void ThreadPthread::set_name(CSlice name) { +#if defined(_GNU_SOURCE) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2, 12) + pthread_setname_np(thread_, name.c_str()); +#endif +#endif +} +void ThreadPthread::join() { + if (is_inited_.get()) { + is_inited_ = false; + pthread_join(thread_, nullptr); + } +} +void ThreadPthread::detach() { + if (is_inited_.get()) { + is_inited_ = false; + pthread_detach(thread_); + } +} +int do_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { + return pthread_create(thread, attr, start_routine, arg); +} +namespace this_thread_pthread { +void yield() { + sched_yield(); +} +ThreadPthread::id get_id() { + return pthread_self(); +} +} // namespace this_thread_pthread +} // namespace detail +} // namespace td +#endif diff --git a/tdutils/td/utils/port/detail/ThreadPthread.h b/tdutils/td/utils/port/detail/ThreadPthread.h index 1f0eae0b..e7a7604e 100644 --- a/tdutils/td/utils/port/detail/ThreadPthread.h +++ b/tdutils/td/utils/port/detail/ThreadPthread.h @@ -17,13 +17,13 @@ #include "td/utils/port/detail/ThreadIdGuard.h" #include "td/utils/port/thread_local.h" #include "td/utils/Slice.h" +#include "td/utils/misc.h" #include #include #include -#include -#include +#include namespace td { namespace detail { @@ -49,33 +49,15 @@ class ThreadPthread { pthread_create(&thread_, nullptr, run_thread, func.release()); is_inited_ = true; } - void set_name(CSlice name) { -#if defined(_GNU_SOURCE) && defined(__GLIBC_PREREQ) -#if __GLIBC_PREREQ(2, 12) - pthread_setname_np(thread_, name.c_str()); -#endif -#endif - } - void join() { - if (is_inited_.get()) { - is_inited_ = false; - pthread_join(thread_, nullptr); - } - } + void set_name(CSlice name); + void join(); - void detach() { - if (is_inited_.get()) { - is_inited_ = false; - pthread_detach(thread_); - } - } + void detach(); ~ThreadPthread() { join(); } - static unsigned hardware_concurrency() { - return 8; - } + static unsigned hardware_concurrency(); using id = pthread_t; @@ -88,6 +70,8 @@ class ThreadPthread { return std::forward(v); } + int do_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); + static void *run_thread(void *ptr) { ThreadIdGuard thread_id_guard; auto func = unique_ptr(static_cast(ptr)); @@ -96,12 +80,8 @@ class ThreadPthread { }; namespace this_thread_pthread { -inline void yield() { - sched_yield(); -} -inline ThreadPthread::id get_id() { - return pthread_self(); -} +void yield(); +ThreadPthread::id get_id(); } // namespace this_thread_pthread } // namespace detail } // namespace td