#include "xsched/utils/common.h"
#include "xsched/preempt/hal/hw_queue.h"
#include "xsched/preempt/xqueue/xqueue.h"
using namespace xsched::preempt;
std::mutex HwQueueManager::mtx_;
std::unordered_map<HwQueueHandle, std::shared_ptr<HwQueue>> HwQueueManager::hwqs_;
XResult HwQueueManager::Add(HwQueueHandle hwq_h, std::function<std::shared_ptr<HwQueue>()> create)
{
std::lock_guard<std::mutex> lock(mtx_);
auto it = hwqs_.find(hwq_h);
if (it != hwqs_.end()) {
XWARN("HwQueue with handle 0x" FMT_64X " already exists", hwq_h);
return kXSchedSuccess;
}
auto hwq = create();
if (hwq == nullptr) {
XWARN("Fail to create HwQueue with handle 0x" FMT_64X, hwq_h);
return kXSchedErrorUnknown;
}
XASSERT(hwq->GetHandle() == hwq_h, "HwQueue handle mismatch");
hwqs_[hwq_h] = hwq;
return kXSchedSuccess;
}
XResult HwQueueManager::Del(HwQueueHandle hwq_h)
{
std::lock_guard<std::mutex> lock(mtx_);
auto it = hwqs_.find(hwq_h);
if (it == hwqs_.end()) {
XWARN("HwQueue with handle 0x" FMT_64X " does not exist", hwq_h);
return kXSchedErrorNotFound;
}
auto xq_shptr = it->second->GetXQueue();
if (xq_shptr != nullptr) {
XWARN("HwQueue (0x" FMT_64X ") is still associated with XQueue (0x" FMT_64X "), "
"please first destroy the XQueue using XQueueDestroy()",
hwq_h, xq_shptr->GetHandle());
return kXSchedErrorNotAllowed;
}
hwqs_.erase(it);
return kXSchedSuccess;
}
std::shared_ptr<HwQueue> HwQueueManager::Get(HwQueueHandle hwq_h)
{
std::lock_guard<std::mutex> lock(mtx_);
auto it = hwqs_.find(hwq_h);
if (it == hwqs_.end()) return nullptr;
return it->second;
}
std::shared_ptr<XQueue> HwQueueManager::GetXQueue(HwQueueHandle hwq_h)
{
std::shared_ptr<HwQueue> hwq_shptr = Get(hwq_h);
if (!hwq_shptr) return nullptr;
return hwq_shptr->GetXQueue();
}
EXPORT_C_FUNC XResult HwQueueDestroy(HwQueueHandle hwq)
{
return HwQueueManager::Del(hwq);
}
EXPORT_C_FUNC XResult HwQueueLaunch(HwQueueHandle hwq, HwCommandHandle hw_cmd)
{
std::shared_ptr<HwQueue> hwq_shptr = HwQueueManager::Get(hwq);
if (hwq_shptr == nullptr) {
XWARN("HwQueue with handle 0x" FMT_64X " does not exist", hwq);
return kXSchedErrorNotFound;
}
std::shared_ptr<HwCommand> hw_cmd_shptr = HwCommandManager::Del(hw_cmd);
if (hw_cmd_shptr == nullptr) {
XWARN("HwCommand with handle 0x" FMT_64X " does not exist or not registered", hw_cmd);
return kXSchedErrorNotFound;
}
auto callback = std::dynamic_pointer_cast<HwCallbackCommand>(hw_cmd_shptr);
if (callback != nullptr) return callback->Launch(hwq);
hwq_shptr->Launch(hw_cmd_shptr);
return kXSchedSuccess;
}
EXPORT_C_FUNC XResult HwQueueSynchronize(HwQueueHandle hwq)
{
std::shared_ptr<HwQueue> hwq_shptr = HwQueueManager::Get(hwq);
if (hwq_shptr == nullptr) {
XWARN("HwQueue with handle 0x" FMT_64X " does not exist", hwq);
return kXSchedErrorNotFound;
}
hwq_shptr->Synchronize();
return kXSchedSuccess;
}