summaryrefslogtreecommitdiffstats
path: root/hci
diff options
context:
space:
mode:
authorzzy <zhenye@broadcom.com>2012-09-20 21:19:10 -0700
committerIliyan Malchev <malchev@google.com>2012-09-21 13:07:45 -0700
commit751c3ccf7c79a717c4f812c613f8911c1b7dee0b (patch)
treee2304a192f7dcfbae7f7c0c46eda330eb5bf2a71 /hci
parentc5af211f3758c7c94d9ca9b36dc106eb815cb67d (diff)
downloadexternal_bluetooth_bluedroid-751c3ccf7c79a717c4f812c613f8911c1b7dee0b.zip
external_bluetooth_bluedroid-751c3ccf7c79a717c4f812c613f8911c1b7dee0b.tar.gz
external_bluetooth_bluedroid-751c3ccf7c79a717c4f812c613f8911c1b7dee0b.tar.bz2
bluedroid: add mutex lock when enumerating the hci tx queue
Bug: 7167816 Bug: 7136940 This could be fix for most of the hci timeout issues. The root cause seemed like the while loop for sending hci message messed up when another thread try to enque/deque a hci message at same time. Change-Id: Ib7f6a68b49b700b0d575326cafae41a158483b27 Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'hci')
-rw-r--r--hci/include/utils.h23
-rw-r--r--hci/src/bt_hci_bdroid.c16
-rw-r--r--hci/src/utils.c46
3 files changed, 68 insertions, 17 deletions
diff --git a/hci/include/utils.h b/hci/include/utils.h
index be4406b..0f1517c 100644
--- a/hci/include/utils.h
+++ b/hci/include/utils.h
@@ -111,6 +111,17 @@ void *utils_dequeue (BUFFER_Q *p_q);
/*******************************************************************************
**
+** Function utils_dequeue_unlocked
+**
+** Description Dequeues a buffer from the head of the given queue without lock
+**
+** Returns NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *utils_dequeue_unlocked (BUFFER_Q *p_q);
+
+/*******************************************************************************
+**
** Function utils_getnext
**
** Description Return a pointer to the next buffer linked to the given buffer
@@ -134,6 +145,18 @@ void *utils_remove_from_queue (BUFFER_Q *p_q, void *p_buf);
/*******************************************************************************
**
+** Function utils_remove_from_queue_unlocked
+**
+** Description Dequeue the given buffer from the middle of the given queue without lock
+**
+** Returns NULL if the given queue is empty, else the given buffer
+**
+*******************************************************************************/
+void *utils_remove_from_queue_unlocked (BUFFER_Q *p_q, void *p_buf);
+
+
+/*******************************************************************************
+**
** Function utils_delay
**
** Description sleep unconditionally for timeout milliseconds
diff --git a/hci/src/bt_hci_bdroid.c b/hci/src/bt_hci_bdroid.c
index e8a8411..27d190e 100644
--- a/hci/src/bt_hci_bdroid.c
+++ b/hci/src/bt_hci_bdroid.c
@@ -410,9 +410,12 @@ static void *bt_hc_worker_thread(void *arg)
* Fine to clear tx_cmd_pkts_pending.
*/
tx_cmd_pkts_pending = FALSE;
-
+ HC_BT_HDR * sending_msg_que[64];
+ int sending_msg_count = 0;
+ utils_lock();
p_next_msg = tx_q.p_first;
- while (p_next_msg)
+ while (p_next_msg && sending_msg_count <
+ (int)sizeof(sending_msg_que)/sizeof(sending_msg_que[0]))
{
if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
{
@@ -434,10 +437,13 @@ static void *bt_hc_worker_thread(void *arg)
p_msg = p_next_msg;
p_next_msg = utils_getnext(p_msg);
- utils_remove_from_queue(&tx_q, p_msg);
- p_hci_if->send(p_msg);
+ utils_remove_from_queue_unlocked(&tx_q, p_msg);
+ sending_msg_que[sending_msg_count++] = p_msg;
}
-
+ utils_unlock();
+ int i;
+ for(i = 0; i < sending_msg_count; i++)
+ p_hci_if->send(sending_msg_que[i]);
if (tx_cmd_pkts_pending == TRUE)
BTHCDBG("Used up Tx Cmd credits");
diff --git a/hci/src/utils.c b/hci/src/utils.c
index 318c985..bfcf724 100644
--- a/hci/src/utils.c
+++ b/hci/src/utils.c
@@ -116,7 +116,6 @@ void utils_enqueue (BUFFER_Q *p_q, void *p_buf)
pthread_mutex_unlock(&utils_mutex);
}
-
/*******************************************************************************
**
** Function utils_dequeue
@@ -128,13 +127,28 @@ void utils_enqueue (BUFFER_Q *p_q, void *p_buf)
*******************************************************************************/
void *utils_dequeue (BUFFER_Q *p_q)
{
+ pthread_mutex_lock(&utils_mutex);
+ void* p_buf = utils_dequeue_unlocked(p_q);
+ pthread_mutex_unlock(&utils_mutex);
+ return p_buf;
+}
+
+/*******************************************************************************
+**
+** Function utils_dequeue_unlocked
+**
+** Description Dequeues a buffer from the head of the given queue without lock
+**
+** Returns NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *utils_dequeue_unlocked (BUFFER_Q *p_q)
+{
HC_BUFFER_HDR_T *p_hdr;
- pthread_mutex_lock(&utils_mutex);
if (!p_q || !p_q->count)
{
- pthread_mutex_unlock(&utils_mutex);
return (NULL);
}
@@ -151,9 +165,6 @@ void *utils_dequeue (BUFFER_Q *p_q)
p_q->count--;
p_hdr->p_next = NULL;
-
- pthread_mutex_unlock(&utils_mutex);
-
return ((uint8_t *)p_hdr + BT_HC_BUFFER_HDR_SIZE);
}
@@ -191,15 +202,29 @@ void *utils_getnext (void *p_buf)
*******************************************************************************/
void *utils_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
{
+ pthread_mutex_lock(&utils_mutex);
+ p_buf = utils_remove_from_queue_unlocked(p_q, p_buf);
+ pthread_mutex_unlock(&utils_mutex);
+ return p_buf;
+}
+/*******************************************************************************
+**
+** Function utils_remove_from_queue_unlocked
+**
+** Description Dequeue the given buffer from the middle of the given queue
+**
+** Returns NULL if the given queue is empty, else the given buffer
+**
+*******************************************************************************/
+void *utils_remove_from_queue_unlocked (BUFFER_Q *p_q, void *p_buf)
+{
HC_BUFFER_HDR_T *p_prev;
HC_BUFFER_HDR_T *p_buf_hdr;
- pthread_mutex_lock(&utils_mutex);
if (p_buf == p_q->p_first)
{
- pthread_mutex_unlock(&utils_mutex);
- return (utils_dequeue (p_q));
+ return (utils_dequeue_unlocked (p_q));
}
p_buf_hdr = (HC_BUFFER_HDR_T *)((uint8_t *)p_buf - BT_HC_BUFFER_HDR_SIZE);
@@ -222,12 +247,9 @@ void *utils_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
/* The buffer is now unlinked */
p_buf_hdr->p_next = NULL;
- pthread_mutex_unlock(&utils_mutex);
return (p_buf);
}
}
-
- pthread_mutex_unlock(&utils_mutex);
return (NULL);
}