From 259fd2a64bf114907017fe286702218cdf13c8ca Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Tue, 15 Jan 2019 15:53:45 +0100 Subject: move source code to src/ --- src/benchmarks/cpuinfo.h | 202 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 src/benchmarks/cpuinfo.h (limited to 'src/benchmarks/cpuinfo.h') diff --git a/src/benchmarks/cpuinfo.h b/src/benchmarks/cpuinfo.h new file mode 100644 index 0000000..1ed1f36 --- /dev/null +++ b/src/benchmarks/cpuinfo.h @@ -0,0 +1,202 @@ +// -*- C++ -*- + +/* + + Heap Layers: An Extensible Memory Allocation Infrastructure + + Copyright (C) 2000-2003 by Emery Berger + http://www.cs.umass.edu/~emery + emery@cs.umass.edu + + This program 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 2 of the License, or + (at your option) any later version. + + This program 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + + + +#ifndef HL_CPUINFO_H +#define HL_CPUINFO_H + +#if defined(_WIN32) +#include +#include +#else +#include +#endif + + +#if !defined(_WIN32) +#include +#endif + +#if defined(__SVR4) // Solaris +#include +extern "C" unsigned int lwp_self(void); +#include +extern "C" int _thr_self(void); +#endif + +#if defined(__linux) +#include +#include +#include +#include +#include +#endif + +#if defined(__APPLE__) +#include +#include +#endif + +#if defined(__sgi) +#include +#include +#include +#endif + +#if defined(hpux) +#include +#endif + +#if defined(_WIN32) +extern __declspec(thread) int localThreadId; +#endif + +#if defined(__SVR4) && defined(MAP_ALIGN) +extern volatile int anyThreadStackCreated; +#endif + +namespace HL { + +/** + * @class CPUInfo + * @author Emery Berger + * + * @brief Architecture-independent wrapper to get number of CPUs. + */ + +class CPUInfo { +public: + CPUInfo (void) + {} + + inline static int getNumProcessors (void) { + static int _numProcessors = computeNumProcessors(); + return _numProcessors; + } + + static inline unsigned long getThreadId (void); + inline static int computeNumProcessors (void); + +}; + + +int CPUInfo::computeNumProcessors (void) +{ + static int np = 0; + if (!np) { +#if defined(__linux) || defined(__APPLE__) + np = (int) sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_WIN32) + SYSTEM_INFO infoReturn[1]; + GetSystemInfo (infoReturn); + np = (int) (infoReturn->dwNumberOfProcessors); +#elif defined(__sgi) + np = (int) sysmp(MP_NAPROCS); +#elif defined(hpux) + np = mpctl(MPC_GETNUMSPUS, NULL, NULL); // or pthread_num_processors_np()? +#elif defined(_SC_NPROCESSORS_ONLN) + np = (int) (sysconf(_SC_NPROCESSORS_ONLN)); +#else + np = 2; + // Unsupported platform. + // Pretend we have at least two processors. This approach avoids the risk of assuming + // we're on a uniprocessor, which might lead clever allocators to avoid using atomic + // operations for all locks. +#endif + return np; + } else { + return np; + } +} + + // Note: when stacksize arg is NULL for pthread_attr_setstacksize [Solaris], +// stack size is 1 MB for 32-bit arch, 2 MB for 64-bit arch. +// pthread_attr_getstacksize +// pthread_attr_setstackaddr +// pthread_attr_getstackaddr +// PTHREAD_STACK_SIZE is minimum. +// or should we just assume we have __declspec(thread) or __thread? + +#if defined(USE_THREAD_KEYWORD) + extern __thread int localThreadId; +#endif + + // FIX ME FIXME + //#include + +unsigned long CPUInfo::getThreadId (void) { +#if defined(__SVR4) + size_t THREAD_STACK_SIZE; + if (sizeof(size_t) <= 4) { + THREAD_STACK_SIZE = 1048576; + } else { + // 64-bits. + THREAD_STACK_SIZE = 1048576 * 2; + } + if (0) { // !anyThreadStackCreated) { + // We know a priori that all stack variables + // are on different stacks. Since no one has created + // a special one, we are in control, and thus all stacks + // are 1 MB in size and on 1 MB boundaries. + // (Actually: 1 MB for 32-bits, 2 MB for 64-bits.) + char buf; + return (((size_t) &buf) & ~(THREAD_STACK_SIZE-1)) >> 20; + } else { + return (int) pthread_self(); + } +#elif defined(_WIN32) + // It looks like thread id's are always multiples of 4, so... + return GetCurrentThreadId() >> 2; +#elif defined(__APPLE__) + // Consecutive thread id's in Mac OS are 4096 apart; + // dividing off the 4096 gives us an appropriate thread id. + int tid = (int) ((unsigned long) pthread_self()) >> 12; + return tid; +#elif defined(__BEOS__) + return find_thread(0); +#elif defined(USE_THREAD_KEYWORD) + return localThreadId; +#elif defined(__linux) || defined(PTHREAD_KEYS_MAX) + // Consecutive thread id's in Linux are 1024 apart; + // dividing off the 1024 gives us an appropriate thread id. + return (unsigned long) pthread_self() >> 10; +#elif defined(POSIX) + return (unsigned long) pthread_self(); +#elif USE_SPROC + // This hairiness has the same effect as calling getpid(), + // but it's MUCH faster since it avoids making a system call + // and just accesses the sproc-local data directly. + unsigned long pid = (unsigned long) PRDA->sys_prda.prda_sys.t_pid; + return pid; +#else + return 0; +#endif +} + +} + +#endif -- cgit v1.2.3