| 105 | } |
| 106 | |
| 107 | int32 GPUTasksManager::RequestWork(GPUTask** buffer, int32 maxCount) |
| 108 | { |
| 109 | const auto b1Index = _bufferIndex; |
| 110 | const auto b2Index = (_bufferIndex + 1) % 2; |
| 111 | auto& b1 = _buffers[b1Index]; |
| 112 | auto& b2 = _buffers[b2Index]; |
| 113 | |
| 114 | // Take maximum amount of tasks to the buffer at once |
| 115 | ASSERT(b1.IsEmpty()); |
| 116 | const int32 takenTasksCount = (int32)_tasks.try_dequeue_bulk(b1.Get(), maxCount); |
| 117 | b2.Add(b1.Get(), takenTasksCount); |
| 118 | |
| 119 | int32 count = 0; |
| 120 | |
| 121 | // Filter taken tasks to keep maxTotalComplexity limit |
| 122 | b1.Clear(); |
| 123 | int32 i = 0; |
| 124 | for (; i < b2.Count() && count < maxCount; i++) |
| 125 | { |
| 126 | auto task = b2[i]; |
| 127 | const auto state = task->GetState(); |
| 128 | switch (state) |
| 129 | { |
| 130 | case TaskState::Failed: |
| 131 | case TaskState::Canceled: |
| 132 | case TaskState::Finished: |
| 133 | // Skip task |
| 134 | break; |
| 135 | case TaskState::Queued: |
| 136 | // Run queued task |
| 137 | buffer[count++] = task; |
| 138 | break; |
| 139 | case TaskState::Created: |
| 140 | case TaskState::Running: |
| 141 | default: |
| 142 | // Keep task for the next RequestWork |
| 143 | b1.Add(task); |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | const int32 itemsLeft = b2.Count() - i; |
| 148 | if (itemsLeft > 0) |
| 149 | b1.Add(&b2[i], itemsLeft); |
| 150 | b2.Clear(); |
| 151 | |
| 152 | // Swap buffers |
| 153 | _bufferIndex = b2Index; |
| 154 | |
| 155 | return count; |
| 156 | } |
| 157 | |
| 158 | String GPUTasksManager::ToString() const |
| 159 | { |