15 #include <condition_variable>
19 #if ALPAKA_DEBUG >= ALPAKA_DEBUG_MINIMAL
25 namespace generic::detail
28 template<
typename TDev>
45 auto wait(std::size_t
const& enqueueCount, std::unique_lock<std::mutex>& lk)
const noexcept ->
void
71 template<
typename TDev>
79 :
m_spEventImpl(std::make_shared<generic::detail::EventGenericThreadsImpl<TDev>>(dev))
90 return !((*this) == rhs);
94 std::shared_ptr<generic::detail::EventGenericThreadsImpl<TDev>>
m_spEventImpl;
100 template<
typename TDev>
107 template<
typename TDev>
112 return event.m_spEventImpl->m_dev;
117 template<
typename TDev>
123 std::lock_guard<std::mutex> lk(event.m_spEventImpl->m_mutex);
125 return event.m_spEventImpl->isReady();
130 template<
typename TDev>
142 auto spEventImpl =
event.m_spEventImpl;
145 std::lock_guard<std::mutex> lk(spEventImpl->m_mutex);
147 ++spEventImpl->m_enqueueCount;
149 auto const enqueueCount = spEventImpl->m_enqueueCount;
152 spEventImpl->m_future = queueImpl.m_workerThread.submit(
153 [spEventImpl, enqueueCount]()
mutable
155 std::unique_lock<std::mutex> lk2(spEventImpl->m_mutex);
158 if(enqueueCount == spEventImpl->m_enqueueCount)
160 spEventImpl->m_LastReadyEnqueueCount
161 =
std::max(enqueueCount, spEventImpl->m_LastReadyEnqueueCount);
168 template<
typename TDev>
182 template<
typename TDev>
191 std::promise<void> promise;
193 std::lock_guard<std::mutex> lk(queueImpl.m_mutex);
195 queueImpl.m_bCurrentlyExecutingTask =
true;
197 auto& eventImpl(*event.m_spEventImpl);
201 std::lock_guard<std::mutex> evLk(eventImpl.m_mutex);
203 ++eventImpl.m_enqueueCount;
205 eventImpl.m_LastReadyEnqueueCount = eventImpl.m_enqueueCount;
207 eventImpl.m_future = promise.get_future();
210 queueImpl.m_bCurrentlyExecutingTask =
false;
217 template<
typename TDev>
235 template<
typename TDev>
240 auto vQueues = dev.getAllQueues();
243 std::vector<EventGenericThreads<TDev>> vEvents;
244 for(
auto&& spQueue : vQueues)
246 vEvents.emplace_back(dev);
247 spQueue->enqueue(vEvents.back());
251 for(
auto&& event : vEvents)
262 template<
typename TDev>
267 wait(*event.m_spEventImpl);
277 template<
typename TDev>
283 std::unique_lock<std::mutex> lk(eventImpl.m_mutex);
285 auto const enqueueCount = eventImpl.m_enqueueCount;
286 eventImpl.wait(enqueueCount, lk);
291 template<
typename TDev>
303 auto spEventImpl =
event.m_spEventImpl;
305 std::lock_guard<std::mutex> lk(spEventImpl->m_mutex);
307 if(!spEventImpl->isReady())
309 auto oldFuture = spEventImpl->m_future;
312 queueImpl.m_workerThread.submit([oldFuture]() { oldFuture.get(); });
318 template<
typename TDev>
325 wait(*queue.m_spQueueImpl, event);
330 template<
typename TDev>
338 wait(*event.m_spEventImpl);
343 template<
typename TDev>
350 wait(*queue.m_spQueueImpl, event);
358 template<
typename TDev>
365 auto vspQueues(dev.getAllQueues());
370 for(
auto&& spQueue : vspQueues)
372 spQueue->wait(event);
381 template<
typename TDev>
390 auto f = queue.m_spQueueImpl->m_workerThread.submit([]() noexcept {});
#define ALPAKA_ASSERT(...)
The assert can be explicit disabled by defining NDEBUG.
#define ALPAKA_DEBUG_MINIMAL_LOG_SCOPE
EventGenericThreads(TDev const &dev, [[maybe_unused]] bool bBusyWaiting=true)
std::shared_ptr< generic::detail::EventGenericThreadsImpl< TDev > > m_spEventImpl
auto operator==(EventGenericThreads< TDev > const &rhs) const -> bool
auto operator!=(EventGenericThreads< TDev > const &rhs) const -> bool
The CPU device event implementation.
auto isReady() noexcept -> bool
std::size_t m_LastReadyEnqueueCount
The time this event has been ready the last time. Ready means that the event was not waiting within a...
std::shared_future< void > m_future
The future signaling the event completion.
EventGenericThreadsImpl(EventGenericThreadsImpl< TDev > const &)=delete
std::mutex m_mutex
The mutex used to synchronize access to the event.
std::size_t m_enqueueCount
The number of times this event has been enqueued.
EventGenericThreadsImpl(TDev dev) noexcept
TDev const m_dev
The device this event is bound to.
auto wait(std::size_t const &enqueueCount, std::unique_lock< std::mutex > &lk) const noexcept -> void
auto operator=(EventGenericThreadsImpl< TDev > const &) -> EventGenericThreadsImpl< TDev > &=delete
The CPU device queue implementation.
The CPU device queue implementation.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto max(T const &max_ctx, Tx const &x, Ty const &y)
Returns the larger of two arguments. NaNs are treated as missing data (between a NaN and a numeric va...
ALPAKA_FN_HOST auto currentThreadWaitForDevice(TDev const &dev) -> void
The alpaka accelerator library.
ALPAKA_FN_HOST auto enqueue(TQueue &queue, TTask &&task) -> void
Queues the given task in the given queue.
ALPAKA_FN_HOST auto wait(TAwaited const &awaited) -> void
Waits the thread for the completion of the given awaited action to complete.
Tag used in class inheritance hierarchies that describes that a specific interface (TInterface) is im...
static ALPAKA_FN_HOST auto currentThreadWaitFor(EventGenericThreads< TDev > const &event) -> void
static ALPAKA_FN_HOST auto currentThreadWaitFor(QueueGenericThreadsNonBlocking< TDev > const &queue) -> void
static ALPAKA_FN_HOST auto currentThreadWaitFor(alpaka::generic::detail::EventGenericThreadsImpl< TDev > const &eventImpl) -> void
static ALPAKA_FN_HOST auto enqueue(QueueGenericThreadsBlocking< TDev > &queue, EventGenericThreads< TDev > &event) -> void
static ALPAKA_FN_HOST auto enqueue(QueueGenericThreadsNonBlocking< TDev > &queue, EventGenericThreads< TDev > &event) -> void
static ALPAKA_FN_HOST auto enqueue(alpaka::generic::detail::QueueGenericThreadsBlockingImpl< TDev > &queueImpl, EventGenericThreads< TDev > &event) -> void
static ALPAKA_FN_HOST auto enqueue([[maybe_unused]] alpaka::generic::detail::QueueGenericThreadsNonBlockingImpl< TDev > &queueImpl, EventGenericThreads< TDev > &event) -> void
static ALPAKA_FN_HOST auto getDev(EventGenericThreads< TDev > const &event) -> TDev
static ALPAKA_FN_HOST auto isComplete(EventGenericThreads< TDev > const &event) -> bool
static ALPAKA_FN_HOST auto waiterWaitFor(QueueGenericThreadsBlocking< TDev > &queue, EventGenericThreads< TDev > const &event) -> void
static ALPAKA_FN_HOST auto waiterWaitFor(QueueGenericThreadsNonBlocking< TDev > &queue, EventGenericThreads< TDev > const &event) -> void
static ALPAKA_FN_HOST auto waiterWaitFor(TDev &dev, EventGenericThreads< TDev > const &event) -> void
static ALPAKA_FN_HOST auto waiterWaitFor(alpaka::generic::detail::QueueGenericThreadsBlockingImpl< TDev > &, EventGenericThreads< TDev > const &event) -> void
static ALPAKA_FN_HOST auto waiterWaitFor(alpaka::generic::detail::QueueGenericThreadsNonBlockingImpl< TDev > &queueImpl, EventGenericThreads< TDev > const &event) -> void