From 7c168f20f4e38be8d578c96a32358ef97fe282aa Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Tue, 7 Dec 2021 18:10:06 +0100 Subject: [PATCH 1/6] Fix gdd string to double conversion This is an alternative fix for the issue described in https://github.com/epics-modules/pcas/issues/4 and https://github.com/epics-extensions/ca-gateway/issues/37 that keeps the call to epicsScanDouble() before trying sscanf() first with "%lf" (ignoring extra characters) then with "%x" (to catch hex numbers). (closes #216) --- src/ca/legacy/gdd/aitConvert.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/ca/legacy/gdd/aitConvert.cc b/src/ca/legacy/gdd/aitConvert.cc index b2a4e42e3..eeb51ee32 100644 --- a/src/ca/legacy/gdd/aitConvert.cc +++ b/src/ca/legacy/gdd/aitConvert.cc @@ -50,14 +50,16 @@ bool getStringAsDouble ( const char * pString, ftmp = itmp; } else { - int j = epicsScanDouble( pString, &ftmp ); - if ( j != 1 ) { - j = sscanf ( pString,"%x", &itmp ); - if ( j == 1 ) { - ftmp = itmp; - } - else { - return false; + int j = epicsScanDouble ( pString, &ftmp ); + if ( j != 1 ) { + j = sscanf ( pString, "%lf", &ftmp ); + if ( j != 1 ) { + j = sscanf ( pString, "%x", &itmp ); + if ( j == 1 ) { + ftmp = itmp; + } else { + return false; + } } } } From 3cf2d3737f90dd07c58c0d8c2d02b4c4d57696f6 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Tue, 24 May 2022 13:24:42 +0100 Subject: [PATCH 2/6] Use SetThreadDescription(), if available, to set thread name --- src/libCom/osi/os/WIN32/setThreadName.cpp | 74 ++++++++++++++++++----- 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/src/libCom/osi/os/WIN32/setThreadName.cpp b/src/libCom/osi/os/WIN32/setThreadName.cpp index 49663c8af..3db1ca564 100644 --- a/src/libCom/osi/os/WIN32/setThreadName.cpp +++ b/src/libCom/osi/os/WIN32/setThreadName.cpp @@ -8,44 +8,86 @@ * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ - #define VC_EXTRALEAN #define STRICT -#if _WIN64 -# define _WIN32_WINNT 0x400 /* defining this drops support for W95 */ -#endif #include +#include + /* - * this was copied directly from an example in visual c++ 7 documentation, - * It uses visual C++ specific keywords for exception handling, but is - * probably only useful when using the visual c++ or later debugger. - * * Usage: setThreadName (-1, "MainThread"); */ + + +static void setThreadNameVS ( DWORD dwThreadID, LPCSTR szThreadName ); +typedef HRESULT (*setDesc_t)(HANDLE, PCWSTR); + extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ) +{ + static HMODULE hKernel = LoadLibrary("KernelBase.dll"); + static setDesc_t pSetDesc = (hKernel != NULL ? + (setDesc_t)GetProcAddress(hKernel, "SetThreadDescription") : NULL); + if (szThreadName == NULL || *szThreadName == '\0') + { + return; + } + if (pSetDesc != NULL) + { +#ifdef THREAD_SET_LIMITED_INFORMATION + DWORD thread_access = THREAD_SET_LIMITED_INFORMATION; +#else + DWORD thread_access = THREAD_SET_INFORMATION; +#endif /* ifdef THREAD_SET_LIMITED_INFORMATION */ + HANDLE hThread = OpenThread(thread_access, FALSE, dwThreadID); + if (hThread != NULL) + { + const std::string s(szThreadName); + const std::wstring ws(s.begin(), s.end()); + HRESULT hr = (*pSetDesc)(hThread, ws.c_str()); + CloseHandle(hThread); + } + } + // if SetThreadDescription() was available and we have a recent + // visual studio debugger (2017 version 15.6 or higher) attached + // then the names will already be defined. However we don't know + // this for sure, so also trigger the old exception mechanism. + // See https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code + setThreadNameVS(dwThreadID, szThreadName); +} + +static void setThreadNameVS( DWORD dwThreadID, LPCSTR szThreadName ) { #if _MSC_VER >= 1300 && defined ( _DEBUG ) +// This was copied directly from an MSDN example +// It sets the thread name by throwing a special exception that is caught by Visual Sudio +// It requires the debugger to be already attached to the process +// when the exception is thrown for the name to be registered + static const DWORD MS_VC_EXCEPTION = 0x406D1388; +#pragma pack(push,8) typedef struct tagTHREADNAME_INFO { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. } THREADNAME_INFO; +#pragma pack(pop) THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; - +#pragma warning(push) +#pragma warning(disable: 6320 6322) __try { - RaiseException( 0x406D1388, 0, - sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info ); + RaiseException(MS_VC_EXCEPTION, 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR*)&info); } - __except(EXCEPTION_CONTINUE_EXECUTION) + __except (EXCEPTION_EXECUTE_HANDLER) { } +#pragma warning(pop) #endif } From 0ace4e4a30c3146269b84fec38520130cc2b3979 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Tue, 24 May 2022 14:21:12 +0100 Subject: [PATCH 3/6] SetThreadName: Add WINAPI for 32bit builds --- src/libCom/osi/os/WIN32/setThreadName.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/osi/os/WIN32/setThreadName.cpp b/src/libCom/osi/os/WIN32/setThreadName.cpp index 3db1ca564..600950ce5 100644 --- a/src/libCom/osi/os/WIN32/setThreadName.cpp +++ b/src/libCom/osi/os/WIN32/setThreadName.cpp @@ -20,7 +20,7 @@ static void setThreadNameVS ( DWORD dwThreadID, LPCSTR szThreadName ); -typedef HRESULT (*setDesc_t)(HANDLE, PCWSTR); +typedef HRESULT (* WINAPI setDesc_t)(HANDLE, PCWSTR); extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ) { From 4b884c15b11ba945c23c49e5bca68107c986fbf4 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Tue, 24 May 2022 14:40:46 +0100 Subject: [PATCH 4/6] SetThreadName: Add WINAPI (correctly) for 32bit builds --- src/libCom/osi/os/WIN32/setThreadName.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/osi/os/WIN32/setThreadName.cpp b/src/libCom/osi/os/WIN32/setThreadName.cpp index 600950ce5..5df1c3ad0 100644 --- a/src/libCom/osi/os/WIN32/setThreadName.cpp +++ b/src/libCom/osi/os/WIN32/setThreadName.cpp @@ -20,7 +20,7 @@ static void setThreadNameVS ( DWORD dwThreadID, LPCSTR szThreadName ); -typedef HRESULT (* WINAPI setDesc_t)(HANDLE, PCWSTR); +typedef HRESULT (WINAPI* setDesc_t)(HANDLE, PCWSTR); extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ) { From c8647ffab78bb76212a9cbc3fdc65210098a8aaf Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sun, 21 Aug 2022 16:00:30 -0500 Subject: [PATCH 5/6] Added Release Note --- documentation/RELEASE_NOTES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 363105e87..b5436f6f3 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -6,6 +6,12 @@ This version of EPICS Base has not been released yet. +### Set thread names on Windows + +On MS Windows, epicsThread names are made available to the OS and debugger +using `SetThreadDescription()` if available as well as using the older +exception mechanism. + ### Fix timers on MS Windows for non-EPICS threads The waitable timer changes in 3.15.9 broke calls to `epicsThreadSleep()` and From a249561677de73e3f174ec8e4478937a7a55a9b2 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sun, 21 Aug 2022 16:15:53 -0500 Subject: [PATCH 6/6] Added darwin-aarch64 support from 7.0 branch --- configure/os/CONFIG.Common.darwin-aarch64 | 14 ++++++++++++++ configure/os/CONFIG.darwin-aarch64.Common | 8 ++++++++ configure/os/CONFIG_SITE.Common.darwin-aarch64 | 9 +++++++++ documentation/RELEASE_NOTES.md | 5 +++++ src/tools/EpicsHostArch.pl | 7 +++++-- 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 configure/os/CONFIG.Common.darwin-aarch64 create mode 100644 configure/os/CONFIG.darwin-aarch64.Common create mode 100644 configure/os/CONFIG_SITE.Common.darwin-aarch64 diff --git a/configure/os/CONFIG.Common.darwin-aarch64 b/configure/os/CONFIG.Common.darwin-aarch64 new file mode 100644 index 000000000..eaba1efb2 --- /dev/null +++ b/configure/os/CONFIG.Common.darwin-aarch64 @@ -0,0 +1,14 @@ +# CONFIG.Common.darwin-aarch64 +# +# This file is maintained by the build community. +# +# Definitions for darwin-aarch64 target builds +# Sites may override these definitions in CONFIG_SITE.Common.darwin-aarch64 +#------------------------------------------------------- + +# +# To build universal binaries, configure ARCH_CLASS +# in the file CONFIG_SITE.Common.darwin-aarch64 + +# Include definitions common to all Darwin targets +include $(CONFIG)/os/CONFIG.darwinCommon.darwinCommon diff --git a/configure/os/CONFIG.darwin-aarch64.Common b/configure/os/CONFIG.darwin-aarch64.Common new file mode 100644 index 000000000..0be8d68fe --- /dev/null +++ b/configure/os/CONFIG.darwin-aarch64.Common @@ -0,0 +1,8 @@ +# CONFIG.darwin-aarch64.Common +# +# Definitions for darwin-aarch64 host builds +# Sites may override these definitions in CONFIG_SITE.darwin-aarch64.Common +#------------------------------------------------------- + +#Include definitions common to unix hosts +include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG_SITE.Common.darwin-aarch64 b/configure/os/CONFIG_SITE.Common.darwin-aarch64 new file mode 100644 index 000000000..8d79eb16e --- /dev/null +++ b/configure/os/CONFIG_SITE.Common.darwin-aarch64 @@ -0,0 +1,9 @@ +# CONFIG_SITE.Common.darwin-aarch64 +# +# Site override definitions for darwin-aarch64 target builds +#------------------------------------------------------- + +# +# arm64 devices: Apple Silicon M1 + +ARCH_CLASS = arm64 diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index b5436f6f3..3a7575c7d 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -6,6 +6,11 @@ This version of EPICS Base has not been released yet. +### Support for Apple M1/M2 (arm64) Processors + +Thanks to Jeong Han Lee this release comes with build support for Apple's new +M1 CPUs running macOS, using the target name `darwin-aarch64`. + ### Set thread names on Windows On MS Windows, epicsThread names are made available to the OS and debugger diff --git a/src/tools/EpicsHostArch.pl b/src/tools/EpicsHostArch.pl index e8e49bc5e..abff49007 100644 --- a/src/tools/EpicsHostArch.pl +++ b/src/tools/EpicsHostArch.pl @@ -2,6 +2,7 @@ #************************************************************************* # Copyright (c) 2018 UChicago Argonne LLC, as Operator of Argonne # National Laboratory. +# SPDX-License-Identifier: EPICS # EPICS BASE is distributed subject to a Software License Agreement found # in file LICENSE that is included with this distribution. #************************************************************************* @@ -34,6 +35,8 @@ sub HostArch { return 'linux-x86_64' if m/^x86_64-linux/; return 'linux-x86' if m/^i[3-6]86-linux/; return 'linux-arm' if m/^arm-linux/; + return 'linux-aarch64' if m/^aarch64-linux/; + return 'linux-ppc64' if m/^powerpc64-linux/; return 'windows-x64' if m/^MSWin32-x64/; return 'win32-x86' if m/^MSWin32-x86/; return "cygwin-x86_64" if m/^x86_64-cygwin/; @@ -44,8 +47,8 @@ sub HostArch { my ($kernel, $hostname, $release, $version, $cpu) = uname; if (m/^darwin/) { for ($cpu) { - return 'darwin-x86' if m/^(i386|x86_64)/; - return 'darwin-ppc' if m/Power Macintosh/; + return 'darwin-x86' if m/^x86_64/; + return 'darwin-aarch64' if m/^arm64/; } die "$0: macOS CPU type '$cpu' not recognized\n"; }