Skip to content

Commit 373524c

Browse files
committed
Merge branch 'opt/bluedroid_adv_report_datapath' into 'master'
component/bt: optimize BLE adv report datapath and adv report flow control mechanism Closes BT-2561 See merge request espressif/esp-idf!19171
2 parents df1c54d + 2462003 commit 373524c

30 files changed

+1601
-338
lines changed

components/bt/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ if(CONFIG_BT_ENABLED)
5353
"common/osi/buffer.c"
5454
"common/osi/config.c"
5555
"common/osi/fixed_queue.c"
56+
"common/osi/pkt_queue.c"
57+
"common/osi/fixed_pkt_queue.c"
5658
"common/osi/future.c"
5759
"common/osi/hash_functions.c"
5860
"common/osi/hash_map.c"

components/bt/common/btc/core/btc_task.c

+19-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@
6060
#endif /* #if CLASSIC_BT_INCLUDED */
6161
#endif
6262

63+
#if (BLE_INCLUDED == TRUE)
64+
#include "btc_gap_ble.h"
65+
#endif
66+
6367
#if CONFIG_BLE_MESH
6468
#include "btc_ble_mesh_ble.h"
6569
#include "btc_ble_mesh_prov.h"
@@ -75,6 +79,9 @@
7579
#define BTC_TASK_STACK_SIZE (BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
7680
#define BTC_TASK_NAME "BTC_TASK"
7781
#define BTC_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 6)
82+
#define BTC_TASK_WORKQUEUE_NUM (2)
83+
#define BTC_TASK_WORKQUEUE0_LEN (0)
84+
#define BTC_TASK_WORKQUEUE1_LEN (5)
7885

7986
osi_thread_t *btc_thread;
8087

@@ -414,7 +421,9 @@ error_exit:;
414421

415422
bt_status_t btc_init(void)
416423
{
417-
btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 2);
424+
const size_t workqueue_len[] = {BTC_TASK_WORKQUEUE0_LEN, BTC_TASK_WORKQUEUE1_LEN};
425+
btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE,
426+
BTC_TASK_WORKQUEUE_NUM, workqueue_len);
418427
if (btc_thread == NULL) {
419428
return BT_STATUS_NOMEM;
420429
}
@@ -427,6 +436,7 @@ bt_status_t btc_init(void)
427436

428437
#if (BLE_INCLUDED == TRUE)
429438
btc_gap_callback_init();
439+
btc_gap_ble_init();
430440
#endif ///BLE_INCLUDED == TRUE
431441

432442
#if SCAN_QUEUE_CONGEST_CHECK
@@ -444,7 +454,9 @@ void btc_deinit(void)
444454

445455
osi_thread_free(btc_thread);
446456
btc_thread = NULL;
447-
457+
#if (BLE_INCLUDED == TRUE)
458+
btc_gap_ble_deinit();
459+
#endif ///BLE_INCLUDED == TRUE
448460
#if SCAN_QUEUE_CONGEST_CHECK
449461
btc_adv_list_deinit();
450462
#endif
@@ -463,3 +475,8 @@ int get_btc_work_queue_size(void)
463475
{
464476
return osi_thread_queue_wait_size(btc_thread, 0);
465477
}
478+
479+
osi_thread_t *btc_get_current_thread(void)
480+
{
481+
return btc_thread;
482+
}

components/bt/common/btc/include/btc/btc_task.h

+7
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ void btc_deinit(void);
124124
bool btc_check_queue_is_congest(void);
125125
int get_btc_work_queue_size(void);
126126

127+
/**
128+
* get the BTC thread handle
129+
* @return NULL: fail
130+
* others: pointer of osi_thread structure of BTC
131+
*/
132+
osi_thread_t *btc_get_current_thread(void);
133+
127134
#ifdef __cplusplus
128135
}
129136
#endif
+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "osi/allocator.h"
8+
#include "osi/pkt_queue.h"
9+
#include "osi/fixed_pkt_queue.h"
10+
#include "osi/osi.h"
11+
#include "osi/semaphore.h"
12+
13+
typedef struct fixed_pkt_queue_t {
14+
struct pkt_queue *pkt_list;
15+
osi_sem_t enqueue_sem;
16+
osi_sem_t dequeue_sem;
17+
size_t capacity;
18+
fixed_pkt_queue_cb dequeue_ready;
19+
} fixed_pkt_queue_t;
20+
21+
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity)
22+
{
23+
fixed_pkt_queue_t *ret = osi_calloc(sizeof(fixed_pkt_queue_t));
24+
if (!ret) {
25+
goto error;
26+
}
27+
28+
ret->capacity = capacity;
29+
ret->pkt_list = pkt_queue_create();
30+
if (!ret->pkt_list) {
31+
goto error;
32+
}
33+
34+
osi_sem_new(&ret->enqueue_sem, capacity, capacity);
35+
if (!ret->enqueue_sem) {
36+
goto error;
37+
}
38+
39+
osi_sem_new(&ret->dequeue_sem, capacity, 0);
40+
if (!ret->dequeue_sem) {
41+
goto error;
42+
}
43+
44+
return ret;
45+
46+
error:
47+
fixed_pkt_queue_free(ret, NULL);
48+
return NULL;
49+
}
50+
51+
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb)
52+
{
53+
if (queue == NULL) {
54+
return;
55+
}
56+
57+
fixed_pkt_queue_unregister_dequeue(queue);
58+
59+
pkt_queue_destroy(queue->pkt_list, (pkt_queue_free_cb)free_cb);
60+
queue->pkt_list = NULL;
61+
62+
if (queue->enqueue_sem) {
63+
osi_sem_free(&queue->enqueue_sem);
64+
}
65+
if (queue->dequeue_sem) {
66+
osi_sem_free(&queue->dequeue_sem);
67+
}
68+
osi_free(queue);
69+
}
70+
71+
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue)
72+
{
73+
if (queue == NULL) {
74+
return true;
75+
}
76+
77+
return pkt_queue_is_empty(queue->pkt_list);
78+
}
79+
80+
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue)
81+
{
82+
if (queue == NULL) {
83+
return 0;
84+
}
85+
return pkt_queue_length(queue->pkt_list);
86+
}
87+
88+
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue)
89+
{
90+
assert(queue != NULL);
91+
92+
return queue->capacity;
93+
}
94+
95+
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout)
96+
{
97+
bool ret = false;
98+
99+
assert(queue != NULL);
100+
assert(linked_pkt != NULL);
101+
102+
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) {
103+
return false;
104+
}
105+
106+
ret = pkt_queue_enqueue(queue->pkt_list, linked_pkt);
107+
108+
assert(ret == true);
109+
osi_sem_give(&queue->dequeue_sem);
110+
111+
return ret;
112+
}
113+
114+
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout)
115+
{
116+
pkt_linked_item_t *ret = NULL;
117+
118+
assert(queue != NULL);
119+
120+
if (osi_sem_take(&queue->dequeue_sem, timeout) != 0) {
121+
return NULL;
122+
}
123+
ret = pkt_queue_dequeue(queue->pkt_list);
124+
125+
osi_sem_give(&queue->enqueue_sem);
126+
127+
return ret;
128+
}
129+
130+
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue)
131+
{
132+
if (queue == NULL) {
133+
return NULL;
134+
}
135+
136+
return pkt_queue_try_peek_first(queue->pkt_list);
137+
}
138+
139+
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb)
140+
{
141+
assert(queue != NULL);
142+
assert(ready_cb != NULL);
143+
144+
queue->dequeue_ready = ready_cb;
145+
}
146+
147+
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue)
148+
{
149+
assert(queue != NULL);
150+
151+
queue->dequeue_ready = NULL;
152+
}
153+
154+
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue)
155+
{
156+
assert(queue != NULL);
157+
158+
if (queue->dequeue_ready) {
159+
queue->dequeue_ready(queue);
160+
}
161+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef _FIXED_PKT_QUEUE_H_
8+
#define _FIXED_PKT_QUEUE_H_
9+
10+
11+
#include "osi/pkt_queue.h"
12+
#include "osi/semaphore.h"
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
#ifndef FIXED_PKT_QUEUE_SIZE_MAX
19+
#define FIXED_PKT_QUEUE_SIZE_MAX 254
20+
#endif
21+
22+
#define FIXED_PKT_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
23+
24+
struct fixed_pkt_queue_t;
25+
26+
typedef struct fixed_pkt_queue_t fixed_pkt_queue_t;
27+
28+
typedef void (*fixed_pkt_queue_free_cb)(pkt_linked_item_t *data);
29+
typedef void (*fixed_pkt_queue_cb)(fixed_pkt_queue_t *queue);
30+
31+
// Creates a new fixed queue with the given |capacity|. If more elements than
32+
// |capacity| are added to the queue, the caller is blocked until space is
33+
// made available in the queue. Returns NULL on failure. The caller must free
34+
// the returned queue with |fixed_pkt_queue_free|.
35+
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity);
36+
37+
// Freeing a queue that is currently in use (i.e. has waiters
38+
// blocked on it) results in undefined behaviour.
39+
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb);
40+
41+
// Returns a value indicating whether the given |queue| is empty. If |queue|
42+
// is NULL, the return value is true.
43+
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue);
44+
45+
// Returns the length of the |queue|. If |queue| is NULL, the return value
46+
// is 0.
47+
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue);
48+
49+
// Returns the maximum number of elements this queue may hold. |queue| may
50+
// not be NULL.
51+
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue);
52+
53+
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
54+
// If enqueue failed, it will return false, otherwise return true
55+
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout);
56+
57+
// Dequeues the next element from |queue|. If the queue is currently empty,
58+
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
59+
// If dequeue failed, it will return NULL, otherwise return a point.
60+
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout);
61+
62+
// Returns the first element from |queue|, if present, without dequeuing it.
63+
// This function will never block the caller. Returns NULL if there are no
64+
// elements in the queue or |queue| is NULL.
65+
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue);
66+
67+
// Registers |queue| with |reactor| for dequeue operations. When there is an element
68+
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
69+
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
70+
// |context| may be NULL.
71+
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb);
72+
73+
// Unregisters the dequeue ready callback for |queue| from whichever reactor
74+
// it is registered with, if any. This function is idempotent.
75+
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
76+
77+
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
78+
79+
#endif

0 commit comments

Comments
 (0)