@@ -7,12 +7,13 @@ extern crate alloc;
7
7
8
8
use alloc:: boxed:: Box ;
9
9
use alloc:: vec:: Vec ;
10
+ use zephyr:: object:: KobjInit ;
10
11
use zephyr:: time:: { Duration , sleep, Tick } ;
11
12
use zephyr:: {
12
13
printkln,
13
14
kobj_define,
14
15
sys:: uptime_get,
15
- sync:: Arc ,
16
+ sync:: { Arc , Mutex } ,
16
17
} ;
17
18
18
19
use crate :: sysmutex:: SysMutexSync ;
@@ -51,6 +52,9 @@ extern "C" fn rust_main() {
51
52
zephyr:: kconfig:: CONFIG_BOARD ) ;
52
53
printkln ! ( "Time tick: {}" , zephyr:: time:: SYS_FREQUENCY ) ;
53
54
55
+ STAT_MUTEX . init ( ) ;
56
+ let stats = Arc :: new ( Mutex :: new_from ( Stats :: default ( ) , STAT_MUTEX . get ( ) ) ) ;
57
+
54
58
let syncers = get_syncer ( ) ;
55
59
56
60
printkln ! ( "Pre fork" ) ;
@@ -65,9 +69,9 @@ extern "C" fn rust_main() {
65
69
let child_syncer = ChannelSync::new(cq_send.clone(), reply_queues[i].clone());
66
70
let child_syncer = Arc::new(child_syncer);
67
71
*/
68
- // let child_stat = stats.clone();
72
+ let child_stat = stats. clone ( ) ;
69
73
let thread = PHIL_THREAD [ i] . spawn ( PHIL_STACK [ i] . token ( ) , move || {
70
- phil_thread ( i, syncer /* , child_stat*/ ) ;
74
+ phil_thread ( i, syncer, child_stat) ;
71
75
} ) ;
72
76
thread. start ( ) ;
73
77
}
@@ -76,7 +80,7 @@ extern "C" fn rust_main() {
76
80
loop {
77
81
// Periodically, printout the stats.
78
82
zephyr:: time:: sleep ( delay) ;
79
- // stats.lock().unwrap().show();
83
+ stats. lock ( ) . unwrap ( ) . show ( ) ;
80
84
}
81
85
}
82
86
@@ -92,7 +96,7 @@ fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
92
96
result
93
97
}
94
98
95
- fn phil_thread ( n : usize , syncer : Arc < dyn ForkSync > /* , stats: Arc<Mutex<Stats>>*/ ) {
99
+ fn phil_thread ( n : usize , syncer : Arc < dyn ForkSync > , stats : Arc < Mutex < Stats > > ) {
96
100
printkln ! ( "Child {} started: {:?}" , n, syncer) ;
97
101
98
102
// Determine our two forks.
@@ -112,20 +116,58 @@ fn phil_thread(n: usize, syncer: Arc<dyn ForkSync> /*, stats: Arc<Mutex<Stats>>*
112
116
syncer. take ( forks. 1 ) ;
113
117
114
118
let delay = get_random_delay ( n, 25 ) ;
115
- printkln ! ( "Child {} eating ({} ms)" , n, delay) ;
119
+ // printkln!("Child {} eating ({} ms)", n, delay);
116
120
sleep ( delay) ;
117
- // stats.lock().unwrap().record_eat(n, delay);
121
+ stats. lock ( ) . unwrap ( ) . record_eat ( n, delay) ;
118
122
119
123
// Release the forks.
120
124
// printkln!("Child {} giving up forks", n);
121
125
syncer. release ( forks. 1 ) ;
122
126
syncer. release ( forks. 0 ) ;
123
127
124
128
let delay = get_random_delay ( n, 25 ) ;
125
- printkln ! ( "Child {} thinking ({} ms)" , n, delay) ;
129
+ // printkln!("Child {} thinking ({} ms)", n, delay);
126
130
sleep ( delay) ;
127
- // stats.lock().unwrap().record_think(n, delay);
131
+ stats. lock ( ) . unwrap ( ) . record_think ( n, delay) ;
132
+ }
133
+ }
134
+ }
135
+
136
+ /// Instead of just printing out so much information that the data just scrolls by, gather statistics.
137
+ #[ derive( Default ) ]
138
+ struct Stats {
139
+ /// How many times each philospher has gone through the loop.
140
+ count : [ u64 ; NUM_PHIL ] ,
141
+ /// How much time each philosopher has spent eating.
142
+ eating : [ u64 ; NUM_PHIL ] ,
143
+ /// How much time each pilosopher has spent thinking.
144
+ thinking : [ u64 ; NUM_PHIL ] ,
145
+ }
146
+
147
+ impl Stats {
148
+ fn record_eat ( & mut self , index : usize , time : Duration ) {
149
+ self . eating [ index] += time. to_millis ( ) ;
150
+ }
151
+
152
+ fn record_think ( & mut self , index : usize , time : Duration ) {
153
+ self . thinking [ index] += time. to_millis ( ) ;
154
+ self . count [ index] += 1 ;
155
+ }
156
+
157
+ fn show ( & self ) {
158
+ printkln ! ( "{:?}, e:{:?}, t:{:?}" , self . count, self . eating, self . thinking) ;
159
+
160
+ /*
161
+ // Invoke the thread analyzer report.
162
+ {
163
+ extern "C" {
164
+ fn thread_analyzer_print(cpu: usize);
165
+ }
166
+ unsafe {
167
+ thread_analyzer_print(0);
168
+ }
128
169
}
170
+ */
129
171
}
130
172
}
131
173
@@ -141,4 +183,7 @@ fn get_random_delay(id: usize, period: usize) -> Duration {
141
183
kobj_define ! {
142
184
static PHIL_THREAD : [ StaticThread ; NUM_PHIL ] ;
143
185
static PHIL_STACK : [ ThreadStack <PHIL_STACK_SIZE >; NUM_PHIL ] ;
186
+
187
+ // A mutex to hold statistics data.
188
+ static STAT_MUTEX : StaticMutex ;
144
189
}
0 commit comments