From a049084bbcfac2f003e1b0bc9a40afc8c6d6e5e5 Mon Sep 17 00:00:00 2001 From: Hansong Zhang Date: Thu, 14 Jan 2021 22:34:05 -0800 Subject: [PATCH] RoundRobinScheduler: Add multi priority support And add SetAclTxPriority() API in AclManager and shim Test: cert/run Test: bluetooth_test_gd Tag: #gd-refactor Bug: 141555841 Change-Id: I6d5911dfea23b7e7440738c0c4d51a3e3ffbf52f --- gd/common/multi_priority_queue.h | 6 ++++++ gd/hci/acl_manager.cc | 4 ++++ gd/hci/acl_manager.h | 4 ++++ gd/hci/acl_manager/round_robin_scheduler.cc | 23 +++++++++++++++++++---- gd/hci/acl_manager/round_robin_scheduler.h | 5 ++++- main/shim/l2c_api.cc | 9 +++++++-- 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/gd/common/multi_priority_queue.h b/gd/common/multi_priority_queue.h index dd4785b75..0546cd9c7 100644 --- a/gd/common/multi_priority_queue.h +++ b/gd/common/multi_priority_queue.h @@ -54,6 +54,12 @@ class MultiPriorityQueue { next_to_dequeue_.push(priority); } + // Push the item with specified priority + void push(T&& t, int priority = 0) { + queues_[priority].push(std::forward(t)); + next_to_dequeue_.push(priority); + } + // Pop the item in the front void pop() { queues_[next_to_dequeue_.top()].pop(); diff --git a/gd/hci/acl_manager.cc b/gd/hci/acl_manager.cc index 6ca22c9d0..d9a608d8d 100644 --- a/gd/hci/acl_manager.cc +++ b/gd/hci/acl_manager.cc @@ -249,6 +249,10 @@ void AclManager::HACK_SetScoDisconnectCallback(std::functionclassic_impl_->HACK_SetScoDisconnectCallback(callback); } +void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) { + CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority); +} + void AclManager::ListDependencies(ModuleList* list) { list->add(); list->add(); diff --git a/gd/hci/acl_manager.h b/gd/hci/acl_manager.h index 229762794..1e1aa0974 100644 --- a/gd/hci/acl_manager.h +++ b/gd/hci/acl_manager.h @@ -39,6 +39,7 @@ class SecurityModule; namespace shim { class Btm; void L2CA_UseLegacySecurityModule(); +bool L2CA_SetAclPriority(uint16_t, bool); } namespace hci { @@ -46,6 +47,7 @@ namespace hci { class AclManager : public Module { friend class bluetooth::shim::Btm; friend void bluetooth::shim::L2CA_UseLegacySecurityModule(); + friend bool bluetooth::shim::L2CA_SetAclPriority(uint16_t, bool); public: AclManager(); @@ -129,6 +131,8 @@ private: // Hack for the shim to get SCO disconnect callback. Shim needs to post to their handler! virtual void HACK_SetScoDisconnectCallback(std::function); + virtual void HACK_SetAclTxPriority(uint8_t handle, bool high_priority); + struct impl; std::unique_ptr pimpl_; diff --git a/gd/hci/acl_manager/round_robin_scheduler.cc b/gd/hci/acl_manager/round_robin_scheduler.cc index 230c82127..4b94e0f41 100644 --- a/gd/hci/acl_manager/round_robin_scheduler.cc +++ b/gd/hci/acl_manager/round_robin_scheduler.cc @@ -67,6 +67,15 @@ void RoundRobinScheduler::Unregister(uint16_t handle) { starting_point_ = acl_queue_handlers_.begin(); } +void RoundRobinScheduler::SetLinkPriority(uint16_t handle, bool high_priority) { + auto acl_queue_handler = acl_queue_handlers_.find(handle); + if (acl_queue_handler == acl_queue_handlers_.end()) { + LOG_WARN("handle %d is invalid", handle); + return; + } + acl_queue_handler->second.high_priority_ = high_priority; +} + uint16_t RoundRobinScheduler::GetCredits() { return acl_packet_credits_; } @@ -121,14 +130,20 @@ void RoundRobinScheduler::buffer_packet(std::map::i PacketBoundaryFlag packet_boundary_flag = (connection_type == ConnectionType::CLASSIC ? PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE : PacketBoundaryFlag::FIRST_NON_AUTOMATICALLY_FLUSHABLE); + int acl_priority = acl_queue_handler->second.high_priority_ ? 1 : 0; if (packet->size() <= mtu) { - fragments_to_send_.push(std::make_pair( - connection_type, AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(packet)))); + fragments_to_send_.push( + std::make_pair( + connection_type, AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(packet))), + acl_priority); } else { auto fragments = AclFragmenter(mtu, std::move(packet)).GetFragments(); for (size_t i = 0; i < fragments.size(); i++) { - fragments_to_send_.push(std::make_pair( - connection_type, AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(fragments[i])))); + fragments_to_send_.push( + std::make_pair( + connection_type, + AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(fragments[i]))), + acl_priority); packet_boundary_flag = PacketBoundaryFlag::CONTINUING_FRAGMENT; } } diff --git a/gd/hci/acl_manager/round_robin_scheduler.h b/gd/hci/acl_manager/round_robin_scheduler.h index 95efb2c2c..d78bf511d 100644 --- a/gd/hci/acl_manager/round_robin_scheduler.h +++ b/gd/hci/acl_manager/round_robin_scheduler.h @@ -19,6 +19,7 @@ #include #include "common/bidi_queue.h" +#include "common/multi_priority_queue.h" #include "hci/acl_manager.h" #include "hci/controller.h" #include "hci/hci_packets.h" @@ -41,11 +42,13 @@ class RoundRobinScheduler { std::shared_ptr queue_; bool dequeue_is_registered_ = false; uint16_t number_of_sent_packets_ = 0; // Track credits + bool high_priority_ = false; // For A2dp use }; void Register(ConnectionType connection_type, uint16_t handle, std::shared_ptr queue); void Unregister(uint16_t handle); + void SetLinkPriority(uint16_t handle, bool high_priority); uint16_t GetCredits(); uint16_t GetLeCredits(); @@ -60,7 +63,7 @@ class RoundRobinScheduler { os::Handler* handler_ = nullptr; Controller* controller_ = nullptr; std::map acl_queue_handlers_; - std::queue>> fragments_to_send_; + common::MultiPriorityQueue>, 2> fragments_to_send_; uint16_t max_acl_packet_credits_ = 0; uint16_t acl_packet_credits_ = 0; uint16_t le_max_acl_packet_credits_ = 0; diff --git a/main/shim/l2c_api.cc b/main/shim/l2c_api.cc index 19d4b73ff..269ae1b3b 100644 --- a/main/shim/l2c_api.cc +++ b/main/shim/l2c_api.cc @@ -786,9 +786,14 @@ bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout, } } +bool L2CA_SetAclPriority(uint16_t handle, bool high_priority) { + GetAclManager()->HACK_SetAclTxPriority(handle, high_priority); + return true; +} + bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) { - LOG_INFO("UNIMPLEMENTED %s", __func__); - return false; + uint16_t handle = security_listener_shim_.address_to_handle_[bd_addr]; + return L2CA_SetAclPriority(handle, priority == L2CAP_PRIORITY_HIGH); } bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat, -- 2.11.0