66//
77// Copyright © 2019 Intel Corporation
88//
9- // Copyright (C) 2020 Alibaba Cloud. All rights reserved.
9+ // Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
1010//
1111// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
1212
@@ -26,7 +26,7 @@ use std::mem::size_of;
2626use std:: num:: Wrapping ;
2727use std:: ops:: { Deref , DerefMut } ;
2828use std:: sync:: atomic:: { fence, Ordering } ;
29- use std:: sync:: MutexGuard ;
29+ use std:: sync:: { Arc , Mutex , MutexGuard } ;
3030
3131use defs:: {
3232 VIRTQ_AVAIL_ELEMENT_SIZE , VIRTQ_AVAIL_RING_HEADER_SIZE , VIRTQ_AVAIL_RING_META_SIZE ,
@@ -872,6 +872,97 @@ impl<M: GuestAddressSpace> QueueStateT<M> for QueueState<M> {
872872 }
873873}
874874
875+ /// Struct to maintain information and manipulate state of a virtio queue for multi-threaded
876+ /// context.
877+ #[ derive( Clone , Debug ) ]
878+ pub struct QueueStateSync < M : GuestAddressSpace > {
879+ state : Arc < Mutex < QueueState < M > > > ,
880+ }
881+
882+ impl < M : GuestAddressSpace > QueueStateT < M > for QueueStateSync < M > {
883+ fn new ( max_size : u16 ) -> Self {
884+ QueueStateSync {
885+ state : Arc :: new ( Mutex :: new ( QueueState :: new ( max_size) ) ) ,
886+ }
887+ }
888+
889+ fn is_valid ( & self , mem : & M :: T ) -> bool {
890+ self . state . lock ( ) . unwrap ( ) . is_valid ( mem)
891+ }
892+
893+ fn reset ( & mut self ) {
894+ self . state . lock ( ) . unwrap ( ) . reset ( ) ;
895+ }
896+
897+ fn lock ( & mut self ) -> QueueStateGuard < ' _ , M > {
898+ QueueStateGuard :: MutexGuard ( self . state . lock ( ) . unwrap ( ) )
899+ }
900+
901+ fn max_size ( & self ) -> u16 {
902+ self . state . lock ( ) . unwrap ( ) . max_size ( )
903+ }
904+
905+ fn actual_size ( & self ) -> u16 {
906+ self . state . lock ( ) . unwrap ( ) . actual_size ( )
907+ }
908+
909+ fn set_size ( & mut self , size : u16 ) {
910+ self . state . lock ( ) . unwrap ( ) . set_size ( size)
911+ }
912+
913+ fn ready ( & self ) -> bool {
914+ self . state . lock ( ) . unwrap ( ) . ready
915+ }
916+
917+ fn set_ready ( & mut self , ready : bool ) {
918+ self . state . lock ( ) . unwrap ( ) . set_ready ( ready)
919+ }
920+
921+ fn set_desc_table_address ( & mut self , low : Option < u32 > , high : Option < u32 > ) {
922+ self . state . lock ( ) . unwrap ( ) . set_desc_table_address ( low, high) ;
923+ }
924+
925+ fn set_avail_ring_address ( & mut self , low : Option < u32 > , high : Option < u32 > ) {
926+ self . state . lock ( ) . unwrap ( ) . set_avail_ring_address ( low, high) ;
927+ }
928+
929+ fn set_used_ring_address ( & mut self , low : Option < u32 > , high : Option < u32 > ) {
930+ self . state . lock ( ) . unwrap ( ) . set_used_ring_address ( low, high) ;
931+ }
932+
933+ fn set_event_idx ( & mut self , enabled : bool ) {
934+ self . state . lock ( ) . unwrap ( ) . set_event_idx ( enabled) ;
935+ }
936+
937+ fn avail_idx ( & self , mem : & M :: T , order : Ordering ) -> Result < Wrapping < u16 > , Error > {
938+ self . state . lock ( ) . unwrap ( ) . avail_idx ( mem, order)
939+ }
940+
941+ fn add_used ( & mut self , mem : & M :: T , head_index : u16 , len : u32 ) -> Result < ( ) , Error > {
942+ self . state . lock ( ) . unwrap ( ) . add_used ( mem, head_index, len)
943+ }
944+
945+ fn enable_notification ( & mut self , mem : & M :: T ) -> Result < bool , Error > {
946+ self . state . lock ( ) . unwrap ( ) . enable_notification ( mem)
947+ }
948+
949+ fn disable_notification ( & mut self , mem : & M :: T ) -> Result < ( ) , Error > {
950+ self . state . lock ( ) . unwrap ( ) . disable_notification ( mem)
951+ }
952+
953+ fn needs_notification ( & mut self , mem : & M :: T ) -> Result < bool , Error > {
954+ self . state . lock ( ) . unwrap ( ) . needs_notification ( mem)
955+ }
956+
957+ fn next_avail ( & self ) -> u16 {
958+ self . state . lock ( ) . unwrap ( ) . next_avail ( )
959+ }
960+
961+ fn set_next_avail ( & mut self , next_avail : u16 ) {
962+ self . state . lock ( ) . unwrap ( ) . set_next_avail ( next_avail) ;
963+ }
964+ }
965+
875966/// A convenient wrapper struct for a virtio queue, with associated GuestMemory object.
876967#[ derive( Clone , Debug ) ]
877968pub struct Queue < M : GuestAddressSpace , S : QueueStateT < M > = QueueState < M > > {
0 commit comments