Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #pragma once
00015
00019 #include <iostream>
00020 #include "Atomics.h"
00021
00022 namespace kNet
00023 {
00024
00025 template<typename T>
00026 struct PoolAllocatable
00027 {
00028 T *next;
00029 };
00030
00032 template<typename T>
00033 class LockFreePoolAllocator
00034 {
00035 public:
00036 LockFreePoolAllocator()
00037 :root(0)
00038 {
00039 }
00040
00041 ~LockFreePoolAllocator()
00042 {
00043 UnsafeClearAll();
00044 }
00045
00048 T *New()
00049 {
00050 if (!root)
00051 {
00052 T *n = new T();
00053 return n;
00054 }
00055
00056 T *allocated;
00057 T *newRoot;
00058
00059 do
00060 {
00061 allocated = root;
00062 newRoot = root->next;
00063 } while(CmpXChgPointer((void**)&root, newRoot, allocated) == false);
00064
00065 assert(allocated != root);
00066 return allocated;
00067 }
00068
00069 void Free(T *ptr)
00070 {
00071 if (!ptr)
00072 return;
00073
00074 assert(ptr != root);
00075 T *top;
00076
00077 do
00078 {
00079 top = root;
00080 ptr->next = top;
00081 } while(CmpXChgPointer((void**)&root, ptr, top) == false);
00082 }
00083
00087 void ClearAll()
00088 {
00089 assert(!DebugHasCycle());
00090 while(root)
00091 {
00092 T *node = New();
00093 delete node;
00094 }
00095 }
00096
00099 void UnsafeClearAll()
00100 {
00101 assert(!DebugHasCycle());
00102 T *node = root;
00103 while(node)
00104 {
00105 T *next = node->next;
00106 delete node;
00107 node = next;
00108 }
00109 root = 0;
00110 }
00111
00113 bool DebugHasCycle()
00114 {
00115 T *n1 = root;
00116 if (!n1)
00117 return false;
00118 T *n2 = n1->next;
00119 while(n2 != 0)
00120 {
00121 if (n1 == n2)
00122 return true;
00123
00124 n1 = n1->next;
00125 n2 = n2->next;
00126 if (n2)
00127 n2 = n2->next;
00128 }
00129 return false;
00130 }
00131
00133 void DumpPool()
00134 {
00135 using namespace std;
00136
00137 T *node = root;
00138 cout << "Root: 0x" << ios::hex << root << ".Next: " << ios::hex << (root ? root->next : 0) << std::endl;
00139 int size = 0;
00140 if (node)
00141 node = node->next;
00142 while(node)
00143 {
00144 cout << "Node: 0x" << ios::hex << node << ".Next: " << ios::hex << (node ? node->next : 0) << std::endl;
00145 node = node->next;
00146 ++size;
00147 }
00148 cout << "Total: " << size << " elements." << endl;
00149 }
00150
00151 private:
00152 T * volatile root;
00153 };
00154
00155 }