@@ -272,6 +272,9 @@ typedef struct {
272272#define  VSND_RING_SZ_MASK  0x0FFFFFFFULL /* ring size mask */ 
273273typedef  struct  {
274274    void  * buffer ;
275+     pthread_cond_t  readable , writable ;
276+     int  buf_ev_notity ;
277+     pthread_mutex_t  lock ;
275278    struct  prod  {
276279        volatile  uint32_t  head ; /* producer head */ 
277280        volatile  uint32_t  tail ; /* producer tail */ 
@@ -298,9 +301,9 @@ typedef struct {
298301    // PCM frame ring buffer 
299302    virtio_snd_ring_buffer_t  ring ;
300303} virtio_snd_prop_t ;
301- #define  VSND_COMPILER_BARRIER  \
302-     do {                      \
303-         asm("" ::: "memory"); \
304+ #define  VSND_COMPILER_BARRIER         \
305+     do {                             \
306+         asm("mfence " ::: "memory"); \
304307    } while (0)
305308
306309static  virtio_snd_config_t  vsnd_configs [VSND_DEV_CNT_MAX ];
@@ -518,6 +521,9 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
518521    vsnd_props [stream_id ].ring .cons .size  =  sz ;
519522    vsnd_props [stream_id ].ring .prod .mask  =  sz  -  1 ;
520523    vsnd_props [stream_id ].ring .cons .mask  =  sz  -  1 ;
524+     pthread_mutex_init (& vsnd_props [stream_id ].ring .lock , NULL );
525+     pthread_cond_init (& vsnd_props [stream_id ].ring .readable , NULL );
526+     pthread_cond_init (& vsnd_props [stream_id ].ring .writable , NULL );
521527
522528    * plen  =  0 ;
523529    fprintf (stderr , "virtio_snd_read_pcm_prepare\n" );
@@ -588,11 +594,15 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
588594    }
589595
590596    vsnd_props [stream_id ].pp .hdr .hdr .code  =  VIRTIO_SND_R_PCM_RELEASE ;
591-     CNFAClose (vsnd_props [stream_id ].audio_host );
592-     fprintf (stderr , "pass CNFAclose\n" );
593597
594598    /* Tear down the PCM frames. */ 
595599    free (vsnd_props [stream_id ].ring .buffer );
600+     pthread_mutex_destroy (& vsnd_props [stream_id ].ring .lock );
601+     pthread_cond_destroy (& vsnd_props [stream_id ].ring .readable );
602+     pthread_cond_destroy (& vsnd_props [stream_id ].ring .writable );
603+ 
604+     CNFAClose (vsnd_props [stream_id ].audio_host );
605+     fprintf (stderr , "pass CNFAclose\n" );
596606
597607    * plen  =  0 ;
598608    fprintf (stderr , "virtio_snd_read_pcm_release\n" );
@@ -610,6 +620,12 @@ static void __virtio_snd_frame_dequeue(short *out,
610620    uint32_t  cons_next , entries ;
611621    uint32_t  mask  =  props -> ring .cons .mask ;
612622
623+     pthread_mutex_lock (& props -> ring .lock );
624+     while  (props -> ring .buf_ev_notity  <  1 ) {
625+         fprintf (stderr , "---wair in deque---\n" );
626+         pthread_cond_wait (& props -> ring .readable , & props -> ring .lock );
627+     }
628+ 
613629    cons_head  =  props -> ring .cons .head ;
614630    prod_tail  =  props -> ring .prod .tail ;
615631    /* The subtraction is done between two unsigned 32bits value 
@@ -639,10 +655,16 @@ static void __virtio_snd_frame_dequeue(short *out,
639655    } else  {
640656        memcpy (out , props -> ring .buffer  +  idx , size  -  idx );
641657        memcpy (out  +  (size  -  idx ), props -> ring .buffer , n  -  (size  -  idx ));
658+         fprintf (stderr , "=== start %"  PRIu32  " end %"  PRIu32  "\n" , size  -  idx ,
659+                 n  -  (size  -  idx ));
642660    }
643661    VSND_COMPILER_BARRIER ;
644662
645663    props -> ring .cons .tail  =  cons_next ;
664+ 
665+     props -> ring .buf_ev_notity -- ;
666+     pthread_cond_signal (& props -> ring .writable );
667+     pthread_mutex_unlock (& props -> ring .lock );
646668}
647669static  void  virtio_snd_cb (struct  CNFADriver  * dev ,
648670                          short  * out ,
@@ -656,7 +678,6 @@ static void virtio_snd_cb(struct CNFADriver *dev,
656678    uint32_t  out_buf_sz  =  framesp  *  channels ;
657679
658680    pthread_mutex_lock (& virtio_snd_ctrl_mutex );
659- 
660681    while  (v_ptr -> guest_playing  ==  0 ) {
661682        fprintf (stderr , "wait ctrl cond\n" );
662683        memset (out , 0 , sizeof (* out ) *  out_buf_sz );
@@ -667,7 +688,8 @@ static void virtio_snd_cb(struct CNFADriver *dev,
667688    totalframesp  +=  framesp ;
668689
669690    uint32_t  id  =  v_ptr -> stream_id ;
670-     fprintf (stderr , "start to play with out_buf_sz %"  PRIu32  "\n" , out_buf_sz );
691+     // fprintf(stderr, "start to play with out_buf_sz %" PRIu32 "\n", 
692+     // out_buf_sz); 
671693
672694    /* TODO: add single consumer */ 
673695#if  1 
@@ -791,6 +813,12 @@ static void __virtio_snd_frame_enqueue(void *payload,
791813    virtio_snd_prop_t  * props  =  & vsnd_props [stream_id ];
792814    uint32_t  mask  =  props -> ring .prod .mask ;
793815
816+     pthread_mutex_lock (& props -> ring .lock );
817+     while  (props -> ring .buf_ev_notity  >  0 ) {
818+         fprintf (stderr , "---wait for enque---\n" );
819+         pthread_cond_wait (& props -> ring .writable , & props -> ring .lock );
820+     }
821+ 
794822    prod_head  =  props -> ring .prod .head ;
795823    cons_tail  =  props -> ring .cons .tail ;
796824    /* The subtraction is done between two unsigned 32bits value 
@@ -828,6 +856,10 @@ static void __virtio_snd_frame_enqueue(void *payload,
828856
829857    /* Update prod_tail */ 
830858    props -> ring .prod .tail  =  prod_next ;
859+ 
860+     props -> ring .buf_ev_notity ++ ;
861+     pthread_cond_signal (& props -> ring .readable );
862+     pthread_mutex_unlock (& props -> ring .lock );
831863}
832864
833865typedef  struct  {
0 commit comments