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