diff options
Diffstat (limited to 'offload/liboffload/src/OffloadImpl.cpp')
-rw-r--r-- | offload/liboffload/src/OffloadImpl.cpp | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index 6486b2b..f5365ca 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -72,6 +72,8 @@ struct ol_queue_impl_t { struct ol_event_impl_t { ol_event_impl_t(void *EventInfo, ol_queue_handle_t Queue) : EventInfo(EventInfo), Queue(Queue) {} + // EventInfo may be null, in which case the event should be considered always + // complete void *EventInfo; ol_queue_handle_t Queue; }; @@ -206,7 +208,7 @@ Error initPlugins(OffloadContext &Context) { } Error olInit_impl() { - std::lock_guard<std::mutex> Lock{OffloadContextValMutex}; + std::lock_guard<std::mutex> Lock(OffloadContextValMutex); if (isOffloadInitialized()) { OffloadContext::get().RefCount++; @@ -224,7 +226,7 @@ Error olInit_impl() { } Error olShutDown_impl() { - std::lock_guard<std::mutex> Lock{OffloadContextValMutex}; + std::lock_guard<std::mutex> Lock(OffloadContextValMutex); if (--OffloadContext::get().RefCount != 0) return Error::success(); @@ -485,16 +487,13 @@ Error olSyncQueue_impl(ol_queue_handle_t Queue) { // Host plugin doesn't have a queue set so it's not safe to call synchronize // on it, but we have nothing to synchronize in that situation anyway. if (Queue->AsyncInfo->Queue) { - if (auto Err = Queue->Device->Device->synchronize(Queue->AsyncInfo)) + // We don't need to release the queue and we would like the ability for + // other offload threads to submit work concurrently, so pass "false" here + // so we don't release the underlying queue object. + if (auto Err = Queue->Device->Device->synchronize(Queue->AsyncInfo, false)) return Err; } - // Recreate the stream resource so the queue can be reused - // TODO: Would be easier for the synchronization to (optionally) not release - // it to begin with. - if (auto Res = Queue->Device->Device->initAsyncInfo(&Queue->AsyncInfo)) - return Res; - return Error::success(); } @@ -509,8 +508,8 @@ Error olWaitEvents_impl(ol_queue_handle_t Queue, ol_event_handle_t *Events, return Plugin::error(ErrorCode::INVALID_NULL_HANDLE, "olWaitEvents asked to wait on a NULL event"); - // Do nothing if the event is for this queue - if (Event->Queue == Queue) + // Do nothing if the event is for this queue or the event is always complete + if (Event->Queue == Queue || !Event->EventInfo) continue; if (auto Err = Device->waitEvent(Event->EventInfo, Queue->AsyncInfo)) @@ -528,6 +527,12 @@ Error olGetQueueInfoImplDetail(ol_queue_handle_t Queue, switch (PropName) { case OL_QUEUE_INFO_DEVICE: return Info.write<ol_device_handle_t>(Queue->Device); + case OL_QUEUE_INFO_EMPTY: { + auto Pending = Queue->Device->Device->hasPendingWork(Queue->AsyncInfo); + if (auto Err = Pending.takeError()) + return Err; + return Info.write<bool>(!*Pending); + } default: return createOffloadError(ErrorCode::INVALID_ENUMERATION, "olGetQueueInfo enum '%i' is invalid", PropName); @@ -548,6 +553,10 @@ Error olGetQueueInfoSize_impl(ol_queue_handle_t Queue, ol_queue_info_t PropName, } Error olSyncEvent_impl(ol_event_handle_t Event) { + if (!Event->EventInfo) + // Event always complete + return Plugin::success(); + if (auto Res = Event->Queue->Device->Device->syncEvent(Event->EventInfo)) return Res; @@ -555,8 +564,9 @@ Error olSyncEvent_impl(ol_event_handle_t Event) { } Error olDestroyEvent_impl(ol_event_handle_t Event) { - if (auto Res = Event->Queue->Device->Device->destroyEvent(Event->EventInfo)) - return Res; + if (Event->EventInfo) + if (auto Res = Event->Queue->Device->Device->destroyEvent(Event->EventInfo)) + return Res; return olDestroy(Event); } @@ -590,7 +600,16 @@ Error olGetEventInfoSize_impl(ol_event_handle_t Event, ol_event_info_t PropName, } Error olCreateEvent_impl(ol_queue_handle_t Queue, ol_event_handle_t *EventOut) { + auto Pending = Queue->Device->Device->hasPendingWork(Queue->AsyncInfo); + if (auto Err = Pending.takeError()) + return Err; + *EventOut = new ol_event_impl_t(nullptr, Queue); + if (!*Pending) + // Queue is empty, don't record an event and consider the event always + // complete + return Plugin::success(); + if (auto Res = Queue->Device->Device->createEvent(&(*EventOut)->EventInfo)) return Res; @@ -725,7 +744,7 @@ Error olGetSymbol_impl(ol_program_handle_t Program, const char *Name, ol_symbol_kind_t Kind, ol_symbol_handle_t *Symbol) { auto &Device = Program->Image->getDevice(); - std::lock_guard<std::mutex> Lock{Program->SymbolListMutex}; + std::lock_guard<std::mutex> Lock(Program->SymbolListMutex); switch (Kind) { case OL_SYMBOL_KIND_KERNEL: { |