Skip to content

Commit 3700283

Browse files
authored
Merge pull request #3924 from qiyongzhong0/fix_bug_of_dataqueue
Fix bug of dataqueue
2 parents c2252f6 + 77f0814 commit 3700283

File tree

2 files changed

+92
-34
lines changed

2 files changed

+92
-34
lines changed

components/drivers/include/ipc/dataqueue.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@
1717
#define RT_DATAQUEUE_EVENT_LWM 0x03
1818

1919
struct rt_data_item;
20-
#define RT_DATAQUEUE_SIZE(dq) ((dq)->put_index - (dq)->get_index)
21-
#define RT_DATAQUEUE_EMPTY(dq) ((dq)->size - RT_DATAQUEUE_SIZE(dq))
20+
2221
/* data queue implementation */
2322
struct rt_data_queue
2423
{
2524
rt_uint32_t magic;
2625

2726
rt_uint16_t size;
2827
rt_uint16_t lwm;
29-
rt_bool_t waiting_lwm;
3028

31-
rt_uint16_t get_index;
32-
rt_uint16_t put_index;
29+
rt_uint16_t get_index : 15;
30+
rt_uint16_t is_empty : 1;
31+
rt_uint16_t put_index : 15;
32+
rt_uint16_t is_full : 1;
3333

3434
struct rt_data_item *queue;
3535

@@ -60,5 +60,6 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
6060
rt_size_t *size);
6161
void rt_data_queue_reset(struct rt_data_queue *queue);
6262
rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue);
63+
rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue);
6364

6465
#endif

components/drivers/src/dataqueue.c

Lines changed: 86 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ rt_data_queue_init(struct rt_data_queue *queue,
2828
void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event))
2929
{
3030
RT_ASSERT(queue != RT_NULL);
31-
RT_ASSERT((0x10000 % size) == 0);
31+
RT_ASSERT(size > 0);
3232

3333
queue->evt_notify = evt_notify;
3434

@@ -38,6 +38,8 @@ rt_data_queue_init(struct rt_data_queue *queue,
3838

3939
queue->get_index = 0;
4040
queue->put_index = 0;
41+
queue->is_empty = 1;
42+
queue->is_full = 0;
4143

4244
rt_list_init(&(queue->suspended_push_list));
4345
rt_list_init(&(queue->suspended_pop_list));
@@ -61,14 +63,14 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
6163
rt_thread_t thread;
6264
rt_err_t result;
6365

64-
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
6566
RT_ASSERT(queue != RT_NULL);
67+
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
6668

6769
result = RT_EOK;
6870
thread = rt_thread_self();
6971

7072
level = rt_hw_interrupt_disable();
71-
while (queue->put_index - queue->get_index == queue->size)
73+
while (queue->is_full)
7274
{
7375
/* queue is full */
7476
if (timeout == 0)
@@ -109,9 +111,18 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
109111
if (result != RT_EOK) goto __exit;
110112
}
111113

112-
queue->queue[queue->put_index % queue->size].data_ptr = data_ptr;
113-
queue->queue[queue->put_index % queue->size].data_size = data_size;
114+
queue->queue[queue->put_index].data_ptr = data_ptr;
115+
queue->queue[queue->put_index].data_size = data_size;
114116
queue->put_index += 1;
117+
if (queue->put_index == queue->size)
118+
{
119+
queue->put_index = 0;
120+
}
121+
queue->is_empty = 0;
122+
if (queue->put_index == queue->get_index)
123+
{
124+
queue->is_full = 1;
125+
}
115126

116127
/* there is at least one thread in suspended list */
117128
if (!rt_list_isempty(&(queue->suspended_pop_list)))
@@ -151,16 +162,16 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
151162
rt_thread_t thread;
152163
rt_err_t result;
153164

154-
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
155165
RT_ASSERT(queue != RT_NULL);
166+
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
156167
RT_ASSERT(data_ptr != RT_NULL);
157168
RT_ASSERT(size != RT_NULL);
158169

159170
result = RT_EOK;
160171
thread = rt_thread_self();
161172

162173
level = rt_hw_interrupt_disable();
163-
while (queue->get_index == queue->put_index)
174+
while (queue->is_empty)
164175
{
165176
/* queue is empty */
166177
if (timeout == 0)
@@ -201,12 +212,20 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
201212
goto __exit;
202213
}
203214

204-
*data_ptr = queue->queue[queue->get_index % queue->size].data_ptr;
205-
*size = queue->queue[queue->get_index % queue->size].data_size;
206-
215+
*data_ptr = queue->queue[queue->get_index].data_ptr;
216+
*size = queue->queue[queue->get_index].data_size;
207217
queue->get_index += 1;
218+
if (queue->get_index == queue->size)
219+
{
220+
queue->get_index = 0;
221+
}
222+
queue->is_full = 0;
223+
if (queue->put_index == queue->get_index)
224+
{
225+
queue->is_empty = 1;
226+
}
208227

209-
if ((queue->put_index - queue->get_index) <= queue->lwm)
228+
if (rt_data_queue_len(queue) <= queue->lwm)
210229
{
211230
/* there is at least one thread in suspended list */
212231
if (!rt_list_isempty(&(queue->suspended_push_list)))
@@ -251,20 +270,18 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
251270
{
252271
rt_ubase_t level;
253272

254-
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
255273
RT_ASSERT(queue != RT_NULL);
274+
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
256275

257-
level = rt_hw_interrupt_disable();
258-
259-
if (queue->get_index == queue->put_index)
276+
if (queue->is_empty)
260277
{
261-
rt_hw_interrupt_enable(level);
262-
263278
return -RT_EEMPTY;
264279
}
265280

266-
*data_ptr = queue->queue[queue->get_index % queue->size].data_ptr;
267-
*size = queue->queue[queue->get_index % queue->size].data_size;
281+
level = rt_hw_interrupt_disable();
282+
283+
*data_ptr = queue->queue[queue->get_index].data_ptr;
284+
*size = queue->queue[queue->get_index].data_size;
268285

269286
rt_hw_interrupt_enable(level);
270287

@@ -274,10 +291,20 @@ RTM_EXPORT(rt_data_queue_peak);
274291

275292
void rt_data_queue_reset(struct rt_data_queue *queue)
276293
{
294+
rt_ubase_t level;
277295
struct rt_thread *thread;
278-
register rt_ubase_t temp;
279296

297+
RT_ASSERT(queue != RT_NULL);
280298
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
299+
300+
level = rt_hw_interrupt_disable();
301+
302+
queue->get_index = 0;
303+
queue->put_index = 0;
304+
queue->is_empty = 1;
305+
queue->is_full = 0;
306+
307+
rt_hw_interrupt_enable(level);
281308

282309
rt_enter_critical();
283310
/* wakeup all suspend threads */
@@ -286,7 +313,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
286313
while (!rt_list_isempty(&(queue->suspended_pop_list)))
287314
{
288315
/* disable interrupt */
289-
temp = rt_hw_interrupt_disable();
316+
level = rt_hw_interrupt_disable();
290317

291318
/* get next suspend thread */
292319
thread = rt_list_entry(queue->suspended_pop_list.next,
@@ -303,14 +330,14 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
303330
rt_thread_resume(thread);
304331

305332
/* enable interrupt */
306-
rt_hw_interrupt_enable(temp);
333+
rt_hw_interrupt_enable(level);
307334
}
308335

309336
/* resume on push list */
310337
while (!rt_list_isempty(&(queue->suspended_push_list)))
311338
{
312339
/* disable interrupt */
313-
temp = rt_hw_interrupt_disable();
340+
level = rt_hw_interrupt_disable();
314341

315342
/* get next suspend thread */
316343
thread = rt_list_entry(queue->suspended_push_list.next,
@@ -327,7 +354,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
327354
rt_thread_resume(thread);
328355

329356
/* enable interrupt */
330-
rt_hw_interrupt_enable(temp);
357+
rt_hw_interrupt_enable(level);
331358
}
332359
rt_exit_critical();
333360

@@ -339,19 +366,49 @@ rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue)
339366
{
340367
rt_ubase_t level;
341368

342-
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
343369
RT_ASSERT(queue != RT_NULL);
344-
345-
level = rt_hw_interrupt_disable();
370+
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
346371

347372
/* wakeup all suspend threads */
348373
rt_data_queue_reset(queue);
349374

375+
level = rt_hw_interrupt_disable();
350376
queue->magic = 0;
351-
rt_free(queue->queue);
352-
353377
rt_hw_interrupt_enable(level);
378+
379+
rt_free(queue->queue);
354380

355381
return RT_EOK;
356382
}
357383
RTM_EXPORT(rt_data_queue_deinit);
384+
385+
rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue)
386+
{
387+
rt_ubase_t level;
388+
rt_int16_t len;
389+
390+
RT_ASSERT(queue != RT_NULL);
391+
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
392+
393+
if (queue->is_empty)
394+
{
395+
return 0;
396+
}
397+
398+
level = rt_hw_interrupt_disable();
399+
400+
if (queue->put_index > queue->get_index)
401+
{
402+
len = queue->put_index - queue->get_index;
403+
}
404+
else
405+
{
406+
len = queue->size + queue->put_index - queue->get_index;
407+
}
408+
409+
rt_hw_interrupt_enable(level);
410+
411+
return len;
412+
}
413+
RTM_EXPORT(rt_data_queue_len);
414+

0 commit comments

Comments
 (0)