mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-03 10:45:36 +00:00
This patch implements the default implementation of WaitableEvent (AsyncWaitableEvent) with std::condition_variable instead of std::future as std::future will always block its destructor until the async function returns, which makes us unable to clean up all the execution environment of the async task inside the async function. This patch also implements WorkerThreadTaskManager to manage all the async tasks (inherited from WorkerThreadTask) in the future, for example all the Create*PipelineAsync() tasks. This patch also updates the related dawn_unittest WorkerThreadTest. Basic. BUG=dawn:529 TEST=dawn_unittests Change-Id: Ie789ba788789e91128ffc416e7e768923828a367 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/51740 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
98 lines
2.7 KiB
C++
98 lines
2.7 KiB
C++
// Copyright 2021 The Dawn Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "dawn_platform/WorkerThread.h"
|
|
|
|
#include <condition_variable>
|
|
#include <functional>
|
|
#include <thread>
|
|
|
|
#include "common/Assert.h"
|
|
|
|
namespace {
|
|
|
|
class AsyncWaitableEventImpl {
|
|
public:
|
|
AsyncWaitableEventImpl() : mIsComplete(false) {
|
|
}
|
|
|
|
void Wait() {
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
mCondition.wait(lock, [this] { return mIsComplete; });
|
|
}
|
|
|
|
bool IsComplete() {
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mIsComplete;
|
|
}
|
|
|
|
void MarkAsComplete() {
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
mIsComplete = true;
|
|
}
|
|
mCondition.notify_all();
|
|
}
|
|
|
|
private:
|
|
std::mutex mMutex;
|
|
std::condition_variable mCondition;
|
|
bool mIsComplete;
|
|
};
|
|
|
|
class AsyncWaitableEvent final : public dawn_platform::WaitableEvent {
|
|
public:
|
|
explicit AsyncWaitableEvent()
|
|
: mWaitableEventImpl(std::make_shared<AsyncWaitableEventImpl>()) {
|
|
}
|
|
|
|
void Wait() override {
|
|
mWaitableEventImpl->Wait();
|
|
}
|
|
|
|
bool IsComplete() override {
|
|
return mWaitableEventImpl->IsComplete();
|
|
}
|
|
|
|
std::shared_ptr<AsyncWaitableEventImpl> GetWaitableEventImpl() const {
|
|
return mWaitableEventImpl;
|
|
}
|
|
|
|
private:
|
|
std::shared_ptr<AsyncWaitableEventImpl> mWaitableEventImpl;
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
namespace dawn_platform {
|
|
|
|
std::unique_ptr<dawn_platform::WaitableEvent> AsyncWorkerThreadPool::PostWorkerTask(
|
|
dawn_platform::PostWorkerTaskCallback callback,
|
|
void* userdata) {
|
|
std::unique_ptr<AsyncWaitableEvent> waitableEvent = std::make_unique<AsyncWaitableEvent>();
|
|
|
|
std::function<void()> doTask =
|
|
[callback, userdata, waitableEventImpl = waitableEvent->GetWaitableEventImpl()]() {
|
|
callback(userdata);
|
|
waitableEventImpl->MarkAsComplete();
|
|
};
|
|
|
|
std::thread thread(doTask);
|
|
thread.detach();
|
|
|
|
return waitableEvent;
|
|
}
|
|
|
|
} // namespace dawn_platform
|