Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/util/cpuinfo.h
Ir a la documentación de este archivo.
00001 // -*- C++ -*-
00002 
00003 /*
00004 
00005   Heap Layers: An Extensible Memory Allocation Infrastructure
00006   
00007   Copyright (C) 2000-2003 by Emery Berger
00008   http://www.cs.umass.edu/~emery
00009   emery@cs.umass.edu
00010   
00011   This program is free software; you can redistribute it and/or modify
00012   it under the terms of the GNU General Public License as published by
00013   the Free Software Foundation; either version 2 of the License, or
00014   (at your option) any later version.
00015   
00016   This program is distributed in the hope that it will be useful,
00017   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019   GNU General Public License for more details.
00020   
00021   You should have received a copy of the GNU General Public License
00022   along with this program; if not, write to the Free Software
00023   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025 */
00026 
00027 
00028 
00029 #ifndef _CPUINFO_H_
00030 #define _CPUINFO_H_
00031 
00032 #if defined(_WIN32)
00033 #include <windows.h>
00034 #include <process.h>
00035 #else
00036 #include <unistd.h>
00037 #endif
00038 
00039 
00040 #if !defined(_WIN32)
00041 #include <pthread.h>
00042 #endif
00043 
00044 #if defined(__SVR4) // Solaris
00045 #include <sys/lwp.h>
00046 extern "C" unsigned int lwp_self(void);
00047 #include <thread.h>
00048 extern "C" int _thr_self(void);
00049 #endif
00050 
00051 #if defined(__linux)
00052 #include <sys/types.h>
00053 #include <sys/stat.h>
00054 #include <fcntl.h>
00055 #include <string.h>
00056 #include <unistd.h>
00057 #endif
00058 
00059 #if defined(__APPLE__)
00060 #include <sys/types.h>
00061 #include <sys/sysctl.h>
00062 #endif
00063 
00064 #if defined(__sgi)
00065 #include <sys/types.h>
00066 #include <sys/sysmp.h>
00067 #include <sys/sysinfo.h>
00068 #endif
00069 
00070 #if defined(hpux)
00071 #include <sys/mpctl.h>
00072 #endif
00073 
00074 #if defined(_WIN32)
00075 extern __declspec(thread) int localThreadId;
00076 #endif
00077 
00078 #if defined(__SVR4) && defined(MAP_ALIGN)
00079 extern volatile int anyThreadStackCreated;
00080 #endif
00081 
00082 namespace HL {
00083 
00091 class CPUInfo {
00092 public:
00093   CPUInfo (void)
00094   {}
00095 
00096   inline static int getNumProcessors (void) {
00097     static int _numProcessors = computeNumProcessors();
00098     return _numProcessors;
00099   }
00100 
00101   static inline unsigned long getThreadId (void);
00102   inline static int computeNumProcessors (void);
00103 
00104 };
00105 
00106 
00107 int CPUInfo::computeNumProcessors (void)
00108 {
00109   static int np = 0;
00110   if (!np) {
00111 #if defined(__linux) /*|| defined(__APPLE__)*/
00112     np = (int) sysconf(_SC_NPROCESSORS_ONLN);
00113 #elif defined(_WIN32)
00114     SYSTEM_INFO infoReturn[1];
00115     GetSystemInfo (infoReturn);
00116     np = (int) (infoReturn->dwNumberOfProcessors);
00117 #elif defined(__sgi)
00118     np = (int) sysmp(MP_NAPROCS);
00119 #elif defined(hpux)
00120     np = mpctl(MPC_GETNUMSPUS, NULL, NULL); // or pthread_num_processors_np()?
00121 #elif defined(_SC_NPROCESSORS_ONLN)
00122     np = (int) (sysconf(_SC_NPROCESSORS_ONLN));
00123 #else
00124     np = 2;
00125     // Unsupported platform.
00126     // Pretend we have at least two processors. This approach avoids the risk of assuming
00127     // we're on a uniprocessor, which might lead clever allocators to avoid using atomic
00128     // operations for all locks.
00129 #endif
00130     return np;
00131   } else {
00132     return np;
00133   }
00134 }
00135 
00136   // Note: when stacksize arg is NULL for pthread_attr_setstacksize [Solaris],
00137 // stack size is 1 MB for 32-bit arch, 2 MB for 64-bit arch.
00138 // pthread_attr_getstacksize
00139 // pthread_attr_setstackaddr
00140 // pthread_attr_getstackaddr
00141 // PTHREAD_STACK_SIZE is minimum.
00142 // or should we just assume we have __declspec(thread) or __thread?
00143 
00144 #if defined(USE_THREAD_KEYWORD)
00145   extern __thread int localThreadId;
00146 #endif
00147 
00148 
00149 unsigned long CPUInfo::getThreadId (void) {
00150 #if defined(__SVR4)
00151   size_t THREAD_STACK_SIZE;
00152   if (sizeof(size_t) <= 4) {
00153     THREAD_STACK_SIZE = 1048576;
00154   } else {
00155     // 64-bits.
00156     THREAD_STACK_SIZE = 1048576 * 2;
00157   }
00158   if (0) { // !anyThreadStackCreated) {
00159     // We know a priori that all stack variables
00160     // are on different stacks. Since no one has created
00161     // a special one, we are in control, and thus all stacks
00162     // are 1 MB in size and on 1 MB boundaries.
00163     // (Actually: 1 MB for 32-bits, 2 MB for 64-bits.)
00164     char buf;
00165     return (((size_t) &buf) & ~(THREAD_STACK_SIZE-1)) >> 20;
00166   } else {
00167     return (int) pthread_self();
00168   }
00169 #elif defined(_WIN32)
00170   // It looks like thread id's are always multiples of 4, so...
00171   return GetCurrentThreadId() >> 2;
00172 #elif defined(__APPLE__)
00173   // Consecutive thread id's in Mac OS are 4096 apart;
00174   // dividing off the 4096 gives us an appropriate thread id.
00175   int tid = (int) ((unsigned long) pthread_self()) >> 12;
00176   return tid;
00177 #elif defined(__BEOS__)
00178   return find_thread(0);
00179 #elif defined(USE_THREAD_KEYWORD)
00180   return localThreadId;
00181 #elif defined(__linux) || defined(PTHREAD_KEYS_MAX)
00182   // Consecutive thread id's in Linux are 1024 apart;
00183   // dividing off the 1024 gives us an appropriate thread id.
00184   return (unsigned long) pthread_self() >> 10;
00185 #elif defined(POSIX)
00186   return (unsigned long) pthread_self();
00187 #elif USE_SPROC
00188   // This hairiness has the same effect as calling getpid(),
00189   // but it's MUCH faster since it avoids making a system call
00190   // and just accesses the sproc-local data directly.
00191   unsigned long pid = (unsigned long) PRDA->sys_prda.prda_sys.t_pid;
00192   return pid;
00193 #else
00194   return 0;
00195 #endif
00196 }
00197 
00198 }
00199 
00200 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'