Advertisement
Guest User

Untitled

a guest
Nov 25th, 2012
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.52 KB | None | 0 0
  1. -- uniprim.cpp
  2. #include<uniprim.h>
  3.  
  4. bool CAS(void *data, uint32_t cmp1, uint32_t rep1)
  5. {
  6. bool ret1 = false;
  7. _asm
  8. {
  9. mov esi, data;
  10. mov eax, cmp1;
  11. mov ecx, rep1;
  12. lock cmpxchg [esi], ecx;
  13. jz suc;
  14. mov ret1, 0
  15. jmp end;
  16. suc:
  17. mov ret1, 1;
  18. end:
  19. }
  20. return ret1;
  21. }
  22.  
  23. bool CAS2(void *data, uint32_t cmp1, uint32_t cmp2, uint32_t rep1, uint32_t rep2)
  24. {
  25. bool ret1 = false;
  26. _asm
  27. {
  28. push ebx;
  29. mov esi, data;
  30. mov eax, cmp1;
  31. mov edx, cmp2;
  32. mov ebx, rep1;
  33. mov ecx, rep2;
  34. lock cmpxchg8b [esi];
  35. jz suc;
  36. mov ret1, 0
  37. jmp end;
  38. suc:
  39. mov ret1, 1;
  40. end:
  41. pop ebx;
  42. }
  43. return ret1;
  44. }
  45.  
  46. -- uniprim.h
  47. #pragma once
  48.  
  49. #include<stdint.h>
  50.  
  51. // Universal primitives
  52. bool CAS(void *ptr, uint32_t cmp, uint32_t rep);
  53. bool CAS2(void *ptr, uint32_t cmp1, uint32_t cmp2, uint32_t rep1, uint32_t rep2);
  54.  
  55. -- queue.h
  56. #pragma once
  57.  
  58. #include<uniprim.h>
  59.  
  60. // This is thread safe
  61. template<typename T, T N> class Queue
  62. {
  63. public:
  64. Queue() : m_pHead(0), m_pTail(0), m_cPushes(0), m_cPops(0) { }
  65.  
  66. // Practically copied out of game programming gems 6
  67. void Add(T data)
  68. {
  69. node<T> *pNode = new node<T>;
  70. pNode->m_pNext = NULL;
  71. pNode->m_data = data;
  72.  
  73. uint32_t cPushes;
  74. uint32_t cPops;
  75. node<T> *pTail;
  76.  
  77. while (true)
  78. {
  79. cPushes = m_cPushes;
  80. cPops = m_cPops;
  81. pTail = (node<T>*)m_pTail;
  82. if (cPushes != m_cPushes)
  83. continue;
  84.  
  85. if (!pTail)
  86. if (CAS2(&m_pTail, NULL, cPushes, (uint32_t)pNode, cPushes +1))
  87. break;
  88. else if (CAS(&pTail->m_pNext, NULL, (uint32_t)pNode))
  89. break;
  90. else
  91. CAS2(&m_pTail, (uint32_t)pTail, cPushes, (uint32_t)pTail->m_pNext, cPushes + 1);
  92. }
  93.  
  94. CAS2(&m_pHead, NULL, cPops, (uint32_t)pNode, cPops + 1);
  95. CAS2(&m_pTail, (uint32_t)pTail, cPushes, (uint32_t)pNode, cPushes + 1);
  96. }
  97.  
  98. T Remove(void)
  99. {
  100. node<T> *pHead;
  101. while (true)
  102. {
  103. uint32_t cPops = m_cPops;
  104. uint32_t cPushes = m_cPushes;
  105. pHead = (node<T>*)m_pHead;
  106. if (cPops != m_cPops)
  107. continue;
  108. node<T> *pNext = pHead->m_pNext;
  109.  
  110. if (pHead == m_pTail)
  111. CAS2(&m_pTail, (uint32_t)pHead, cPushes, (uint32_t)pNext, cPushes + 1);
  112.  
  113. if (CAS2(&m_pHead, (uint32_t)pHead, cPops, (uint32_t)pNext, cPops + 1))
  114. {
  115. T data = pHead->m_data;
  116. delete pHead;
  117. return data;
  118. }
  119. }
  120. return (T)N;
  121. }
  122.  
  123. private:
  124. template<class T> struct node
  125. {
  126. T m_data;
  127. node<T> *m_pNext;
  128. };
  129.  
  130. volatile node<T> *m_pHead;
  131. volatile unsigned int m_cPops;
  132. volatile node<T> *m_pTail;
  133. volatile unsigned int m_cPushes;
  134. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement