| 10 | std::unordered_map<XQueueHandle, std::shared_ptr<XQueue>> XQueueManager::xqs_; |
| 11 | |
| 12 | XResult XQueueManager::Add(XQueueHandle *xq_hp, HwQueueHandle hwq_h, int64_t level, int64_t flags) |
| 13 | { |
| 14 | if (xq_hp == nullptr) return kXSchedErrorInvalidValue; |
| 15 | if (level <= kPreemptLevelUnknown || level >= kPreemptLevelMax) return kXSchedErrorInvalidValue; |
| 16 | |
| 17 | // TODO: implement BlockingXQueue |
| 18 | if (flags & kQueueCreateFlagBlockingSubmit) return kXSchedErrorNotSupported; |
| 19 | |
| 20 | std::lock_guard<std::mutex> lock(mtx_); |
| 21 | std::shared_ptr<HwQueue> hwq_shptr = HwQueueManager::Get(hwq_h); |
| 22 | if (hwq_shptr == nullptr) { |
| 23 | XWARN("HwQueue with handle 0x" FMT_64X " does not exist or not registered", hwq_h); |
| 24 | return kXSchedErrorNotFound; |
| 25 | } |
| 26 | |
| 27 | if (hwq_shptr->GetXQueue() != nullptr) { |
| 28 | XQueueHandle xq_h = hwq_shptr->GetXQueue()->GetHandle(); |
| 29 | auto it = xqs_.find(xq_h); |
| 30 | XASSERT(it != xqs_.end(), "XQueue with handle 0x" FMT_64X " does not exist", xq_h); |
| 31 | XASSERT(it->second == hwq_shptr->GetXQueue(), |
| 32 | "XQueue and handle 0x" FMT_64X " mismatch", xq_h); |
| 33 | XWARN("HwQueue (0x" FMT_64X ") already has an XQueue (0x" FMT_64X ")", hwq_h, xq_h); |
| 34 | if (xq_hp != nullptr) *xq_hp = xq_h; |
| 35 | return kXSchedSuccess; |
| 36 | } |
| 37 | |
| 38 | auto xq_shptr = std::make_shared<AsyncXQueue>(hwq_shptr, (XPreemptLevel)level); |
| 39 | if (xq_shptr == nullptr) { |
| 40 | XWARN("Fail to create XQueue"); |
| 41 | return kXSchedErrorUnknown; |
| 42 | } |
| 43 | |
| 44 | hwq_shptr->SetXQueue(xq_shptr); // Circular reference. |
| 45 | XQueueHandle xq_h = xq_shptr->GetHandle(); |
| 46 | xqs_[xq_h] = xq_shptr; |
| 47 | if (xq_hp != nullptr) *xq_hp = xq_h; |
| 48 | return kXSchedSuccess; |
| 49 | } |
| 50 | |
| 51 | XResult XQueueManager::Del(XQueueHandle xq_h) |
| 52 | { |