From 6eac5cb704db3b56f35417c2816d749cef1ffcae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 13 Nov 2025 14:47:53 +0000 Subject: [PATCH 1/3] Fix IPv4 socket binding on non-Windows systems The IPv4 binding code was incorrectly wrapped in #ifdef _WIN32, causing the server to fall through to IPv6 binding even when IPv4 was explicitly requested with the -4 flag on Linux systems. This fix removes the Windows- specific conditional around the IPv4 binding logic while keeping platform- specific socket close calls. Fixes the issue where pcm-sensor-server with -4 flag would fail to accept connections from curl and wget on Linux. Co-authored-by: rdementi <25432609+rdementi@users.noreply.github.com> --- src/pcm-sensor-server.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pcm-sensor-server.cpp b/src/pcm-sensor-server.cpp index febbf2a1..b060d16b 100644 --- a/src/pcm-sensor-server.cpp +++ b/src/pcm-sensor-server.cpp @@ -1467,7 +1467,6 @@ class Server { int retval = 0; if (useIPv4) { -#ifdef _WIN32 // Use IPv4 struct sockaddr_in serv4; memset(&serv4, 0, sizeof(serv4)); @@ -1479,13 +1478,16 @@ class Server { if ( 1 != ::inet_pton( AF_INET, listenIP_.c_str(), &(serv4.sin_addr) ) ) { DBG( 3, "close clientsocketFD" ); +#ifdef _WIN32 + closesocket(sockfd); +#else ::close(sockfd); +#endif throw std::runtime_error(std::string("Server Constructor: Cannot convert IP string ") + listenIP_ + " to IPv4 address"); } } socklen_t len = sizeof( struct sockaddr_in ); retval = ::bind( sockfd, reinterpret_cast(&serv4), len ); -#endif } else { // Use IPv6 struct sockaddr_in6 serv; From b6d6a9f2c954b010680ebde8239479684994c984 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 14 Nov 2025 11:40:58 +0100 Subject: [PATCH 2/3] improve the thread-per-core detection on systems where the HT sibling of the first core is offlined pcm fails with the error: PCM ERROR. Exception ERROR: Core: thread_id 1 cannot be larger than 1. This change fixes it by looking at all cores and detecting if there are any cores with the same core id. Change-Id: I237e84741d1de738f57ea3f18aa18a9b1f964206 --- src/cpucounters.cpp | 35 ++++++++++++++++++++++++++++++----- src/topologyentry.h | 28 ++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index b45b5e78..a7445f0f 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -1495,15 +1495,40 @@ bool PCM::discoverSystemTopology() std::cerr << topology[i].socket_id << " " << topology[i].os_id << " " << topology[i].core_id << "\n"; } #endif - if (threads_per_core == 0) + assert(threads_per_core == 0); // make sure it is not initialized yet + // copy the topology array to a temp object + auto sortedTopology = topology; + std::sort(sortedTopology.begin(), sortedTopology.end()); + // find out max number of threads per core given that the topologyCopy is sorted now + assert(sortedTopology.size() > 0); + auto currentCore = sortedTopology.begin(); + while (currentCore != sortedTopology.end()) + { + if (currentCore->os_id == -1 || currentCore->core_id == -1 || currentCore->socket_id == -1) // offlined core + { + ++currentCore; + continue; + } + break; + } + assert(currentCore != sortedTopology.end()); + int current_threads_per_core = 0; + for (auto firstCore = *currentCore;currentCore != sortedTopology.end(); ++currentCore) { - for (int i = 0; i < (int)num_cores; ++i) + DBG(3, "Examining core: os_id=", currentCore->os_id, ", core_id=", currentCore->core_id, ", socket_id=", currentCore->socket_id); + if (currentCore->isSameCore(firstCore)) + { + ++current_threads_per_core; + } + else { - if (topology[i].isSameCore( topology[0] )) - ++threads_per_core; + threads_per_core = (std::max)(threads_per_core, current_threads_per_core); + firstCore = *currentCore; + current_threads_per_core = 1; } - assert(threads_per_core != 0); } + threads_per_core = (std::max)(threads_per_core, current_threads_per_core); + assert(threads_per_core != 0); if(num_phys_cores_per_socket == 0 && num_cores == num_online_cores) num_phys_cores_per_socket = num_cores / num_sockets / threads_per_core; if(num_online_cores == 0) num_online_cores = num_cores; diff --git a/src/topologyentry.h b/src/topologyentry.h index 1e7094b9..4c94d4ca 100644 --- a/src/topologyentry.h +++ b/src/topologyentry.h @@ -78,24 +78,40 @@ struct PCM_API TopologyEntry // describes a core } return "unknown"; } - bool isSameSocket( TopologyEntry& te ) { + bool isSameSocket( TopologyEntry& te ) const { return this->socket_id == te.socket_id; } - bool isSameDieGroup( TopologyEntry& te ) { + bool isSameDieGroup( TopologyEntry& te ) const { return this->die_grp_id == te.die_grp_id && isSameSocket(te); } - bool isSameDie( TopologyEntry& te ) { + bool isSameDie( TopologyEntry& te ) const { return this->die_id == te.die_id && isSameDieGroup(te); } - bool isSameTile( TopologyEntry& te ) { + bool isSameTile( TopologyEntry& te ) const { return this->tile_id == te.tile_id && isSameDie(te); } - bool isSameModule( TopologyEntry& te ) { + bool isSameModule( TopologyEntry& te ) const { return this->module_id == te.module_id && isSameTile (te); } - bool isSameCore( TopologyEntry& te ) { + bool isSameCore( TopologyEntry& te ) const { return this->core_id == te.core_id && isSameModule(te); } + bool operator <(const TopologyEntry& other) const + { + if (socket_id != other.socket_id) + return socket_id < other.socket_id; + if (die_grp_id != other.die_grp_id) + return die_grp_id < other.die_grp_id; + if (die_id != other.die_id) + return die_id < other.die_id; + if (tile_id != other.tile_id) + return tile_id < other.tile_id; + if (module_id != other.module_id) + return module_id < other.module_id; + if (core_id != other.core_id) + return core_id < other.core_id; + return thread_id < other.thread_id; + } }; inline void fillEntry(TopologyEntry & entry, const uint32 & smtMaskWidth, const uint32 & coreMaskWidth, const uint32 & l2CacheMaskShift, const int apic_id) From b81b5751b2a29d4efe1e3d6ed997ce600f455797 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 14 Nov 2025 12:25:02 +0100 Subject: [PATCH 3/3] Update src/cpucounters.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/cpucounters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index a7445f0f..859bee6d 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -1513,7 +1513,7 @@ bool PCM::discoverSystemTopology() } assert(currentCore != sortedTopology.end()); int current_threads_per_core = 0; - for (auto firstCore = *currentCore;currentCore != sortedTopology.end(); ++currentCore) + for (auto firstCore = *currentCore; currentCore != sortedTopology.end(); ++currentCore) { DBG(3, "Examining core: os_id=", currentCore->os_id, ", core_id=", currentCore->core_id, ", socket_id=", currentCore->socket_id); if (currentCore->isSameCore(firstCore))