Skip to content

Commit efaecc1

Browse files
committed
Fix re-initialize queue head problem
1 parent dfc8935 commit efaecc1

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

virtio-snd.c

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -445,14 +445,15 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
445445

446446
/* Control the callback to prepare the buffer */
447447
/* TODO: add lock to avoid race condition */
448-
pthread_mutex_lock(&virtio_snd_mutex);
448+
// pthread_mutex_lock(&virtio_snd_mutex);
449449
v.guest_playing = false;
450450
v.stream_id = stream_id;
451-
pthread_mutex_unlock(&virtio_snd_mutex);
451+
// pthread_mutex_unlock(&virtio_snd_mutex);
452452
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_PREPARE;
453453
vsnd_props[stream_id].audio_host =
454454
CNFAInit(NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0,
455455
vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &v);
456+
INIT_QUEUE_HEAD(&(vsnd_props[stream_id].pcm_frames_q));
456457

457458
*plen = 0;
458459
fprintf(stderr, "virtio_snd_read_pcm_prepare\n");
@@ -474,10 +475,10 @@ static void virtio_snd_read_pcm_start(const virtio_snd_pcm_hdr_t *query,
474475

475476
/* Control the callback to start playing */
476477
/* TODO: add lock to avoid race condition */
477-
pthread_mutex_lock(&virtio_snd_mutex);
478+
// pthread_mutex_lock(&virtio_snd_mutex);
478479
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_START;
479480
v.guest_playing = true;
480-
pthread_mutex_unlock(&virtio_snd_mutex);
481+
// pthread_mutex_unlock(&virtio_snd_mutex);
481482

482483
*plen = 0;
483484
fprintf(stderr, "virtio_snd_read_pcm_start\n");
@@ -498,10 +499,10 @@ static void virtio_snd_read_pcm_stop(const virtio_snd_pcm_hdr_t *query,
498499

499500
/* Control the callback to stop playing */
500501
/* TODO: add lock to avoid race condition */
501-
pthread_mutex_lock(&virtio_snd_mutex);
502+
// pthread_mutex_lock(&virtio_snd_mutex);
502503
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_STOP;
503504
v.guest_playing = false;
504-
pthread_mutex_lock(&virtio_snd_mutex);
505+
// pthread_mutex_lock(&virtio_snd_mutex);
505506

506507
*plen = 0;
507508
fprintf(stderr, "virtio_snd_read_pcm_stop\n");
@@ -522,24 +523,24 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
522523
}
523524
/* Control the callback to stop playing */
524525
/* TODO: add lock to avoid race condition */
525-
pthread_mutex_lock(&virtio_snd_mutex);
526+
// pthread_mutex_lock(&virtio_snd_mutex);
526527
v.guest_playing = false;
527-
pthread_mutex_unlock(&virtio_snd_mutex);
528+
// pthread_mutex_unlock(&virtio_snd_mutex);
528529

529530
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_RELEASE;
530531
CNFAClose(vsnd_props[stream_id].audio_host);
531532

532533
/* Tear down the PCM frames. */
533534
virtio_snd_pcm_frame_t *t = NULL;
534-
struct queue_head frame_q = vsnd_props[stream_id].pcm_frames_q;
535+
struct queue_head *frame_q = &(vsnd_props[stream_id].pcm_frames_q);
535536
virtio_snd_pcm_frame_t *frame = vsnd_props[stream_id].pcm_frames;
536-
queue_for_each_entry_safe(frame, t, &frame_q, q)
537+
queue_for_each_entry_safe(frame, t, frame_q, q)
537538
{
538539
free(frame->buf);
539540
queue_del(&frame->q);
540541
free(frame);
541542
}
542-
assert(queue_empty(&frame_q));
543+
assert(queue_empty(frame_q));
543544

544545
*plen = 0;
545546
fprintf(stderr, "virtio_snd_read_pcm_release\n");
@@ -576,8 +577,8 @@ static void virtio_snd_cb(struct CNFADriver *dev,
576577
totalframesp += framesp;
577578

578579
if (!playing) {
579-
fprintf(stderr, "notplaying totalframesr: %d totalframesp: %d\n",
580-
totalframesr, totalframesp);
580+
/*fprintf(stderr, "notplaying totalframesr: %d totalframesp: %d\n",
581+
totalframesr, totalframesp);*/
581582
return;
582583
}
583584

@@ -696,7 +697,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
696697
uint32_t *plen)
697698
{
698699
/* Start of critical section */
699-
pthread_mutex_lock(&virtio_snd_mutex);
700+
// pthread_mutex_lock(&virtio_snd_mutex);
700701

701702
/* TODO: clarify the usage of the last descriptor. */
702703
/* virtio-snd TX uses arbitrary number of virtqueue descriptors.
@@ -709,12 +710,12 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
709710
*/
710711
virtq_desc_queue_node_t *node;
711712
struct queue_head q;
712-
713713
INIT_QUEUE_HEAD(&q);
714+
assert(queue_empty(&q));
714715

715716
/* Collect the descriptors */
716717
int cnt = 0;
717-
while (true) {
718+
for (;;) {
718719
/* The size of the `struct virtq_desc` is 4 words */
719720
const uint32_t *desc = &vsnd->ram[queue->QueueDesc + desc_idx * 4];
720721

@@ -738,8 +739,8 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
738739
int idx = 0;
739740
uint32_t stream_id;
740741
uintptr_t base = (uintptr_t) vsnd->ram;
741-
struct queue_head frame_q = vsnd_props[stream_id].pcm_frames_q;
742-
INIT_QUEUE_HEAD(&frame_q);
742+
struct queue_head *frame_q = &(vsnd_props[stream_id].pcm_frames_q);
743+
743744
virtio_snd_pcm_frame_t *frame = vsnd_props[stream_id].pcm_frames;
744745
uint32_t ret_len = 0;
745746
queue_for_each_entry(node, &q, q)
@@ -759,7 +760,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
759760
(virtio_snd_pcm_status_t *) (base + addr);
760761
response->status = VIRTIO_SND_S_OK;
761762
response->latency_bytes = ret_len;
762-
*plen = sizeof(virtio_snd_pcm_status_t);
763+
*plen = sizeof(*response);
763764
fprintf(stderr, "TX response\n");
764765
goto early_continue;
765766
}
@@ -768,7 +769,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
768769
void *buf = (void *) (base + addr);
769770
frame->buf = (void *) malloc(sizeof(frame->buf) * len);
770771
memcpy(frame->buf, buf, len);
771-
queue_push(&frame->q, &frame_q);
772+
queue_push(&frame->q, frame_q);
772773
ret_len += len;
773774

774775
early_continue:
@@ -786,7 +787,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
786787
}
787788

788789
/* End of critical seciont. */
789-
pthread_mutex_unlock(&virtio_snd_mutex);
790+
// pthread_mutex_unlock(&virtio_snd_mutex);
790791

791792
/* TODO: remove sleep once find the root cause of infinite loop in TX. */
792793
sleep(1);
@@ -860,8 +861,10 @@ static void virtio_queue_notify_handler(
860861
vsnd->ram[queue->QueueUsed] |= ((uint32_t) new_used) << 16; /* len */
861862

862863
/* Send interrupt, unless VIRTQ_AVAIL_F_NO_INTERRUPT is set */
863-
if (!(ram[queue->QueueAvail] & 1))
864+
if (!(ram[queue->QueueAvail] & 1)) {
865+
fprintf(stderr, "send interrupt\n");
864866
vsnd->InterruptStatus |= VIRTIO_INT__USED_RING;
867+
}
865868
}
866869

867870
static bool virtio_snd_reg_read(virtio_snd_state_t *vsnd,
@@ -1014,6 +1017,7 @@ void virtio_snd_read(hart_t *vm,
10141017
uint8_t width,
10151018
uint32_t *value)
10161019
{
1020+
pthread_mutex_lock(&virtio_snd_mutex);
10171021
switch (width) {
10181022
case RV_MEM_LW:
10191023
if (!virtio_snd_reg_read(vsnd, addr >> 2, value))
@@ -1024,19 +1028,21 @@ void virtio_snd_read(hart_t *vm,
10241028
case RV_MEM_LHU:
10251029
case RV_MEM_LH:
10261030
vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val);
1027-
return;
1031+
break;
10281032

10291033
default:
10301034
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0);
1031-
return;
1035+
break;
10321036
}
1037+
pthread_mutex_unlock(&virtio_snd_mutex);
10331038
}
10341039
void virtio_snd_write(hart_t *vm,
10351040
virtio_snd_state_t *vsnd,
10361041
uint32_t addr,
10371042
uint8_t width,
10381043
uint32_t value)
10391044
{
1045+
pthread_mutex_lock(&virtio_snd_mutex);
10401046
switch (width) {
10411047
case RV_MEM_SW:
10421048
if (!virtio_snd_reg_write(vsnd, addr >> 2, value))
@@ -1045,11 +1051,12 @@ void virtio_snd_write(hart_t *vm,
10451051
case RV_MEM_SB:
10461052
case RV_MEM_SH:
10471053
vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val);
1048-
return;
1054+
break;
10491055
default:
10501056
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0);
1051-
return;
1057+
break;
10521058
}
1059+
pthread_mutex_unlock(&virtio_snd_mutex);
10531060
}
10541061

10551062
bool virtio_snd_init(virtio_snd_state_t *vsnd)

0 commit comments

Comments
 (0)