mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Threading: Remove a level of indirection from Promise and Mailbox.
Makes using small copyable or POD objects in these more efficient, and if you want to you can just put a pointer or smart pointer in there, which will effectively do the same thing as the old setup.
This commit is contained in:
parent
20c3c8f291
commit
4f85b8b2ef
@ -9,6 +9,7 @@
|
||||
// well as a simple blocking mailbox. Let's see if we get there.
|
||||
|
||||
// Single item mailbox.
|
||||
// T is copyable. Often T will itself just be a pointer or smart pointer of some sort.
|
||||
template<class T>
|
||||
struct Mailbox {
|
||||
Mailbox() : refcount_(1) {}
|
||||
@ -18,9 +19,9 @@ struct Mailbox {
|
||||
|
||||
std::mutex mutex_;
|
||||
std::condition_variable condvar_;
|
||||
T *data_ = nullptr;
|
||||
T data_ = nullptr;
|
||||
|
||||
T *Wait() {
|
||||
T Wait() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
while (!data_) {
|
||||
condvar_.wait(lock);
|
||||
@ -28,7 +29,7 @@ struct Mailbox {
|
||||
return data_;
|
||||
}
|
||||
|
||||
bool Poll(T **data) {
|
||||
bool Poll(T *data) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
if (data_) {
|
||||
*data = data_;
|
||||
@ -38,7 +39,7 @@ struct Mailbox {
|
||||
}
|
||||
}
|
||||
|
||||
bool Send(T *data) {
|
||||
bool Send(T data) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
if (!data_) {
|
||||
data_ = data;
|
||||
|
@ -9,7 +9,7 @@
|
||||
template<class T>
|
||||
class PromiseTask : public Task {
|
||||
public:
|
||||
PromiseTask(std::function<T *()> fun, Mailbox<T> *tx) : fun_(fun), tx_(tx) {
|
||||
PromiseTask(std::function<T ()> fun, Mailbox<T> *tx) : fun_(fun), tx_(tx) {
|
||||
tx_->AddRef();
|
||||
}
|
||||
~PromiseTask() {
|
||||
@ -17,11 +17,11 @@ public:
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
T *value = fun_();
|
||||
T value = fun_();
|
||||
tx_->Send(value);
|
||||
}
|
||||
|
||||
std::function<T *()> fun_;
|
||||
std::function<T ()> fun_;
|
||||
Mailbox<T> *tx_;
|
||||
};
|
||||
|
||||
@ -32,7 +32,7 @@ public:
|
||||
template<class T>
|
||||
class Promise {
|
||||
public:
|
||||
static Promise<T> *Spawn(ThreadManager *threadman, std::function<T *()> fun, TaskType taskType) {
|
||||
static Promise<T> *Spawn(ThreadManager *threadman, std::function<T()> fun, TaskType taskType) {
|
||||
Mailbox<T> *mailbox = new Mailbox<T>();
|
||||
|
||||
Promise<T> *promise = new Promise<T>();
|
||||
@ -50,8 +50,8 @@ public:
|
||||
delete data_;
|
||||
}
|
||||
|
||||
// Returns *T if the data is ready, nullptr if it's not.
|
||||
T *Poll() {
|
||||
// Returns T if the data is ready, nullptr if it's not.
|
||||
T Poll() {
|
||||
if (ready_) {
|
||||
return data_;
|
||||
} else {
|
||||
@ -66,7 +66,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
T *BlockUntilReady() {
|
||||
T BlockUntilReady() {
|
||||
if (ready_) {
|
||||
return data_;
|
||||
} else {
|
||||
@ -81,7 +81,7 @@ public:
|
||||
private:
|
||||
Promise() {}
|
||||
|
||||
T *data_ = nullptr;
|
||||
T data_ = nullptr;
|
||||
bool ready_ = false;
|
||||
Mailbox<T> *rx_;
|
||||
};
|
||||
|
@ -645,7 +645,7 @@ UI::EventReturn ConfirmMemstickMoveScreen::OnConfirm(UI::EventParams ¶ms) {
|
||||
if (moveData_) {
|
||||
progressReporter_.Set(iz->T("Starting move..."));
|
||||
|
||||
moveDataTask_ = Promise<MoveResult>::Spawn(&g_threadManager, [&]() -> MoveResult * {
|
||||
moveDataTask_ = Promise<MoveResult *>::Spawn(&g_threadManager, [&]() -> MoveResult * {
|
||||
Path moveSrc = g_Config.memStickDirectory;
|
||||
Path moveDest = newMemstickFolder_;
|
||||
if (moveSrc.GetFilename() != "PSP") {
|
||||
|
@ -130,7 +130,7 @@ private:
|
||||
ProgressReporter progressReporter_;
|
||||
UI::TextView *progressView_ = nullptr;
|
||||
|
||||
Promise<MoveResult> *moveDataTask_ = nullptr;
|
||||
Promise<MoveResult *> *moveDataTask_ = nullptr;
|
||||
|
||||
std::string error_;
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ ResultObject *ResultProducer() {
|
||||
}
|
||||
|
||||
bool TestMailbox() {
|
||||
Mailbox<ResultObject> *mailbox = new Mailbox<ResultObject>();
|
||||
Mailbox<ResultObject *> *mailbox = new Mailbox<ResultObject *>();
|
||||
mailbox->Send(new ResultObject{ true });
|
||||
ResultObject *data;
|
||||
data = mailbox->Wait();
|
||||
@ -60,7 +60,7 @@ bool TestThreadManager() {
|
||||
ThreadManager manager;
|
||||
manager.Init(8, 1);
|
||||
|
||||
Promise<ResultObject> *object(Promise<ResultObject>::Spawn(&manager, &ResultProducer, TaskType::IO_BLOCKING));
|
||||
Promise<ResultObject *> *object(Promise<ResultObject *>::Spawn(&manager, &ResultProducer, TaskType::IO_BLOCKING));
|
||||
|
||||
if (!TestParallelLoop(&manager)) {
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user