@@ -18,7 +18,7 @@ use zephyr::{
18
18
printkln,
19
19
kobj_define,
20
20
sys:: uptime_get,
21
- sync:: Arc ,
21
+ sync:: { Arc , Mutex } ,
22
22
} ;
23
23
24
24
// These are optional, based on Kconfig, so allow them to be unused.
@@ -68,21 +68,25 @@ extern "C" fn rust_main() {
68
68
zephyr:: kconfig:: CONFIG_BOARD ) ;
69
69
printkln ! ( "Time tick: {}" , zephyr:: time:: SYS_FREQUENCY ) ;
70
70
71
+ let stats = Arc :: new ( Mutex :: new_from ( Stats :: default ( ) , STAT_MUTEX . init_once ( ( ) ) . unwrap ( ) ) ) ;
72
+
71
73
let syncers = get_syncer ( ) ;
72
74
73
75
printkln ! ( "Pre fork" ) ;
74
76
75
77
for ( i, syncer) in ( 0 ..NUM_PHIL ) . zip ( syncers. into_iter ( ) ) {
78
+ let child_stat = stats. clone ( ) ;
76
79
let thread = PHIL_THREADS [ i] . init_once ( PHIL_STACKS [ i] . init_once ( ( ) ) . unwrap ( ) ) . unwrap ( ) ;
77
80
thread. spawn ( move || {
78
- phil_thread ( i, syncer) ;
81
+ phil_thread ( i, syncer, child_stat ) ;
79
82
} ) ;
80
83
}
81
84
82
85
let delay = Duration :: secs_at_least ( 10 ) ;
83
86
loop {
84
87
// Periodically, printout the stats.
85
88
zephyr:: time:: sleep ( delay) ;
89
+ stats. lock ( ) . unwrap ( ) . show ( ) ;
86
90
}
87
91
}
88
92
@@ -121,7 +125,7 @@ fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
121
125
get_channel_syncer ( )
122
126
}
123
127
124
- fn phil_thread ( n : usize , syncer : Arc < dyn ForkSync > ) {
128
+ fn phil_thread ( n : usize , syncer : Arc < dyn ForkSync > , stats : Arc < Mutex < Stats > > ) {
125
129
printkln ! ( "Child {} started: {:?}" , n, syncer) ;
126
130
127
131
// Determine our two forks.
@@ -134,26 +138,26 @@ fn phil_thread(n: usize, syncer: Arc<dyn ForkSync>) {
134
138
135
139
loop {
136
140
{
137
- printkln ! ( "Child {} hungry" , n) ;
138
- printkln ! ( "Child {} take left fork" , n) ;
141
+ // printkln!("Child {} hungry", n);
142
+ // printkln!("Child {} take left fork", n);
139
143
syncer. take ( forks. 0 ) ;
140
- printkln ! ( "Child {} take right fork" , n) ;
144
+ // printkln!("Child {} take right fork", n);
141
145
syncer. take ( forks. 1 ) ;
142
146
143
147
let delay = get_random_delay ( n, 25 ) ;
144
- printkln ! ( "Child {} eating ({} ms)" , n, delay) ;
148
+ // printkln!("Child {} eating ({} ms)", n, delay);
145
149
sleep ( delay) ;
146
- // stats.lock().unwrap().record_eat(n, delay);
150
+ stats. lock ( ) . unwrap ( ) . record_eat ( n, delay) ;
147
151
148
152
// Release the forks.
149
- printkln ! ( "Child {} giving up forks" , n) ;
153
+ // printkln!("Child {} giving up forks", n);
150
154
syncer. release ( forks. 1 ) ;
151
155
syncer. release ( forks. 0 ) ;
152
156
153
157
let delay = get_random_delay ( n, 25 ) ;
154
- printkln ! ( "Child {} thinking ({} ms)" , n, delay) ;
158
+ // printkln!("Child {} thinking ({} ms)", n, delay);
155
159
sleep ( delay) ;
156
- // stats.lock().unwrap().record_think(n, delay);
160
+ stats. lock ( ) . unwrap ( ) . record_think ( n, delay) ;
157
161
}
158
162
}
159
163
}
@@ -167,7 +171,36 @@ fn get_random_delay(id: usize, period: usize) -> Duration {
167
171
Duration :: millis_at_least ( ( ( delay + 1 ) * period) as Tick )
168
172
}
169
173
174
+ /// Instead of just printint out so much information that the data just scolls by, gather
175
+ /// statistics.
176
+ #[ derive( Default ) ]
177
+ struct Stats {
178
+ /// How many times each philosopher has gone through the loop.
179
+ count : [ u64 ; NUM_PHIL ] ,
180
+ /// How much time each philosopher has spent eating.
181
+ eating : [ u64 ; NUM_PHIL ] ,
182
+ /// How much time each philosopher has spent thinking.
183
+ thinking : [ u64 ; NUM_PHIL ] ,
184
+ }
185
+
186
+ impl Stats {
187
+ fn record_eat ( & mut self , index : usize , time : Duration ) {
188
+ self . eating [ index] += time. to_millis ( ) ;
189
+ }
190
+
191
+ fn record_think ( & mut self , index : usize , time : Duration ) {
192
+ self . thinking [ index] += time. to_millis ( ) ;
193
+ self . count [ index] += 1 ;
194
+ }
195
+
196
+ fn show ( & self ) {
197
+ printkln ! ( "{:?}, e:{:?}, t:{:?}" , self . count, self . eating, self . thinking) ;
198
+ }
199
+ }
200
+
170
201
kobj_define ! {
171
202
static PHIL_THREADS : [ StaticThread ; NUM_PHIL ] ;
172
203
static PHIL_STACKS : [ ThreadStack <PHIL_STACK_SIZE >; NUM_PHIL ] ;
204
+
205
+ static STAT_MUTEX : StaticMutex ;
173
206
}
0 commit comments