kernel: Use std::list for semaphore

This commit is contained in:
IndecisiveTurtle 2024-08-26 00:13:01 +03:00
parent 5c1de381c4
commit 833a366e3b
3 changed files with 20 additions and 22 deletions

View File

@ -2,9 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <condition_variable> #include <condition_variable>
#include <list>
#include <mutex> #include <mutex>
#include <utility>
#include <boost/intrusive/list.hpp>
#include <pthread.h> #include <pthread.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
@ -13,9 +12,6 @@
namespace Libraries::Kernel { namespace Libraries::Kernel {
using ListBaseHook =
boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>;
class Semaphore { class Semaphore {
public: public:
Semaphore(s32 init_count, s32 max_count, std::string_view name, bool is_fifo) Semaphore(s32 init_count, s32 max_count, std::string_view name, bool is_fifo)
@ -37,7 +33,7 @@ public:
// Create waiting thread object and add it into the list of waiters. // Create waiting thread object and add it into the list of waiters.
WaitingThread waiter{need_count, is_fifo}; WaitingThread waiter{need_count, is_fifo};
AddWaiter(waiter); AddWaiter(&waiter);
// Perform the wait. // Perform the wait.
return waiter.Wait(lk, timeout); return waiter.Wait(lk, timeout);
@ -52,14 +48,14 @@ public:
// Wake up threads in order of priority. // Wake up threads in order of priority.
for (auto it = wait_list.begin(); it != wait_list.end();) { for (auto it = wait_list.begin(); it != wait_list.end();) {
auto& waiter = *it; auto* waiter = *it;
if (waiter.need_count > token_count) { if (waiter->need_count > token_count) {
it++; it++;
continue; continue;
} }
it = wait_list.erase(it); it = wait_list.erase(it);
token_count -= waiter.need_count; token_count -= waiter->need_count;
waiter.cv.notify_one(); waiter->cv.notify_one();
} }
return true; return true;
@ -70,9 +66,9 @@ public:
if (num_waiters) { if (num_waiters) {
*num_waiters = wait_list.size(); *num_waiters = wait_list.size();
} }
for (auto& waiter : wait_list) { for (auto* waiter : wait_list) {
waiter.was_cancled = true; waiter->was_cancled = true;
waiter.cv.notify_one(); waiter->cv.notify_one();
} }
wait_list.clear(); wait_list.clear();
token_count = set_count < 0 ? init_count : set_count; token_count = set_count < 0 ? init_count : set_count;
@ -80,7 +76,7 @@ public:
} }
public: public:
struct WaitingThread : public ListBaseHook { struct WaitingThread {
std::condition_variable cv; std::condition_variable cv;
u32 priority; u32 priority;
s32 need_count; s32 need_count;
@ -132,7 +128,7 @@ public:
} }
}; };
void AddWaiter(WaitingThread& waiter) { void AddWaiter(WaitingThread* waiter) {
// Insert at the end of the list for FIFO order. // Insert at the end of the list for FIFO order.
if (is_fifo) { if (is_fifo) {
wait_list.push_back(waiter); wait_list.push_back(waiter);
@ -140,16 +136,13 @@ public:
} }
// Find the first with priority less then us and insert right before it. // Find the first with priority less then us and insert right before it.
auto it = wait_list.begin(); auto it = wait_list.begin();
while (it != wait_list.end() && it->priority > waiter.priority) { while (it != wait_list.end() && (*it)->priority > waiter->priority) {
it++; it++;
} }
wait_list.insert(it, waiter); wait_list.insert(it, waiter);
} }
using WaitingThreads = std::list<WaitingThread*> wait_list;
boost::intrusive::list<WaitingThread, boost::intrusive::base_hook<ListBaseHook>,
boost::intrusive::constant_time_size<false>>;
WaitingThreads wait_list;
std::string name; std::string name;
std::atomic<s32> token_count; std::atomic<s32> token_count;
std::mutex mutex; std::mutex mutex;

View File

@ -167,7 +167,7 @@ struct Liverpool {
static constexpr auto* GetBinaryInfo(const Shader& sh) { static constexpr auto* GetBinaryInfo(const Shader& sh) {
const auto* code = sh.template Address<u32*>(); const auto* code = sh.template Address<u32*>();
const auto* bininfo = std::bit_cast<const BinaryInfo*>(code + (code[1] + 1) * 2); const auto* bininfo = std::bit_cast<const BinaryInfo*>(code + (code[1] + 1) * 2);
ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header"); // ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header");
return bininfo; return bininfo;
} }

View File

@ -250,7 +250,12 @@ void PipelineCache::RefreshGraphicsKey() {
infos[i] = nullptr; infos[i] = nullptr;
continue; continue;
} }
const auto* bininfo = Liverpool::GetBinaryInfo(*pgm);
if (!bininfo->Valid()) {
key.stage_hashes[i] = 0;
infos[i] = nullptr;
continue;
}
const auto stage = Shader::Stage{i}; const auto stage = Shader::Stage{i};
std::tie(infos[i], modules[i], key.stage_hashes[i]) = GetProgram(pgm, stage, binding); std::tie(infos[i], modules[i], key.stage_hashes[i]) = GetProgram(pgm, stage, binding);
} }