Skip to content

Commit

Permalink
Fix re-initialize queue head problem
Browse files Browse the repository at this point in the history
  • Loading branch information
Cuda-Chen committed Nov 18, 2024
1 parent dfc8935 commit efaecc1
Showing 1 changed file with 33 additions and 26 deletions.
59 changes: 33 additions & 26 deletions virtio-snd.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,14 +445,15 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,

/* Control the callback to prepare the buffer */
/* TODO: add lock to avoid race condition */
pthread_mutex_lock(&virtio_snd_mutex);
// pthread_mutex_lock(&virtio_snd_mutex);
v.guest_playing = false;
v.stream_id = stream_id;
pthread_mutex_unlock(&virtio_snd_mutex);
// pthread_mutex_unlock(&virtio_snd_mutex);
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_PREPARE;
vsnd_props[stream_id].audio_host =
CNFAInit(NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0,
vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &v);
INIT_QUEUE_HEAD(&(vsnd_props[stream_id].pcm_frames_q));

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

/* Control the callback to start playing */
/* TODO: add lock to avoid race condition */
pthread_mutex_lock(&virtio_snd_mutex);
// pthread_mutex_lock(&virtio_snd_mutex);
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_START;
v.guest_playing = true;
pthread_mutex_unlock(&virtio_snd_mutex);
// pthread_mutex_unlock(&virtio_snd_mutex);

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

/* Control the callback to stop playing */
/* TODO: add lock to avoid race condition */
pthread_mutex_lock(&virtio_snd_mutex);
// pthread_mutex_lock(&virtio_snd_mutex);
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_STOP;
v.guest_playing = false;
pthread_mutex_lock(&virtio_snd_mutex);
// pthread_mutex_lock(&virtio_snd_mutex);

*plen = 0;
fprintf(stderr, "virtio_snd_read_pcm_stop\n");
Expand All @@ -522,24 +523,24 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
}
/* Control the callback to stop playing */
/* TODO: add lock to avoid race condition */
pthread_mutex_lock(&virtio_snd_mutex);
// pthread_mutex_lock(&virtio_snd_mutex);
v.guest_playing = false;
pthread_mutex_unlock(&virtio_snd_mutex);
// pthread_mutex_unlock(&virtio_snd_mutex);

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

/* Tear down the PCM frames. */
virtio_snd_pcm_frame_t *t = NULL;
struct queue_head frame_q = vsnd_props[stream_id].pcm_frames_q;
struct queue_head *frame_q = &(vsnd_props[stream_id].pcm_frames_q);
virtio_snd_pcm_frame_t *frame = vsnd_props[stream_id].pcm_frames;
queue_for_each_entry_safe(frame, t, &frame_q, q)
queue_for_each_entry_safe(frame, t, frame_q, q)
{
free(frame->buf);
queue_del(&frame->q);
free(frame);
}
assert(queue_empty(&frame_q));
assert(queue_empty(frame_q));

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

if (!playing) {
fprintf(stderr, "notplaying totalframesr: %d totalframesp: %d\n",
totalframesr, totalframesp);
/*fprintf(stderr, "notplaying totalframesr: %d totalframesp: %d\n",
totalframesr, totalframesp);*/
return;
}

Expand Down Expand Up @@ -696,7 +697,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
uint32_t *plen)
{
/* Start of critical section */
pthread_mutex_lock(&virtio_snd_mutex);
// pthread_mutex_lock(&virtio_snd_mutex);

/* TODO: clarify the usage of the last descriptor. */
/* virtio-snd TX uses arbitrary number of virtqueue descriptors.
Expand All @@ -709,12 +710,12 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
*/
virtq_desc_queue_node_t *node;
struct queue_head q;

INIT_QUEUE_HEAD(&q);
assert(queue_empty(&q));

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

Expand All @@ -738,8 +739,8 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
int idx = 0;
uint32_t stream_id;
uintptr_t base = (uintptr_t) vsnd->ram;
struct queue_head frame_q = vsnd_props[stream_id].pcm_frames_q;
INIT_QUEUE_HEAD(&frame_q);
struct queue_head *frame_q = &(vsnd_props[stream_id].pcm_frames_q);

virtio_snd_pcm_frame_t *frame = vsnd_props[stream_id].pcm_frames;
uint32_t ret_len = 0;
queue_for_each_entry(node, &q, q)
Expand All @@ -759,7 +760,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
(virtio_snd_pcm_status_t *) (base + addr);
response->status = VIRTIO_SND_S_OK;
response->latency_bytes = ret_len;
*plen = sizeof(virtio_snd_pcm_status_t);
*plen = sizeof(*response);
fprintf(stderr, "TX response\n");
goto early_continue;
}
Expand All @@ -768,7 +769,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
void *buf = (void *) (base + addr);
frame->buf = (void *) malloc(sizeof(frame->buf) * len);
memcpy(frame->buf, buf, len);
queue_push(&frame->q, &frame_q);
queue_push(&frame->q, frame_q);
ret_len += len;

early_continue:
Expand All @@ -786,7 +787,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
}

/* End of critical seciont. */
pthread_mutex_unlock(&virtio_snd_mutex);
// pthread_mutex_unlock(&virtio_snd_mutex);

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

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

static bool virtio_snd_reg_read(virtio_snd_state_t *vsnd,
Expand Down Expand Up @@ -1014,6 +1017,7 @@ void virtio_snd_read(hart_t *vm,
uint8_t width,
uint32_t *value)
{
pthread_mutex_lock(&virtio_snd_mutex);
switch (width) {
case RV_MEM_LW:
if (!virtio_snd_reg_read(vsnd, addr >> 2, value))
Expand All @@ -1024,19 +1028,21 @@ void virtio_snd_read(hart_t *vm,
case RV_MEM_LHU:
case RV_MEM_LH:
vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val);
return;
break;

default:
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0);
return;
break;
}
pthread_mutex_unlock(&virtio_snd_mutex);
}
void virtio_snd_write(hart_t *vm,
virtio_snd_state_t *vsnd,
uint32_t addr,
uint8_t width,
uint32_t value)
{
pthread_mutex_lock(&virtio_snd_mutex);
switch (width) {
case RV_MEM_SW:
if (!virtio_snd_reg_write(vsnd, addr >> 2, value))
Expand All @@ -1045,11 +1051,12 @@ void virtio_snd_write(hart_t *vm,
case RV_MEM_SB:
case RV_MEM_SH:
vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val);
return;
break;
default:
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0);
return;
break;
}
pthread_mutex_unlock(&virtio_snd_mutex);
}

bool virtio_snd_init(virtio_snd_state_t *vsnd)
Expand Down

0 comments on commit efaecc1

Please sign in to comment.