Guest User

Untitled

a guest
Dec 15th, 2018
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.05 KB | None | 0 0
  1. template<class T>
  2. class LockFreeDispatchStackMPMC
  3. {
  4. public:
  5. LockFreeDispatchStackMPMC()
  6. {
  7. Head = NULL;
  8. }
  9. ~LockFreeDispatchStackMPMC(){
  10. }
  11. void Send(T *item)
  12. {
  13. Node<T> * new_node = Cache.Malloc();
  14. new_node->Data=item;
  15. bool done = false;
  16. while(!done)
  17. {
  18. auto head = Head.load();
  19. new_node->Next.store( head);
  20. if( Head.compare_exchange_weak(head,new_node))
  21. {
  22. done = true;
  23. }
  24. }
  25. }
  26.  
  27. T *Recieve()
  28. {
  29. T *returnValue = NULL;
  30. bool done = false;
  31. while(!done)
  32. {
  33. auto head = Head.load();
  34. if(head == NULL)
  35. {
  36. done=true;
  37. }
  38. else
  39. {
  40. Node<T> * curr = head;
  41. Node<T> *next = curr->Next.load();
  42. if(Head.compare_exchange_weak(head,next))
  43. {
  44. done = true;
  45. returnValue = curr->Data;
  46. curr->Next =NULL;
  47. Cache.Free(curr);
  48. }
  49.  
  50. }
  51. }
  52. return returnValue;
  53. }
  54. public:
  55. std::atomic<Node<T> *> Head;
  56.  
  57. private:
  58. LockFreeMemCache<Node<T> > Cache;
  59. };
  60.  
  61. #define GROW_BY_SIZE 4
  62.  
  63. template<class T>
  64. class LockFreeCacheMPMC
  65. {
  66. public:
  67. LockFreeCacheMPMC()
  68. {
  69. Head=NULL;
  70. FreeStack=NULL;
  71. AddSomeCache();
  72. }
  73. ~LockFreeCacheMPMC()
  74. {
  75. Node<T> *node ,*prev;
  76.  
  77. bool done = false;
  78. node = Head;
  79. prev = NULL;
  80. while(!done)
  81. {
  82. prev = node;
  83. if(node == NULL)
  84. {
  85. done = true;
  86. }
  87. else
  88. {
  89. node = node->Next.load();
  90. delete prev->Data;
  91. delete prev;
  92. }
  93. }
  94. done = false;
  95. node = FreeStack;
  96. prev = NULL;
  97. while(!done)
  98. {
  99. prev = node;
  100. if(node == NULL)
  101. {
  102. done = true;
  103. }
  104. else
  105. {
  106. node = node->Next.load();
  107. delete prev;
  108. }
  109. }
  110. }
  111. T *Malloc()
  112. {
  113. T *returnValue = NULL;
  114. returnValue=Pop();
  115. while(returnValue==NULL)
  116. {
  117. AddSomeCache();
  118. returnValue=Pop();
  119. }
  120. return returnValue;
  121. }
  122. void Free(T *ptr)
  123. {
  124. Push(ptr);
  125. }
  126.  
  127. private:
  128. void AddSomeCache()
  129. {
  130.  
  131. for(int i=0; i < GROW_BY_SIZE; i++)
  132. {
  133. T *tmp = new T();
  134. Push(tmp);
  135. }
  136. }
  137.  
  138. private:
  139. void Push(T *item)
  140. {
  141. Node<T> * new_node = PopNode(true);
  142. new_node->Data=item;
  143.  
  144. bool done = false;
  145. while(!done)
  146. {
  147. Node<T>* head = Head.load();
  148. new_node->Next.store(head);
  149. if(Head.compare_exchange_weak(head,new_node))
  150. {
  151. done = true;
  152. }
  153. }
  154. }
  155. T *Pop()
  156. {
  157. T *returnValue = NULL;
  158. bool done = false;
  159. while(!done)
  160. {
  161. Node<T> * curr= Head.load();
  162. if(curr == NULL)
  163. {
  164. done=true;
  165. }
  166. else
  167. {
  168. Node<T> *next = curr->Next.load();
  169. if(Head.compare_exchange_weak(curr,next))
  170. {
  171. done = true;
  172. returnValue = curr->Data;
  173. PushNode(curr);
  174. }
  175. }
  176. }
  177. return returnValue;
  178. }
  179.  
  180. void PushNode(Node<T> *item)
  181. {
  182. item->Next = NULL;
  183. item->Data = NULL;
  184. bool done = false;
  185. while(!done)
  186. {
  187. Node<T>* fs = FreeStack.load();
  188. item->Next.store(fs);
  189. if(FreeStack.compare_exchange_weak(fs,item))
  190. {
  191. done = true;
  192. }
  193. }
  194. }
  195. Node<T> *PopNode(bool Alloc)
  196. {
  197. Node<T> *returnValue = NULL;
  198.  
  199. bool done = false;
  200. while(!done)
  201. {
  202. Node<T> *fs = FreeStack.load();
  203. if(fs == NULL)
  204. {
  205. done=true;
  206. }
  207. else
  208. {
  209. Node<T> *next = fs->Next.load();
  210. if(FreeStack.compare_exchange_weak(fs,next))
  211. {
  212. done = true;
  213. returnValue = fs;
  214. }
  215.  
  216. }
  217. }
  218. if ((returnValue == NULL) &&Alloc )
  219. {
  220. returnValue =new Node<T>();
  221. returnValue->Data = NULL;
  222. returnValue->Next = NULL;
  223. }
  224. return returnValue;
  225. }
  226. std::atomic<Node<T> *> Head;
  227. std::atomic<Node<T> *>FreeStack;
  228. };
  229.  
  230. template<class T>
  231. class LockFreeQueueMPMC
  232. {
  233. public:
  234. LockFreeQueueMPMC()
  235. {
  236. Head=NULL;
  237. }
  238. ~LockFreeQueueMPMC(){
  239. }
  240. void Enqueue(T *item)
  241. {
  242. Node<T> * new_node = Cache.Malloc();
  243. new_node->Data=item;
  244.  
  245. bool done = false;
  246. while(!done)
  247. {
  248. auto head = Head.load();
  249. new_node->Next.store(head);
  250. if(Head.compare_exchange_weak(head,new_node))
  251. {
  252. done = true;
  253. }
  254. }
  255. }
  256. T *Dequeue()
  257. {
  258. T *returnValue=NULL;
  259. bool done = false;
  260. while(!done)
  261. {
  262. auto head = Head.load();
  263. if(head == NULL)
  264. {
  265. done = true;
  266. }
  267. else
  268. {
  269. std::atomic<Node<T> *> prev, curr;
  270. prev.store(NULL);
  271. curr = head;
  272. bool found = false;
  273. while(!found)
  274. {
  275. auto c = curr.load();
  276. if(c == NULL)
  277. {
  278. break;
  279. }
  280. auto n = c->Next.load();
  281. if(n == NULL)
  282. {
  283. found=true;
  284. break;
  285. }
  286. prev.store(c);
  287. curr.store(n);
  288. }
  289. if(found)
  290. {
  291. if(prev == NULL)
  292. {
  293. if(Head.compare_exchange_weak(head,NULL))
  294. {
  295. done = true;
  296. }
  297. }
  298. else
  299. {
  300. auto p = prev.load();
  301. auto c = curr.load();
  302. if(p->Next.compare_exchange_weak(c,NULL))
  303. {
  304. done = true;
  305. }
  306. }
  307. if(done)
  308. {
  309. auto c = curr.load();
  310. returnValue = c->Data;
  311. Cache.Free(c);
  312. }
  313. }
  314. }
  315. }
  316. return returnValue;
  317. }
  318. private:
  319. std::atomic<Node<T> *> Head;
  320. LockFreeMemCache<Node<T> > Cache;
  321. };
Add Comment
Please, Sign In to add comment