Bluetooth: controller: Optimize calls to hci_get_class()

Cache the result of calling hci_get_class() to avoid repeatedly invoking
it on the same data. In order to cache it we take advantage of the fact
that both radio_pdu_node_rx_hdr and node_rx_hdr are not packed
structures and they currently have a spare padding byte (between type
and handle).

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Carles Cufi 2019-10-08 19:08:23 +02:00 committed by Carles Cufí
commit 058724f329
5 changed files with 17 additions and 10 deletions

View file

@ -3410,7 +3410,7 @@ void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num)
}
#endif
s8_t hci_get_class(struct node_rx_pdu *node_rx)
u8_t hci_get_class(struct node_rx_pdu *node_rx)
{
#if defined(CONFIG_BT_CONN)
struct pdu_data *pdu_data = PDU_DATA(node_rx);
@ -3489,7 +3489,7 @@ s8_t hci_get_class(struct node_rx_pdu *node_rx)
#endif /* CONFIG_BT_CTLR_USER_EXT */
default:
return -1;
return HCI_CLASS_NONE;
}
#if defined(CONFIG_BT_CONN)
@ -3500,7 +3500,7 @@ s8_t hci_get_class(struct node_rx_pdu *node_rx)
}
#else
} else {
return -1;
return HCI_CLASS_NONE;
}
#endif
}

View file

@ -81,12 +81,12 @@ static s32_t hbuf_count;
static void prio_recv_thread(void *p1, void *p2, void *p3)
{
while (1) {
void *node_rx;
struct node_rx_pdu *node_rx;
u8_t num_cmplt;
u16_t handle;
/* While there are completed rx nodes */
while ((num_cmplt = ll_rx_get(&node_rx, &handle))) {
while ((num_cmplt = ll_rx_get((void *)&node_rx, &handle))) {
#if defined(CONFIG_BT_CONN)
struct net_buf *buf;
@ -105,6 +105,9 @@ static void prio_recv_thread(void *p1, void *p2, void *p3)
*/
ll_rx_dequeue();
/* Find out and store the class for this node */
node_rx->hdr.user_meta = hci_get_class(node_rx);
/* Send the rx node up to Host thread, recv_thread() */
BT_DBG("RX node enqueue");
k_fifo_put(&recv_fifo, node_rx);
@ -183,7 +186,7 @@ static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx,
static inline struct net_buf *process_node(struct node_rx_pdu *node_rx)
{
s8_t class = hci_get_class(node_rx);
u8_t class = node_rx->hdr.user_meta;
struct net_buf *buf = NULL;
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
@ -226,7 +229,7 @@ static inline struct net_buf *process_hbuf(struct node_rx_pdu *n)
struct node_rx_pdu *node_rx = NULL;
s32_t hbuf_total = hci_hbuf_total;
struct net_buf *buf = NULL;
s8_t class;
u8_t class;
int reset;
reset = atomic_test_and_clear_bit(&hci_state_mask, HCI_STATE_BIT_RESET);
@ -250,7 +253,7 @@ static inline struct net_buf *process_hbuf(struct node_rx_pdu *n)
}
/* Return early if this iteration already has a node to process */
class = hci_get_class(node_rx);
class = node_rx->hdr.user_meta;
if (n) {
if (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA && hbuf_count)) {
@ -289,7 +292,7 @@ static inline struct net_buf *process_hbuf(struct node_rx_pdu *n)
/* next node */
node_rx = (void *)sys_slist_peek_head(&hbuf_pend);
if (node_rx) {
class = hci_get_class(node_rx);
class = node_rx->hdr.user_meta;
if (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA && hbuf_count)) {

View file

@ -26,6 +26,8 @@ extern atomic_t hci_state_mask;
#define HCI_CLASS_ACL_DATA 3 /* Asynchronous Connection Less (general
* data)
*/
#define HCI_CLASS_NONE 0xFF /* Invalid class */
#if defined(CONFIG_BT_LL_SW_SPLIT)
#define PDU_DATA(node_rx) ((void *)node_rx->pdu)
@ -38,7 +40,7 @@ extern atomic_t hci_state_mask;
void hci_init(struct k_poll_signal *signal_host_buf);
struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx);
void hci_evt_encode(struct node_rx_pdu *node_rx, struct net_buf *buf);
s8_t hci_get_class(struct node_rx_pdu *node_rx);
u8_t hci_get_class(struct node_rx_pdu *node_rx);
#if defined(CONFIG_BT_CONN)
int hci_acl_handle(struct net_buf *acl, struct net_buf **evt);
void hci_acl_encode(struct node_rx_pdu *node_rx, struct net_buf *buf);

View file

@ -167,6 +167,7 @@ struct radio_pdu_node_rx_hdr {
};
enum node_rx_type type;
u8_t user_meta; /* User metadata */
u16_t handle;
};

View file

@ -211,6 +211,7 @@ struct node_rx_hdr {
};
enum node_rx_type type;
u8_t user_meta; /* User metadata */
u16_t handle;
union {