Eneboo - Documentación para desarrolladores
|
00001 /* -*- C++ -*- */ 00002 00003 #ifndef _THREADHEAP_H_ 00004 #define _THREADHEAP_H_ 00005 00006 #include <assert.h> 00007 #include <new> 00008 00009 #if !defined(_WIN32) 00010 #include <pthread.h> 00011 #endif 00012 00013 #if defined(__SVR4) // Solaris 00014 extern "C" unsigned int lwp_self(void); 00015 #endif 00016 00017 /* 00018 00019 A ThreadHeap comprises NumHeaps "per-thread" heaps. 00020 00021 To pick a per-thread heap, the current thread id is hashed (mod NumHeaps). 00022 00023 malloc gets memory from its hashed per-thread heap. 00024 free returns memory to its hashed per-thread heap. 00025 00026 (This allows the per-thread heap to determine the return 00027 policy -- 'pure private heaps', 'private heaps with ownership', 00028 etc.) 00029 00030 NB: We assume that the thread heaps are 'locked' as needed. */ 00031 00032 namespace HL { 00033 00034 template <int NumHeaps, class PerThreadHeap> 00035 class ThreadHeap : public PerThreadHeap { 00036 public: 00037 00038 inline void * malloc (size_t sz) { 00039 int tid = getThreadId() % NumHeaps; 00040 assert (tid >= 0); 00041 assert (tid < NumHeaps); 00042 return getHeap(tid)->malloc (sz); 00043 } 00044 00045 inline void free (void * ptr) { 00046 int tid = getThreadId() % NumHeaps; 00047 assert (tid >= 0); 00048 assert (tid < NumHeaps); 00049 getHeap(tid)->free (ptr); 00050 } 00051 00052 inline size_t getSize (void * ptr) { 00053 int tid = getThreadId() % NumHeaps; 00054 assert (tid >= 0); 00055 assert (tid < NumHeaps); 00056 return getHeap(tid)->getSize (ptr); 00057 } 00058 00059 00060 private: 00061 00062 // Access the given heap within the buffer. 00063 inline PerThreadHeap * getHeap (int index) { 00064 assert (index >= 0); 00065 assert (index < NumHeaps); 00066 return &ptHeaps[index]; 00067 } 00068 00069 // Get a suitable thread id number. 00070 inline static volatile int getThreadId (void); 00071 00072 PerThreadHeap ptHeaps[NumHeaps]; 00073 00074 }; 00075 00076 } 00077 00078 00079 // A platform-dependent way to get a thread id. 00080 00081 // Include the necessary platform-dependent crud. 00082 #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) 00083 #ifndef WIN32 00084 #define WIN32 1 00085 #endif 00086 #include <windows.h> 00087 #include <process.h> 00088 #endif 00089 00090 template <int NumHeaps, class PerThreadHeap> 00091 inline volatile int 00092 HL::ThreadHeap<NumHeaps, PerThreadHeap>::getThreadId (void) { 00093 #if defined(WIN32) 00094 // It looks like thread id's are always multiples of 4, so... 00095 int tid = GetCurrentThreadId() >> 2; 00096 // Now hash in some of the first bits. 00097 // return (tid & ~(1024-1)) ^ tid; 00098 return tid; 00099 #endif 00100 #if defined(__BEOS__) 00101 return find_thread(0); 00102 #endif 00103 #if defined(__linux) 00104 // Consecutive thread id's in Linux are 1024 apart; 00105 // dividing off the 1024 gives us an appropriate thread id. 00106 return (int) pthread_self() >> 10; // (>> 10 = / 1024) 00107 #endif 00108 #if defined(__SVR4) 00109 // printf ("lwp_self = %d\n", (int) lwp_self()); 00110 return (int) lwp_self(); 00111 #endif 00112 #if defined(__APPLE__) 00113 return (int) pthread_self(); 00114 #endif 00115 #if defined(POSIX) 00116 return (int) pthread_self(); 00117 #endif 00118 #if USE_SPROC 00119 // This hairiness has the same effect as calling getpid(), 00120 // but it's MUCH faster since it avoids making a system call 00121 // and just accesses the sproc-local data directly. 00122 int pid = (int) PRDA->sys_prda.prda_sys.t_pid; 00123 return pid; 00124 #endif 00125 } 00126 00127 00128 #endif