@@ -611,6 +611,7 @@ impl PendingEvents {
611611struct RunningTcs {
612612 tcs_address : TcsAddress ,
613613 mode : EnclaveEntry ,
614+ aex_count : tcs:: AexCount ,
614615}
615616
616617enum EnclaveKind {
@@ -665,6 +666,7 @@ pub(crate) struct EnclaveState {
665666 // Once set to Some, the guards should not be dropped for the lifetime of the enclave.
666667 fifo_guards : Mutex < Option < FifoGuards > > ,
667668 return_queue_tx : Mutex < Option < ipc_queue:: AsyncSender < Return , QueueSynchronizer > > > ,
669+ aex_counts : Option < Mutex < FnvHashMap < TcsAddress , Arc < AtomicUsize > > > > ,
668670}
669671
670672struct Work {
@@ -682,7 +684,7 @@ impl Work {
682684 let buf = RefCell :: new ( [ 0u8 ; 1024 ] ) ;
683685 let usercall_send_data = match self . entry {
684686 CoEntry :: Initial ( erased_tcs, p1, p2, p3, p4, p5) => {
685- let coresult = tcs:: coenter ( erased_tcs, p1, p2, p3, p4, p5, Some ( & buf) ) ;
687+ let coresult = tcs:: coenter ( erased_tcs, p1, p2, p3, p4, p5, Some ( & buf) , self . tcs . aex_count . clone ( ) ) ;
686688 UsercallSendData :: Sync ( coresult, self . tcs , buf)
687689 }
688690 CoEntry :: Resume ( usercall, coresult) => {
@@ -736,6 +738,7 @@ impl EnclaveState {
736738 threads_vector : Vec < ErasedTcs > ,
737739 forward_panics : bool ,
738740 force_time_usercalls : bool ,
741+ aex_counts : Option < Mutex < FnvHashMap < TcsAddress , Arc < AtomicUsize > > > > ,
739742 ) -> Arc < Self > {
740743 let mut fds = FnvHashMap :: default ( ) ;
741744
@@ -779,6 +782,7 @@ impl EnclaveState {
779782 force_time_usercalls,
780783 fifo_guards : Mutex :: new ( None ) ,
781784 return_queue_tx : Mutex :: new ( None ) ,
785+ aex_counts,
782786 } )
783787 }
784788
@@ -1053,7 +1057,10 @@ impl EnclaveState {
10531057 }
10541058 } ) ;
10551059
1056- local_set. block_on ( & mut rt, select_fut. unit_error ( ) ) . unwrap ( )
1060+ let ret = local_set. block_on ( & mut rt, select_fut. unit_error ( ) ) . unwrap ( ) ;
1061+ #[ cfg( feature = "instrumentation" ) ]
1062+ tokio:: runtime:: Runtime :: new ( ) . unwrap ( ) . block_on ( enclave. print_aex_counts ( ) ) ;
1063+ ret
10571064 }
10581065
10591066 fn run (
@@ -1105,12 +1112,18 @@ impl EnclaveState {
11051112 usercall_ext : Option < Box < dyn UsercallExtension > > ,
11061113 forward_panics : bool ,
11071114 force_time_usercalls : bool ,
1115+ track_aex_count : bool ,
11081116 cmd_args : Vec < Vec < u8 > > ,
11091117 num_of_worker_threads : usize ,
11101118 ) -> StdResult < ( ) , anyhow:: Error > {
11111119 assert ! ( num_of_worker_threads > 0 , "worker_threads cannot be zero" ) ;
11121120 let mut event_queues =
11131121 FnvHashMap :: with_capacity_and_hasher ( threads. len ( ) + 1 , Default :: default ( ) ) ;
1122+ let mut aex_counts: Option < FnvHashMap < TcsAddress , Arc < AtomicUsize > > > = if track_aex_count {
1123+ Some ( FnvHashMap :: with_capacity_and_hasher ( threads. len ( ) + 1 , Default :: default ( ) ) )
1124+ } else {
1125+ None
1126+ } ;
11141127 let main = Self :: event_queue_add_tcs ( & mut event_queues, main) ;
11151128
11161129 let mut args = Vec :: with_capacity ( cmd_args. len ( ) ) ;
@@ -1123,10 +1136,16 @@ impl EnclaveState {
11231136 let argc = args. len ( ) ;
11241137 let argv = Box :: into_raw ( args. into_boxed_slice ( ) ) as * const u8 ;
11251138
1139+ let aex_count = if let Some ( aex_counts) = & mut aex_counts {
1140+ tcs:: AexCount :: from ( aex_counts. entry ( main. tcs . address ( ) ) . or_default ( ) . clone ( ) )
1141+ } else {
1142+ tcs:: AexCount :: none ( )
1143+ } ;
11261144 let main_work = Work {
11271145 tcs : RunningTcs {
11281146 tcs_address : main. tcs . address ( ) ,
11291147 mode : EnclaveEntry :: ExecutableMain ,
1148+ aex_count,
11301149 } ,
11311150 entry : CoEntry :: Initial ( main. tcs , argv as _ , argc as _ , 0 , 0 , 0 ) ,
11321151 } ;
@@ -1137,7 +1156,7 @@ impl EnclaveState {
11371156 other_reasons : vec ! [ ] ,
11381157 } ) ,
11391158 } ) ;
1140- let enclave = EnclaveState :: new ( kind, event_queues, usercall_ext, threads, forward_panics, force_time_usercalls) ;
1159+ let enclave = EnclaveState :: new ( kind, event_queues, usercall_ext, threads, forward_panics, force_time_usercalls, aex_counts . map ( Mutex :: new ) ) ;
11411160
11421161 let main_result = EnclaveState :: run ( enclave. clone ( ) , num_of_worker_threads, main_work) ;
11431162
@@ -1194,7 +1213,7 @@ impl EnclaveState {
11941213
11951214 let kind = EnclaveKind :: Library ( Library { } ) ;
11961215
1197- let enclave = EnclaveState :: new ( kind, event_queues, usercall_ext, threads, forward_panics, force_time_usercalls) ;
1216+ let enclave = EnclaveState :: new ( kind, event_queues, usercall_ext, threads, forward_panics, force_time_usercalls, None ) ;
11981217 return enclave;
11991218 }
12001219
@@ -1211,6 +1230,7 @@ impl EnclaveState {
12111230 tcs : RunningTcs {
12121231 tcs_address : thread. tcs . address ( ) ,
12131232 mode : EnclaveEntry :: Library ,
1233+ aex_count : tcs:: AexCount :: none ( ) ,
12141234 } ,
12151235 entry : CoEntry :: Initial ( thread. tcs , p1, p2, p3, p4, p5) ,
12161236 } ;
@@ -1244,6 +1264,17 @@ impl EnclaveState {
12441264 pending_events. abort ( ) ;
12451265 }
12461266 }
1267+
1268+ #[ cfg( feature = "instrumentation" ) ]
1269+ async fn print_aex_counts ( & self ) {
1270+ if let Some ( aex_counts) = & self . aex_counts {
1271+ eprintln ! ( "===AEX counts per TCS===" ) ;
1272+ for ( addr, count) in aex_counts. lock ( ) . await . iter ( ) {
1273+ eprintln ! ( "{:p} {}" , addr, count. load( Ordering :: Relaxed ) ) ;
1274+ }
1275+ eprintln ! ( "========================" ) ;
1276+ }
1277+ }
12471278}
12481279
12491280#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
@@ -1540,7 +1571,7 @@ impl<'tcs> IOHandlerInput<'tcs> {
15401571 }
15411572
15421573 #[ inline( always) ]
1543- fn launch_thread ( & self ) -> IoResult < ( ) > {
1574+ async fn launch_thread ( & self ) -> IoResult < ( ) > {
15441575 // check if enclave is of type command
15451576 self . enclave
15461577 . kind
@@ -1553,10 +1584,16 @@ impl<'tcs> IOHandlerInput<'tcs> {
15531584 }
15541585 } ;
15551586
1587+ let aex_count = if let Some ( aex_counts) = & self . enclave . aex_counts {
1588+ tcs:: AexCount :: from ( aex_counts. lock ( ) . await . entry ( new_tcs. tcs . address ( ) ) . or_default ( ) . clone ( ) )
1589+ } else {
1590+ tcs:: AexCount :: none ( )
1591+ } ;
15561592 let ret = self . work_sender . send ( Work {
15571593 tcs : RunningTcs {
15581594 tcs_address : new_tcs. tcs . address ( ) ,
15591595 mode : EnclaveEntry :: ExecutableNonMain ,
1596+ aex_count,
15601597 } ,
15611598 entry : CoEntry :: Initial ( new_tcs. tcs , 0 , 0 , 0 , 0 , 0 ) ,
15621599 } ) ;
0 commit comments