implement EnumerateCores()

Index: rts/System/Platform/CpuID.cpp
--- rts/System/Platform/CpuID.cpp.orig
+++ rts/System/Platform/CpuID.cpp
@@ -10,6 +10,11 @@
 	#include <intrin.h>
 #endif
 
+#ifdef __OpenBSD__
+	#include <sys/types.h>
+	#include <sys/sysctl.h>
+#endif
+
 #include "System/Threading/SpringThreading.h"
 #include "System/UnorderedSet.hpp"
 
@@ -34,7 +39,7 @@ namespace springproc {
 	// NOLINTNEXTLINE{readability-non-const-parameter}
 	_noinline void ExecCPUID(unsigned int* a, unsigned int* b, unsigned int* c, unsigned int* d)
 	{
-		#ifndef __APPLE__
+		#if !defined(__APPLE__) && !defined(__OpenBSD__)
 		__asm__ __volatile__(
 			"cpuid"
 			: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
@@ -96,6 +101,16 @@ namespace springproc {
 	}
 
 	void CPUID::EnumerateCores() {
+#ifdef __OpenBSD__
+		int mib[2] = { CTL_HW, HW_NCPUONLINE };
+		size_t len = sizeof(numLogicalCores);
+		// XXX: currently assumes that hyperthreading is disabled and numLogicalCores == numPhysicalCores
+		if (sysctl(mib, 2, &numLogicalCores, &len, (void *) 0, 0) != 0) std::abort();
+
+		numPhysicalCores = numLogicalCores;
+		numPerformanceCores = 0;	// XXX: not supported at the moment
+		smtDetected = 0;	// XXX: assumed as disabled for now
+#else
 		processorMasks = cpu_topology::GetProcessorMasks();
 		processorCaches = cpu_topology::GetProcessorCache();
 
@@ -119,6 +134,7 @@ namespace springproc {
 		numPerformanceCores = std::popcount(perfCoreCountMask);
 
 		smtDetected = !!( processorMasks.hyperThreadLowMask | processorMasks.hyperThreadHighMask );
+#endif
 	}
 
 }
