00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "charm.h"
00013
00016 template <typename type>
00017 class CkPoolQueue {
00018 type *first;
00019 int sz;
00020 int classSize;
00021 void *allocations;
00022
00023 CkPoolQueue() {}
00024 public:
00025 CkPoolQueue(int _sz) : first(NULL), sz(_sz), allocations(NULL) { CkAssert(_sz > 0); }
00026 void enqueue(type *p) {
00027
00028 *(type**)p = first;
00029 first = p;
00030 }
00031 type *dequeue(size_t size) {
00032 if (first == NULL) {
00033 classSize = size;
00034
00035 first = (type*)malloc(sz * ALIGN8(size) + sizeof(void*));
00036 type **src;
00037 type *dest;
00038 for (int i=0; i<sz-1; ++i) {
00039 src = (type**)(((char*)first)+i*ALIGN8(size));
00040 dest = (type*)(((char*)first)+(i+1)*ALIGN8(size));
00041
00042 *src = dest;
00043 }
00044 src = (type**)(((char*)first)+(sz-1)*ALIGN8(size));
00045
00046 *src = NULL;
00047
00048 void **nextAlloc = (void**)(((char*)first) + sz*ALIGN8(size));
00049 *nextAlloc = allocations;
00050 allocations = (void*)first;
00051 }
00052
00053 type *ret = first;
00054 first = *(type**)first;
00055 return ret;
00056 }
00057 void destroyAll() {
00058 void *next;
00059 first = NULL;
00060 while (allocations != NULL) {
00061 next = *(void**)(((char*)allocations) + sz*ALIGN8(classSize));
00062 free(allocations);
00063 allocations = next;
00064 }
00065 }
00066 };
00067
00068
00069 template <typename type> class CkMultiPool;
00070
00076 template <typename type, unsigned int sz = 16>
00077 class CkPool {
00078 static CkPoolQueue<type> buffer;
00079 public:
00080
00081 void *operator new(size_t size) {
00082 void *ret = buffer.dequeue(size);
00083
00084 return ret;
00085 }
00086 void *operator new(size_t size, void *p) {
00087 return p;
00088 }
00089 void operator delete(void *p, size_t size) {
00090
00091 buffer.enqueue((type*)p);
00092 }
00093 friend class CkMultiPool<type>;
00094 static void destroyAll();
00095 };
00096
00097 template <typename type, unsigned int sz>
00098 CkPoolQueue<type> CkPool<type,sz>::buffer = CkPoolQueue<type>(sz);
00099
00100 template <typename type, unsigned int sz>
00101 void CkPool<type,sz>::destroyAll() {
00102
00103 buffer.destroyAll();
00104 }
00105
00110 template <typename type>
00111 class CkMultiPool {
00112 public:
00113 void *operator new(size_t sz) {
00114 type *ret = CkPool<type>::buffer.dequeue(sz+sizeof(CkPoolQueue<type>*));
00115 CkPoolQueue<type> **bufferP = (CkPoolQueue<type> **)(ALIGN8((int)((char*)ret)+sz+sizeof(CkPoolQueue<type>*)) - sizeof(CkPoolQueue<type>*));
00116 *bufferP = &CkPool<type>::buffer;
00117
00118 return ret;
00119 }
00120 void *operator new(size_t sz, CkPoolQueue<type> *buf) {
00121 type *ret = buf->dequeue(sz+sizeof(CkPoolQueue<type>*));
00122 CkPoolQueue<type> **bufferP = (CkPoolQueue<type> **)(ALIGN8((int)((char*)ret)+sz+sizeof(CkPoolQueue<type>*)) - sizeof(CkPoolQueue<type>*));
00123 *bufferP = buf;
00124
00125 return ret;
00126 }
00127 void *operator new(size_t size, void *p) {
00128 return p;
00129 }
00130 void operator delete(void *p, size_t sz) {
00131 CkPoolQueue<type> **bufferP = (CkPoolQueue<type> **)(ALIGN8((int)((char*)p)+sz+sizeof(CkPoolQueue<type>*)) - sizeof(CkPoolQueue<type>*));
00132
00133 (*bufferP)->enqueue((type*)p);
00134 }
00135 };