| 1198 | } |
| 1199 | |
| 1200 | void Content::WaitForTask(ContentLoadTask* loadingTask, double timeoutInMilliseconds) |
| 1201 | { |
| 1202 | // Check if call is made from the Loading Thread and task has not been taken yet |
| 1203 | auto thread = ThisLoadThread; |
| 1204 | if (thread != nullptr) |
| 1205 | { |
| 1206 | // Note: to reproduce this case just include material into material (use layering). |
| 1207 | // So during loading first material it will wait for child materials loaded calling this function |
| 1208 | |
| 1209 | const double timeoutInSeconds = timeoutInMilliseconds * 0.001; |
| 1210 | const double startTime = Platform::GetTimeSeconds(); |
| 1211 | int32 loopCounter = 0; |
| 1212 | Task* task = loadingTask; |
| 1213 | Array<ContentLoadTask*, InlinedAllocation<64>> localQueue; |
| 1214 | #define CHECK_CONDITIONS() (!Engine::ShouldExit() && (timeoutInSeconds <= 0.0 || Platform::GetTimeSeconds() - startTime < timeoutInSeconds)) |
| 1215 | do |
| 1216 | { |
| 1217 | #if PLATFORM_THREADS_LIMIT > 1 |
| 1218 | // Give opportunity for other threads to use the current core |
| 1219 | if (loopCounter == 0) |
| 1220 | ; // First run is fast |
| 1221 | else if (loopCounter < 10) |
| 1222 | Platform::Yield(); |
| 1223 | else |
| 1224 | Platform::Sleep(1); |
| 1225 | loopCounter++; |
| 1226 | |
| 1227 | // Try to execute content tasks |
| 1228 | while (task->IsQueued() && CHECK_CONDITIONS()) |
| 1229 | { |
| 1230 | // Dequeue task from the loading queue |
| 1231 | ContentLoadTask* tmp; |
| 1232 | if (LoadTasks.try_dequeue(tmp)) |
| 1233 | { |
| 1234 | if (tmp == task) |
| 1235 | { |
| 1236 | if (localQueue.Count() != 0) |
| 1237 | { |
| 1238 | // Put back queued tasks |
| 1239 | LoadTasks.enqueue_bulk(localQueue.Get(), localQueue.Count()); |
| 1240 | localQueue.Clear(); |
| 1241 | } |
| 1242 | |
| 1243 | PROFILE_CPU_NAMED("Inline"); |
| 1244 | ZoneColor(0xffaaaaaa); |
| 1245 | thread->Run(tmp); |
| 1246 | } |
| 1247 | else |
| 1248 | { |
| 1249 | localQueue.Add(tmp); |
| 1250 | } |
| 1251 | } |
| 1252 | else |
| 1253 | { |
| 1254 | // No task in queue but it's queued so other thread could have stolen it into own local queue |
| 1255 | break; |
| 1256 | } |
| 1257 | } |