@@ -269,13 +269,15 @@ static virtio_snd_prop_t vsnd_props[VSND_DEV_CNT_MAX] = {
269269static int vsnd_dev_cnt = 0 ;
270270
271271typedef struct {
272- bool guest_playing ;
272+ int32_t guest_playing ;
273273 uint32_t stream_id ;
274274} vsnd_stream_sel_t ;
275275static vsnd_stream_sel_t v ;
276276
277277static pthread_mutex_t virtio_snd_mutex = PTHREAD_MUTEX_INITIALIZER ;
278+ static pthread_mutex_t virtio_snd_ctrl_mutex = PTHREAD_MUTEX_INITIALIZER ;
278279static pthread_cond_t virtio_snd_tx_cond = PTHREAD_COND_INITIALIZER ;
280+ static pthread_cond_t virtio_snd_ctrl_cond = PTHREAD_COND_INITIALIZER ;
279281static int tx_ev_notify ;
280282
281283/* Forward declaration */
@@ -451,7 +453,7 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
451453 /* Control the callback to prepare the buffer */
452454 /* TODO: add lock to avoid race condition */
453455 // pthread_mutex_lock(&virtio_snd_mutex);
454- v .guest_playing = false ;
456+ v .guest_playing = 0 ;
455457 v .stream_id = stream_id ;
456458 // pthread_mutex_unlock(&virtio_snd_mutex);
457459 vsnd_props [stream_id ].pp .hdr .hdr .code = VIRTIO_SND_R_PCM_PREPARE ;
@@ -480,10 +482,9 @@ static void virtio_snd_read_pcm_start(const virtio_snd_pcm_hdr_t *query,
480482
481483 /* Control the callback to start playing */
482484 /* TODO: add lock to avoid race condition */
483- // pthread_mutex_lock(&virtio_snd_mutex);
484485 vsnd_props [stream_id ].pp .hdr .hdr .code = VIRTIO_SND_R_PCM_START ;
485- v .guest_playing = true ;
486- // pthread_mutex_unlock(&virtio_snd_mutex );
486+ v .guest_playing ++ ;
487+ pthread_cond_signal ( & virtio_snd_ctrl_cond );
487488
488489 * plen = 0 ;
489490 fprintf (stderr , "virtio_snd_read_pcm_start\n" );
@@ -504,10 +505,9 @@ static void virtio_snd_read_pcm_stop(const virtio_snd_pcm_hdr_t *query,
504505
505506 /* Control the callback to stop playing */
506507 /* TODO: add lock to avoid race condition */
507- // pthread_mutex_lock(&virtio_snd_mutex);
508508 vsnd_props [stream_id ].pp .hdr .hdr .code = VIRTIO_SND_R_PCM_STOP ;
509- v .guest_playing = false ;
510- // pthread_mutex_lock(&virtio_snd_mutex );
509+ v .guest_playing -- ;
510+ pthread_cond_signal ( & virtio_snd_ctrl_cond );
511511
512512 * plen = 0 ;
513513 fprintf (stderr , "virtio_snd_read_pcm_stop\n" );
@@ -528,9 +528,8 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
528528 }
529529 /* Control the callback to stop playing */
530530 /* TODO: add lock to avoid race condition */
531- // pthread_mutex_lock(&virtio_snd_mutex);
532- v .guest_playing = false;
533- // pthread_mutex_unlock(&virtio_snd_mutex);
531+ v .guest_playing = 0 ;
532+ pthread_cond_signal (& virtio_snd_ctrl_cond );
534533
535534 vsnd_props [stream_id ].pp .hdr .hdr .code = VIRTIO_SND_R_PCM_RELEASE ;
536535 CNFAClose (vsnd_props [stream_id ].audio_host );
@@ -577,17 +576,17 @@ static void virtio_snd_cb(struct CNFADriver *dev,
577576 memcpy (out , vsnd_props [id ].buf , output_buf_sz );
578577#endif
579578 vsnd_stream_sel_t * v_ptr = (vsnd_stream_sel_t * ) dev -> opaque ;
580- bool playing = v_ptr -> guest_playing ;
579+
580+ pthread_mutex_lock (& virtio_snd_ctrl_mutex );
581+
582+ while (v_ptr -> guest_playing <= 0 )
583+ pthread_cond_wait (& virtio_snd_ctrl_cond , & virtio_snd_ctrl_mutex );
584+
585+ v_ptr -> guest_playing -- ;
581586
582587 totalframesr += framesr ;
583588 totalframesp += framesp ;
584589
585- if (!playing ) {
586- /*fprintf(stderr, "notplaying totalframesr: %d totalframesp: %d\n",
587- totalframesr, totalframesp);*/
588- return ;
589- }
590-
591590 fprintf (stderr , "start to play\n" );
592591 int channels = dev -> channelsPlay ;
593592 for (int i = 0 ; i < framesp ; i ++ ) {
@@ -602,6 +601,8 @@ static void virtio_snd_cb(struct CNFADriver *dev,
602601 * (out ++ ) = value ;
603602 }
604603 }
604+
605+ pthread_mutex_unlock (& virtio_snd_ctrl_mutex );
605606}
606607
607608#define VSND_DESC_CNT 3
@@ -734,7 +735,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
734735
735736 /* Leave the loop if next-flag is not set */
736737 if (!(desc [3 ] & VIRTIO_DESC_F_NEXT )) {
737- fprintf (stderr , "index %" PRIu32 " no next flag\n" , cnt );
738+ // fprintf(stderr, "index %" PRIu32 " no next flag\n", cnt);
738739 break ;
739740 }
740741 }
@@ -750,21 +751,21 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
750751 {
751752 uint32_t addr = node -> vq_desc .addr ;
752753 uint32_t len = node -> vq_desc .len ;
753- fprintf (stderr , "idx %d addr %" PRIu32 " len %" PRIu32 "\n" , idx , addr ,
754- len );
754+ // fprintf(stderr, "idx %d addr %" PRIu32 " len %" PRIu32 "\n", idx,
755+ // addr, len);
755756 if (idx == 0 ) { // the first descriptor
756757 const virtio_snd_pcm_xfer_t * request =
757758 (virtio_snd_pcm_xfer_t * ) (base + addr );
758759 stream_id = request -> stream_id ;
759- fprintf (stderr , "stream_id %" PRIu32 "\n" , stream_id );
760+ // fprintf(stderr, "stream_id %" PRIu32 "\n", stream_id);
760761 goto early_continue ;
761762 } else if (idx == cnt - 1 ) { // the last descriptor
762763 virtio_snd_pcm_status_t * response =
763764 (virtio_snd_pcm_status_t * ) (base + addr );
764765 response -> status = VIRTIO_SND_S_OK ;
765766 response -> latency_bytes = ret_len ;
766767 * plen = sizeof (* response );
767- fprintf (stderr , "TX response\n" );
768+ // fprintf(stderr, "TX response\n");
768769 goto early_continue ;
769770 }
770771
@@ -811,8 +812,7 @@ static void virtio_queue_notify_handler(
811812 /* Check for new buffers */
812813 uint16_t new_avail = ram [queue -> QueueAvail ] >> 16 ;
813814 if (new_avail - queue -> last_avail > (uint16_t ) queue -> QueueNum )
814- return (fprintf (stderr , "size check fail\n" ),
815- virtio_snd_set_fail (vsnd ));
815+ return virtio_snd_set_fail (vsnd );
816816
817817 if (queue -> last_avail == new_avail )
818818 return ;
@@ -837,7 +837,7 @@ static void virtio_queue_notify_handler(
837837 */
838838 uint32_t len = 0 ;
839839 int result = handler (vsnd , queue , buffer_idx , & len );
840- fprintf (stderr , "len: %" PRIu32 "\n" , len );
840+ // fprintf(stderr, "len: %" PRIu32 "\n", len);
841841 if (result != 0 )
842842 return virtio_snd_set_fail (vsnd );
843843
@@ -850,7 +850,8 @@ static void virtio_queue_notify_handler(
850850 queue -> last_avail ++ ;
851851 new_used ++ ;
852852
853- printf ("last_avail %d new_avail %d\n" , queue -> last_avail , new_avail );
853+ // fprintf(stderr, "last_avail %d new_avail %d\n", queue->last_avail,
854+ // new_avail);
854855 }
855856
856857 /* Check le32 len field of struct virtq_used_elem on the spec */
@@ -859,7 +860,7 @@ static void virtio_queue_notify_handler(
859860
860861 /* Send interrupt, unless VIRTQ_AVAIL_F_NO_INTERRUPT is set */
861862 if (!(ram [queue -> QueueAvail ] & 1 )) {
862- fprintf (stderr , "send interrupt\n" );
863+ // fprintf(stderr, "send interrupt\n");
863864 vsnd -> InterruptStatus |= VIRTIO_INT__USED_RING ;
864865 }
865866}
@@ -871,20 +872,20 @@ static void *func(void *args)
871872{
872873 virtio_snd_state_t * vsnd = (virtio_snd_state_t * ) args ;
873874 for (;;) {
874- fprintf (stderr , "*** tx desc handler is called ***\n" );
875+ // fprintf(stderr, "*** tx desc handler is called ***\n");
875876 pthread_mutex_lock (& virtio_snd_mutex );
876877 while (tx_ev_notify <= 0 ) {
877878 pthread_cond_wait (& virtio_snd_tx_cond , & virtio_snd_mutex );
878- fprintf (stderr , "wait for cond\n" );
879+ // fprintf(stderr, "wait for cond\n");
879880 }
880- fprintf (stderr , "*** start tx critical section ***\n" );
881+ // fprintf(stderr, "*** start tx critical section ***\n");
881882 tx_ev_notify -- ;
882- fprintf (stderr , "*** tx desc handler ***\n" );
883+ // fprintf(stderr, "*** tx desc handler ***\n");
883884 virtio_queue_notify_handler (vsnd , 2 , virtio_snd_tx_desc_handler );
884- fprintf (stderr , "*** end tx cirtical section ***\n" );
885+ // fprintf(stderr, "*** end tx cirtical section ***\n");
885886 pthread_mutex_unlock (& virtio_snd_mutex );
886887 }
887- return NULL ;
888+ pthread_exit ( NULL ) ;
888889}
889890
890891static bool virtio_snd_reg_read (virtio_snd_state_t * vsnd ,
@@ -998,10 +999,8 @@ static bool virtio_snd_reg_write(virtio_snd_state_t *vsnd,
998999 virtio_snd_desc_handler );
9991000 break ;
10001001 case VSND_QUEUE_TX :
1001- fprintf (stderr , "TX start\n" );
10021002 tx_ev_notify ++ ;
10031003 pthread_cond_signal (& virtio_snd_tx_cond );
1004- fprintf (stderr , "TX end\n" );
10051004 break ;
10061005 default :
10071006 fprintf (stderr , "value %d not supported\n" , value );
0 commit comments