OSDN Git Service

RoundRobinScheduler: Add multi priority support
authorHansong Zhang <hsz@google.com>
Fri, 15 Jan 2021 06:34:05 +0000 (22:34 -0800)
committerHansong Zhang <hsz@google.com>
Fri, 15 Jan 2021 19:42:35 +0000 (11:42 -0800)
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
gd/hci/acl_manager.cc
gd/hci/acl_manager.h
gd/hci/acl_manager/round_robin_scheduler.cc
gd/hci/acl_manager/round_robin_scheduler.h
main/shim/l2c_api.cc

index dd4785b..0546cd9 100644 (file)
@@ -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>(t));
+    next_to_dequeue_.push(priority);
+  }
+
   // Pop the item in the front
   void pop() {
     queues_[next_to_dequeue_.top()].pop();
index 6ca22c9..d9a608d 100644 (file)
@@ -249,6 +249,10 @@ void AclManager::HACK_SetScoDisconnectCallback(std::function<void(uint16_t, uint
   pimpl_->classic_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<HciLayer>();
   list->add<Controller>();
index 2297627..1e1aa09 100644 (file)
@@ -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<void(uint16_t /* handle */, uint8_t /* reason */)>);
 
+ virtual void HACK_SetAclTxPriority(uint8_t handle, bool high_priority);
+
  struct impl;
  std::unique_ptr<impl> pimpl_;
 
index 230c821..4b94e0f 100644 (file)
@@ -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<uint16_t, acl_queue_handler>::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;
     }
   }
index 95efb2c..d78bf51 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdint.h>
 
 #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<acl_manager::AclConnection::Queue> 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<acl_manager::AclConnection::Queue> 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<uint16_t, acl_queue_handler> acl_queue_handlers_;
-  std::queue<std::pair<ConnectionType, std::unique_ptr<AclBuilder>>> fragments_to_send_;
+  common::MultiPriorityQueue<std::pair<ConnectionType, std::unique_ptr<AclBuilder>>, 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;
index 19d4b73..269ae1b 100644 (file)
@@ -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,