Re: Optimization for std::to_string()
Jonathan Wakely 2018-07-20 13:05: On 20/07/18 12:44 +0300, niXman wrote: Thanks. How did you verify it's an optimization? Optimization is that there is no superfluous copying into string. The to_string functions always pass at least __n=16 to __to_xstring, which is larger than the SSO buffer in std::__cxx11::string, and so forces a memory allocation. I didn't think about this... -- Regards, niXman ___ C++ for Bitcoins: github.com/niXman
Optimization for std::to_string()
Hi, Patch in attachments. Tested on x86_64-linux-gnu. -- Regards, niXman ___ C++ for Bitcoins: github.com/niXman Index: libstdc++-v3/include/ext/string_conversions.h === --- libstdc++-v3/include/ext/string_conversions.h (revision 262879) +++ libstdc++-v3/include/ext/string_conversions.h (working copy) @@ -100,19 +100,18 @@ __builtin_va_list), std::size_t __n, const _CharT* __fmt, ...) { - // XXX Eventually the result should be constructed in-place in - // the __cxx11 string, likely with the help of internal hooks. - _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __n)); + _String __str(__n, 0); __builtin_va_list __args; __builtin_va_start(__args, __fmt); - const int __len = __convf(__s, __n, __fmt, __args); + const std::size_t __len = __convf(&__str[0], __n, __fmt, __args); __builtin_va_end(__args); - return _String(__s, __s + __len); + __str.resize(__len); + + return __str; } _GLIBCXX_END_NAMESPACE_VERSION
Re: [PATCH] Windows support for std::filesystem
niXman 2017-02-12 20:28: Hi, Tested on i686/x86_64-MinGW-W64 Please test possible regressions on posix platform. As continuation for: https://gcc.gnu.org/ml/libstdc++/2017-02/msg00041.html Regression on posix platform was fixed. Tested on i686/x86_64-MinGW-W64 and x86_64-linux-gnu. Index: libstdc++-v3/src/filesystem/dir.cc === --- libstdc++-v3/src/filesystem/dir.cc (revision 246136) +++ libstdc++-v3/src/filesystem/dir.cc (working copy) @@ -41,9 +41,10 @@ #endif #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS -# undef opendir -# define opendir _wopendir -#endif +# include "fs-win32.h" +#else +# include "fs-posix.h" +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS namespace fs = std::experimental::filesystem; @@ -51,7 +52,7 @@ { _Dir() : dirp(nullptr) { } - _Dir(DIR* dirp, const fs::path& path) : dirp(dirp), path(path) { } + _Dir(os_DIR_t* dirp, const fs::path& path) : dirp(dirp), path(path) { } _Dir(_Dir&& d) : dirp(std::exchange(d.dirp, nullptr)), path(std::move(d.path)), @@ -60,11 +61,11 @@ _Dir& operator=(_Dir&&) = delete; - ~_Dir() { if (dirp) ::closedir(dirp); } + ~_Dir() { if (dirp) ::os_closedir(dirp); } bool advance(std::error_code*, directory_options = directory_options::none); - DIR* dirp; + os_DIR_t* dirp; fs::path path; directory_entry entry; file_type type = file_type::none; @@ -87,7 +88,7 @@ if (ec) ec->clear(); -if (DIR* dirp = ::opendir(p.c_str())) +if (os_DIR_t* dirp = ::os_opendir(p.c_str())) return {dirp, p}; const int err = errno; @@ -105,7 +106,7 @@ } inline fs::file_type - get_file_type(const ::dirent& d __attribute__((__unused__))) + get_file_type(const ::os_dirent_t& d __attribute__((__unused__))) { #ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE switch (d.d_type) @@ -145,13 +146,14 @@ ec->clear(); int err = std::exchange(errno, 0); - const auto entp = readdir(dirp); + const auto entp = ::os_readdir(dirp); std::swap(errno, err); if (entp) { // skip past dot and dot-dot - if (!strcmp(entp->d_name, ".") || !strcmp(entp->d_name, "..")) + if (!std::char_traits::compare(entp->d_name, _WS("."), 1) || + !std::char_traits::compare(entp->d_name, _WS(".."), 2)) return advance(ec, options); entry = fs::directory_entry{path / entp->d_name}; type = get_file_type(*entp); @@ -239,7 +241,7 @@ error_code* ec) : _M_options(options), _M_pending(true) { - if (DIR* dirp = ::opendir(p.c_str())) + if (os_DIR_t* dirp = ::os_opendir(p.c_str())) { auto sp = std::make_shared<_Dir_stack>(); sp->push(_Dir{ dirp, p }); Index: libstdc++-v3/src/filesystem/fs-posix.h === --- libstdc++-v3/src/filesystem/fs-posix.h (revision 0) +++ libstdc++-v3/src/filesystem/fs-posix.h (working copy) @@ -0,0 +1,49 @@ + +// Copyright (C) 2014-2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#ifndef _GLIBCXX_EXPERIMENTAL_FS_POSIX_H +#define _GLIBCXX_EXPERIMENTAL_FS_POSIX_H 1 + +#define os_DIR_t DIR +#define os_dirent_t dirent +#define os_open open +#define os_opendir opendir +#define os_closedir closedir +#define os_readdir readdir +#define os_stat stat +#define os_stat_t stat +#define os_chmod chmod +#define os_mkdir mkdir +#define os_getcwd getcwd +#define os_chdir chdir +#define os_utimbuf_t utimbuf +#define os_utime utime +#define os_remove remove +#define os_rename rename +#define os_truncate truncate + +#define os_utime utime + +#define _WS(x) x + +#endif // _GLIBCXX_EXPERIMENTAL_FS_POSIX_H Index: libstdc++-v3/src/filesystem/fs-win32.h === --- libstdc++-v3/src/filesystem/fs-win32.h (revision 0) +++ libstdc++-v3/src/filesyst
[PATCH] Windows support for std::filesystem
Hi, Tested on i686/x86_64-MinGW-W64 Please test possible regressions on posix platform. -- Regards, niXman ___ Dual-target(32 & 64-bit) MinGW-W64 compilers for 32 and 64-bit Windows: https://sf.net/p/mingw-w64/ Index: libstdc++-v3/src/filesystem/dir.cc === --- libstdc++-v3/src/filesystem/dir.cc (revision 245367) +++ libstdc++-v3/src/filesystem/dir.cc (working copy) @@ -41,9 +41,10 @@ #endif #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS -# undef opendir -# define opendir _wopendir -#endif +# include "fs-win32.h" +#else +# include "fs-posix.h" +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS namespace fs = std::experimental::filesystem; @@ -51,7 +52,7 @@ { _Dir() : dirp(nullptr) { } - _Dir(DIR* dirp, const fs::path& path) : dirp(dirp), path(path) { } + _Dir(os_DIR_t* dirp, const fs::path& path) : dirp(dirp), path(path) { } _Dir(_Dir&& d) : dirp(std::exchange(d.dirp, nullptr)), path(std::move(d.path)), @@ -60,11 +61,11 @@ _Dir& operator=(_Dir&&) = delete; - ~_Dir() { if (dirp) ::closedir(dirp); } + ~_Dir() { if (dirp) ::os_closedir(dirp); } bool advance(std::error_code*, directory_options = directory_options::none); - DIR* dirp; + os_DIR_t* dirp; fs::path path; directory_entry entry; file_type type = file_type::none; @@ -87,7 +88,7 @@ if (ec) ec->clear(); -if (DIR* dirp = ::opendir(p.c_str())) +if (os_DIR_t* dirp = ::os_opendir(p.c_str())) return {dirp, p}; const int err = errno; @@ -105,7 +106,7 @@ } inline fs::file_type - get_file_type(const ::dirent& d __attribute__((__unused__))) + get_file_type(const ::os_dirent_t& d __attribute__((__unused__))) { #ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE switch (d.d_type) @@ -145,13 +146,14 @@ ec->clear(); int err = std::exchange(errno, 0); - const auto entp = readdir(dirp); + const auto entp = ::os_readdir(dirp); std::swap(errno, err); if (entp) { // skip past dot and dot-dot - if (!strcmp(entp->d_name, ".") || !strcmp(entp->d_name, "..")) + if (!std::char_traits::compare(entp->d_name, _WS("."), 1) || + !std::char_traits::compare(entp->d_name, _WS(".."), 2)) return advance(ec, options); entry = fs::directory_entry{path / entp->d_name}; type = get_file_type(*entp); @@ -239,7 +241,7 @@ error_code* ec) : _M_options(options), _M_pending(true) { - if (DIR* dirp = ::opendir(p.c_str())) + if (os_DIR_t* dirp = ::os_opendir(p.c_str())) { auto sp = std::make_shared<_Dir_stack>(); sp->push(_Dir{ dirp, p }); Index: libstdc++-v3/src/filesystem/fs-posix.h === --- libstdc++-v3/src/filesystem/fs-posix.h (nonexistent) +++ libstdc++-v3/src/filesystem/fs-posix.h (working copy) @@ -0,0 +1,49 @@ + +// Copyright (C) 2014-2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#ifndef _GLIBCXX_EXPERIMENTAL_FS_POSIX_H +#define _GLIBCXX_EXPERIMENTAL_FS_POSIX_H 1 + +#define os_DIR_t DIR +#define os_dirent_t dirent +#define os_open open +#define os_opendir opendir +#define os_closedir closedir +#define os_readdir readdir_r +#define os_stat stat +#define os_stat_t stat +#define os_chmod chmod +#define os_mkdir mkdir +#define os_getcwd getcwd +#define os_chdir chdir +#define os_utimbuf_t utimbuf +#define os_utime utime +#define os_remove remove +#define os_rename rename +#define os_truncate truncate + +#define os_utime utime + +#define _WS(x) x + +#endif // _GLIBCXX_EXPERIMENTAL_FS_POSIX_H Index: libstdc++-v3/src/filesystem/fs-win32.h === --- libstdc++-v3/src/filesystem/fs-win32.h (nonexistent) +++ libstdc++-v3/src/filesystem/fs-win32.h (working
Re: Fix for libstdc++-v3's error_constants.h for MinGW-W64
Jonathan Wakely 2016-12-16 16:04: I don't think this is suitable for the branches, but could be applied to trunk (as the patch was posted during stage 1, but I missed it). Ok. Does this require a particular version of MinGW-w64? Yes, at the moment MinGW-W64 trunk is required. (MinGW-W64-v6) Does it work for older versions? No.
ping for msg00567
Hi, A few days ago I sent a patch to libstdc++-v3[1], but the patch is still not applied. Why? Moreover, when I try to ping this thread my messages are returned to sender. Why? [1] https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00567.html -- Regards, niXman ___ Dual-target(32 & 64-bit) MinGW-W64 compilers for 32 and 64-bit Windows: http://sourceforge.net/projects/mingw-w64/
Fix for libstdc++-v3's error_constants.h for MinGW-W64
= ENOSTR, + not_connected = ENOTCONN, not_enough_memory = ENOMEM, #ifdef _GLIBCXX_HAVE_ENOTSUP not_supported = ENOTSUP, #endif -//operation_canceled = ECANCELED, -//operation_in_progress = EINPROGRESS, + operation_canceled = ECANCELED, + operation_in_progress = EINPROGRESS, #ifdef _GLIBCXX_HAVE_EPERM operation_not_permitted =EPERM, #endif -//operation_not_supported =EOPNOTSUPP, + operation_not_supported =EOPNOTSUPP, #ifdef _GLIBCXX_HAVE_EWOULDBLOCK operation_would_block = EWOULDBLOCK, #endif -//owner_dead = EOWNERDEAD, + owner_dead = EOWNERDEAD, permission_denied = EACCES, -//protocol_error = EPROTO, -//protocol_not_supported = EPROTONOSUPPORT, + protocol_error = EPROTO, + protocol_not_supported = EPROTONOSUPPORT, read_only_file_system = EROFS, resource_deadlock_would_occur = EDEADLK, resource_unavailable_try_again = EAGAIN, result_out_of_range =ERANGE, -//state_not_recoverable = ENOTRECOVERABLE, -//stream_timeout = ETIME, -//text_file_busy = ETXTBSY, + state_not_recoverable = ENOTRECOVERABLE, + stream_timeout = ETIME, + text_file_busy = ETXTBSY, #ifdef _GLIBCXX_HAVE_ETIMEDOUT timed_out = ETIMEDOUT, #endif too_many_files_open_in_system = ENFILE, too_many_files_open =EMFILE, - too_many_links = EMLINK -//too_many_symbolic_link_levels = ELOOP, + too_many_links = EMLINK, + too_many_symbolic_link_levels = ELOOP, #ifdef _GLIBCXX_HAVE_EOVERFLOW - , - value_too_large =EOVERFLOW + value_too_large =EOVERFLOW, #endif -//wrong_protocol_type =EPROTOTYPE + wrong_protocol_type =EPROTOTYPE }; _GLIBCXX_END_NAMESPACE_VERSION -- Regards, niXman ___ Dual-target(32 & 64-bit) MinGW-W64 compilers for 32 and 64-bit Windows: http://sourceforge.net/projects/mingw-w64/ Index: libstdc++-v3/config/os/mingw32-w64/error_constants.h === --- libstdc++-v3/config/os/mingw32-w64/error_constants.h (revision 240904) +++ libstdc++-v3/config/os/mingw32-w64/error_constants.h (working copy) @@ -41,22 +41,22 @@ // replaced by Winsock WSA-prefixed equivalents. enum class errc { -//address_family_not_supported = EAFNOSUPPORT, -//address_in_use = EADDRINUSE, -//address_not_available = EADDRNOTAVAIL, -//already_connected = EISCONN, + address_family_not_supported = EAFNOSUPPORT, + address_in_use = EADDRINUSE, + address_not_available = EADDRNOTAVAIL, + already_connected = EISCONN, argument_list_too_long = E2BIG, argument_out_of_domain = EDOM, bad_address = EFAULT, bad_file_descriptor = EBADF, -//bad_message = EBADMSG, + bad_message = EBADMSG, broken_pipe = EPIPE, -//connection_aborted = ECONNABORTED, -//connection_already_in_progress = EALREADY, -//connection_refused = ECONNREFUSED, -//connection_reset = ECONNRESET, -//cross_device_link = EXDEV, -//destination_address_required = EDESTADDRREQ, + connection_aborted = ECONNABORTED, + connection_already_in_progress = EALREADY, + connection_refused = ECONNREFUSED, + connection_reset = ECONNRESET, + cross_device_link = EXDEV, + destination_address_required = EDESTADDRREQ, device_or_resource_busy = EBUSY, directory_not_empty = ENOTEMPTY, executable_format_error = ENOEXEC, @@ -64,8 +64,8 @@ file_too_large = EFBIG, filename_too_long = ENAMETOOLONG, function_not_supported = ENOSYS, -//host_unreachable = EHOSTUNREACH, -//identifier_removed = EIDRM, + host_unreachable = EHOSTUNREACH, + identifier_removed = EIDRM, illegal_byte_sequence = EILSEQ, inappropriate_io_control_operation = ENOTTY, interrupted = EINTR, @@ -73,67 +73,66 @@ invalid_seek = ESPIPE, io_error =
libitm MinGW detect
Hello. -- Regards, niXman libitm-mingw-detect.diff Description: Binary data
Re: implementation of std::thread::hardware_concurrency()
I am currently working on a patch for OpenBSD.I wrote a some autoconf tests for mingw/*BSD. 2011/11/7 Jonathan Wakely jwakely@gmail.com: I'm testing my suggestion on a netbsd machine, I'd be grateful for darwin testing once I've committed it, which I expect to be later today.
Re: implementation of std::thread::hardware_concurrency()
Rechecked. diff --git a/libstdc++-v3/src/thread.cc b/libstdc++-v3/src/thread.cc index 09e7fc5..6feda4d 100644 --- a/libstdc++-v3/src/thread.cc +++ b/libstdc++-v3/src/thread.cc @@ -112,10 +112,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION unsigned int thread::hardware_concurrency() noexcept { -int __n = _GLIBCXX_NPROCS; -if (__n 0) - __n = 0; -return __n; +int count=0; +#if defined(PTW32_VERSION) || \ + (defined(__MINGW64_VERSION_MAJOR) defined(_POSIX_THREADS)) || \ + defined(__hpux) +count=pthread_num_processors_np(); +#elif defined(__APPLE__) || defined(__FreeBSD__) +size_t size=sizeof(count); +sysctlbyname(hw.ncpu, count, size, NULL, 0); +#elif defined(_SC_NPROCESSORS_ONLN) +count=sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_GLIBCXX_USE_GET_NPROCS) +count=_GLIBCXX_NPROCS; +#endif +return (count0)?count:0; } _GLIBCXX_END_NAMESPACE_VERSION 2011/11/1 Paolo Carlini pcarl...@gmail.com: Hi, This is patch is implement the std::thread::hardware_concurrency(). Tested on pthreads-win32/winpthreads on windows OS, and on Linux/FreeBSD. Please send library patches to the library mailing list too. Also, always parch mainline first: actually in the latter the function is alread implemented, maybe something is missing for win32, please check, rediff, and resend. Thanks Paolo
Re: implementation of std::thread::hardware_concurrency()
With what exactly do you don't accept this patch? 2011/11/1 Jonathan Wakely jwakely@gmail.com: On 1 November 2011 11:54, Marc Glisse wrote: On Tue, 1 Nov 2011, niXman wrote: diff --git a/libstdc++-v3/src/thread.cc b/libstdc++-v3/src/thread.cc index 09e7fc5..6feda4d 100644 --- a/libstdc++-v3/src/thread.cc +++ b/libstdc++-v3/src/thread.cc @@ -112,10 +112,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION unsigned int thread::hardware_concurrency() noexcept { - int __n = _GLIBCXX_NPROCS; - if (__n 0) - __n = 0; - return __n; + int count=0; +#if defined(PTW32_VERSION) || \ + (defined(__MINGW64_VERSION_MAJOR) defined(_POSIX_THREADS)) || \ + defined(__hpux) + count=pthread_num_processors_np(); +#elif defined(__APPLE__) || defined(__FreeBSD__) + size_t size=sizeof(count); + sysctlbyname(hw.ncpu, count, size, NULL, 0); +#elif defined(_SC_NPROCESSORS_ONLN) + count=sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_GLIBCXX_USE_GET_NPROCS) + count=_GLIBCXX_NPROCS; +#endif + return (count0)?count:0; Er, the macro _GLIBCXX_NPROCS already handles the case sysconf(_SC_NPROCESSORS_ONLN). It looks like you actually want to remove the macro _GLIBCXX_NPROCS completely. Right, I already handled the case of using sysconf. I'm going to veto this patch in its current form - please check how it works now before changing this code. _GLIBCXX_NPROCS should be made to call pthread_num_processors_np() for mingw or HPUX.
Re: implementation of std::thread::hardware_concurrency()
What header is required for pthread_num_processors_np? pthread.h Also, you should include sys/sysctl.h before calling sysctlbyname. On the right - yes. sysctlbyname() implicitly included in some header files.
Re: implementation of std::thread::hardware_concurrency()
Ok. I correct it. 2011/11/1 Jonathan Wakely jwakely@gmail.com: I've put gcc-patches@ back in the CC list and removed gcc@ On 1 November 2011 15:35, niXman wrote: Er, the macro _GLIBCXX_NPROCS already handles the case sysconf(_SC_NPROCESSORS_ONLN). It looks like you actually want to remove the macro _GLIBCXX_NPROCS completely. Fixed. No, this still isn't acceptable. I do not want to see preprocessor tests like +#elif defined(__APPLE__) || defined(__FreeBSD__) in the body of get_thread::hardware_concurrency(), the configure script should determine what is available on the platform and set an appropriate macro. Look at the definition of _GLIBCXX_NPROCS and adjust that to do #define _GLIBCXX_NPROCS pthread_num_processors_np() for the relevant platforms. For the platforms using sysctlbyname there could be an inline function that calls it, and _GLIBCXX_NPROCS could be defined to call that, so that thread::hardware_concurrency() can still be defined as it is today. Please read the code you're changing and understand how it works today before making changes.
implementation of std::thread::hardware_concurrency()
Hi all. This is patch is implement the std::thread::hardware_concurrency(). Tested on pthreads-win32/winpthreads on windows OS, and on Linux/FreeBSD. diff --git a/libstdc++-v3/src/thread.cc b/libstdc++-v3/src/thread.cc index 09e7fc5..3eacb06 100644 --- a/libstdc++-v3/src/thread.cc +++ b/libstdc++-v3/src/thread.cc @@ -112,10 +112,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION unsigned int thread::hardware_concurrency() noexcept { -int __n = _GLIBCXX_NPROCS; -if (__n 0) - __n = 0; -return __n; +int count=0; +#if defined(PTW32_VERSION) || \ + (defined(__MINGW64_VERSION_MAJOR) defined(_POSIX_THREADS)) || \ + defined(__hpux) +count=pthread_num_processors_np(); +#elif defined(__APPLE__) || defined(__FreeBSD__) +size_t size=sizeof(count); +sysctlbyname(hw.ncpu, count, size, NULL, 0); +#elif defined(_SC_NPROCESSORS_ONLN) +count=sysconf(_SC_NPROCESSORS_ONLN); +#elif definen(_GLIBCXX_USE_GET_NPROCS) +count=_GLIBCXX_NPROCS; +#endif +return (count0)?count:0; } _GLIBCXX_END_NAMESPACE_VERSION