SPIRV-Cross/include/spirv_cross/thread_group.hpp

114 lines
2.0 KiB
C++
Raw Normal View History

2016-03-02 17:09:16 +00:00
/*
* Copyright 2015-2016 ARM Limited
*
* 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.
*/
#ifndef SPIRV_CROSS_THREAD_GROUP_HPP
#define SPIRV_CROSS_THREAD_GROUP_HPP
2016-03-02 17:09:16 +00:00
#include <condition_variable>
#include <mutex>
2016-05-23 11:30:02 +00:00
#include <thread>
2016-03-02 17:09:16 +00:00
namespace spirv_cross
2016-03-02 17:09:16 +00:00
{
template <typename T, unsigned Size>
class ThreadGroup
{
public:
ThreadGroup(T *impl)
{
for (unsigned i = 0; i < Size; i++)
workers[i].start(&impl[i]);
}
2016-03-02 17:09:16 +00:00
void run()
{
for (auto &worker : workers)
worker.run();
}
2016-03-02 17:09:16 +00:00
void wait()
{
for (auto &worker : workers)
worker.wait();
}
2016-03-02 17:09:16 +00:00
private:
struct Thread
{
enum State
{
Idle,
Running,
Dying
};
State state = Idle;
2016-03-02 17:09:16 +00:00
void start(T *impl)
{
2016-05-23 11:30:02 +00:00
worker = std::thread([impl, this] {
for (;;)
{
{
std::unique_lock<std::mutex> l{ lock };
cond.wait(l, [this] { return state != Idle; });
if (state == Dying)
break;
}
2016-03-02 17:09:16 +00:00
2016-05-23 11:30:02 +00:00
impl->main();
2016-03-02 17:09:16 +00:00
2016-05-23 11:30:02 +00:00
std::lock_guard<std::mutex> l{ lock };
state = Idle;
cond.notify_one();
}
});
}
2016-03-02 17:09:16 +00:00
void wait()
{
std::unique_lock<std::mutex> l{ lock };
2016-05-23 11:30:02 +00:00
cond.wait(l, [this] { return state == Idle; });
}
2016-03-02 17:09:16 +00:00
void run()
{
std::lock_guard<std::mutex> l{ lock };
state = Running;
cond.notify_one();
}
2016-03-02 17:09:16 +00:00
~Thread()
{
if (worker.joinable())
{
{
std::lock_guard<std::mutex> l{ lock };
state = Dying;
cond.notify_one();
}
worker.join();
}
}
std::thread worker;
std::condition_variable cond;
std::mutex lock;
};
Thread workers[Size];
};
2016-03-02 17:09:16 +00:00
}
#endif