2727#include " opencl/source/helpers/hardware_commands_helper.h"
2828#include " opencl/source/mem_obj/mem_obj.h"
2929
30+ #include < algorithm>
31+
3032namespace NEO {
3133
3234Event::Event (
@@ -417,23 +419,26 @@ void Event::getBoundaryTimestampValues(TimestampPacketContainer *timestampContai
417419 }
418420}
419421
420- inline bool Event::wait (bool blocking, bool useQuickKmdSleep) {
422+ inline WaitStatus Event::wait (bool blocking, bool useQuickKmdSleep) {
421423 while (this ->taskCount == CompletionStamp::notReady) {
422424 if (blocking == false ) {
423- return false ;
425+ return WaitStatus::NotReady ;
424426 }
425427 }
426428
427429 Range<CopyEngineState> states{&bcsState, bcsState.isValid () ? 1u : 0u };
428- cmdQueue->waitUntilComplete (taskCount.load (), states, flushStamp->peekStamp (), useQuickKmdSleep);
430+ const auto waitStatus = cmdQueue->waitUntilComplete (taskCount.load (), states, flushStamp->peekStamp (), useQuickKmdSleep);
431+ if (waitStatus == WaitStatus::GpuHang) {
432+ return WaitStatus::GpuHang;
433+ }
429434 updateExecutionStatus ();
430435
431436 DEBUG_BREAK_IF (this ->taskLevel == CompletionStamp::notReady && this ->executionStatus >= 0 );
432437
433438 auto *allocationStorage = cmdQueue->getGpgpuCommandStreamReceiver ().getInternalAllocationStorage ();
434439 allocationStorage->cleanAllocationList (this ->taskCount , TEMPORARY_ALLOCATION);
435440
436- return true ;
441+ return WaitStatus::Ready ;
437442}
438443
439444void Event::updateExecutionStatus () {
@@ -630,16 +635,23 @@ cl_int Event::waitForEvents(cl_uint numEvents,
630635 // pointers to workerLists - for fast swap operations
631636 WorkerListT *currentlyPendingEvents = &workerList1;
632637 WorkerListT *pendingEventsLeft = &workerList2;
638+ WaitStatus eventWaitStatus = WaitStatus::NotReady;
633639
634640 while (currentlyPendingEvents->size () > 0 ) {
635- for (auto &e : * currentlyPendingEvents) {
636- Event *event = castToObjectOrAbort<Event>(e );
641+ for (auto current = currentlyPendingEvents-> begin (), end = currentlyPendingEvents-> end (); current != end; ++current ) {
642+ Event *event = castToObjectOrAbort<Event>(*current );
637643 if (event->peekExecutionStatus () < CL_COMPLETE) {
638644 return CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST;
639645 }
640646
641- if (event->wait (false , false ) == false ) {
647+ eventWaitStatus = event->wait (false , false );
648+ if (eventWaitStatus == WaitStatus::NotReady) {
642649 pendingEventsLeft->push_back (event);
650+ } else if (eventWaitStatus == WaitStatus::GpuHang) {
651+ setExecutionStatusToAbortedDueToGpuHang (pendingEventsLeft->begin (), pendingEventsLeft->end ());
652+ setExecutionStatusToAbortedDueToGpuHang (current, end);
653+
654+ return CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST;
643655 }
644656 }
645657
@@ -650,6 +662,13 @@ cl_int Event::waitForEvents(cl_uint numEvents,
650662 return CL_SUCCESS;
651663}
652664
665+ inline void Event::setExecutionStatusToAbortedDueToGpuHang (cl_event *first, cl_event *last) {
666+ std::for_each (first, last, [](cl_event &e) {
667+ Event *event = castToObjectOrAbort<Event>(e);
668+ event->transitionExecutionStatus (executionAbortedDueToGpuHang);
669+ });
670+ }
671+
653672uint32_t Event::getTaskLevel () {
654673 return taskLevel;
655674}
0 commit comments