TickQueue.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "TickQueue.h"
  2. #include "Block.h"
  3. TickQueue::TickQueue()
  4. : ReferenceCounter()
  5. {
  6. maxSize = 0;
  7. readPosition = 0;
  8. writePosition = 0;
  9. queue = 0;
  10. exit = 0;
  11. }
  12. TickQueue::~TickQueue()
  13. {
  14. delete[] queue;
  15. }
  16. void TickQueue::startNextTick(Framework::Array<Tickable*>* zSources)
  17. {
  18. std::unique_lock<std::mutex> lk(mutex);
  19. readPosition = 0;
  20. writePosition = 0;
  21. int count = zSources->getEintragAnzahl();
  22. if (count >= maxSize)
  23. {
  24. Tickable** temp = new Tickable*[count + 1000];
  25. memcpy(queue, temp, sizeof(Tickable*) * maxSize);
  26. memset(temp + sizeof(Tickable*) * maxSize,
  27. 0,
  28. sizeof(Tickable*) * (count + 1000 - maxSize));
  29. maxSize = count + 1000;
  30. delete[] queue;
  31. queue = temp;
  32. }
  33. for (Tickable* block : *zSources)
  34. queue[writePosition++] = block;
  35. lk.unlock();
  36. hasBlocks.notify_all();
  37. }
  38. void TickQueue::addToQueue(Tickable* zBlock)
  39. {
  40. std::unique_lock<std::mutex> lk(mutex);
  41. if (writePosition >= maxSize)
  42. {
  43. Tickable** temp = new Tickable*[maxSize + 1000];
  44. memcpy(queue, temp, sizeof(Tickable*) * maxSize);
  45. memset(temp + sizeof(Tickable*) * maxSize, 0, sizeof(Tickable*) * 1000);
  46. maxSize += 1000;
  47. delete[] queue;
  48. queue = temp;
  49. }
  50. queue[writePosition++] = zBlock;
  51. lk.unlock();
  52. hasBlocks.notify_one();
  53. }
  54. Tickable* TickQueue::zNext(bool& waiting)
  55. {
  56. std::unique_lock<std::mutex> lk(mutex);
  57. if (readPosition == writePosition && exit) return 0;
  58. if (readPosition == writePosition)
  59. {
  60. lk.unlock();
  61. hasNoBlocks.notify_all();
  62. lk.lock();
  63. waiting = 1;
  64. if (exit)
  65. {
  66. lk.unlock();
  67. return 0;
  68. }
  69. hasBlocks.wait(
  70. lk, [this] { return readPosition < writePosition || exit; });
  71. waiting = 0;
  72. }
  73. if (readPosition < writePosition) return queue[readPosition++];
  74. return 0;
  75. }
  76. void TickQueue::requestExit()
  77. {
  78. std::unique_lock<std::mutex> lk(mutex);
  79. exit = 1;
  80. lk.unlock();
  81. hasBlocks.notify_all();
  82. hasNoBlocks.notify_all();
  83. }
  84. void TickQueue::waitForEmpty()
  85. {
  86. std::unique_lock<std::mutex> lk(mutex);
  87. if (readPosition != writePosition)
  88. hasNoBlocks.wait(
  89. lk, [this] { return readPosition == writePosition || exit; });
  90. }
  91. void TickQueue::postTick()
  92. {
  93. for (int i = 0; i < writePosition; i++)
  94. queue[i]->postTick();
  95. }