1 ! Based on http://research.sun.com/people/mario/java_benchmarking/
2 ! Ported by Factor by Slava Pestov
4 ! Based on original version written in BCPL by Dr Martin Richards
5 ! in 1981 at Cambridge University Computer Laboratory, England
6 ! Java version: Copyright (C) 1995 Sun Microsystems, Inc.
8 ! Outer loop added 8/7/96 by Alex Jacoby
9 USING: values kernel accessors math math.bitwise sequences
10 arrays combinators fry locals ;
11 IN: benchmark.richards
14 TUPLE: packet link id kind a1 a2 ;
18 : <packet> ( link id kind -- packet )
24 BUFSIZE 0 <array> >>a2 ;
26 : last-packet ( packet -- last )
27 dup link>> [ last-packet ] [ ] ?if ;
29 : append-to ( packet list -- packet )
31 [ tuck last-packet >>link drop ] when* ;
36 : I_HANDLERA 3 ; inline
37 : I_HANDLERB 4 ; inline
43 : K_WORK 1001 ; inline
50 : S_RUNPKT ( -- n ) { PKTBIT } flags ; inline
51 : S_WAIT ( -- n ) { WAITBIT } flags ; inline
52 : S_WAITPKT ( -- n ) { WAITBIT PKTBIT } flags ; inline
53 : S_HOLD ( -- n ) { HOLDBIT } flags ; inline
54 : S_HOLDPKT ( -- n ) { HOLDBIT PKTBIT } flags ; inline
55 : S_HOLDWAIT ( -- n ) { HOLDBIT WAITBIT } flags ; inline
56 : S_HOLDWAITPKT ( -- n ) { HOLDBIT WAITBIT PKTBIT } flags ; inline
58 : task-tab-size 10 ; inline
66 TUPLE: task link id pri wkq state ;
68 : new-task ( id pri wkq state class -- task )
76 dup dup id>> task-tab set-nth ; inline
78 GENERIC: fn ( packet task -- task )
80 : state-on ( task flag -- task )
81 '[ _ bitor ] change-state ; inline
83 : state-off ( task flag -- task )
84 '[ _ bitnot bitand ] change-state ; inline
86 : wait-task ( task -- task )
89 : hold ( task -- task )
90 hold-count 1+ to: hold-count
94 : highest-priority ( t1 t2 -- t1/t2 )
95 [ [ pri>> ] bi@ > ] most ;
97 : find-tcb ( i -- task )
98 task-tab nth [ "Bad task" throw ] unless* ;
100 : release ( task i -- task )
101 find-tcb HOLDBIT state-off highest-priority ;
103 :: qpkt ( task pkt -- task )
104 [let | t [ pkt id>> find-tcb ] |
106 qpkt-count 1+ to: qpkt-count
110 pkt t wkq>> append-to t (>>wkq)
114 t PKTBIT state-on drop
115 t task highest-priority
120 : schedule-waitpkt ( task -- task pkt )
122 2dup link>> >>wkq drop
123 2dup S_RUNPKT S_RUN ? >>state drop ; inline
125 : schedule-run ( task pkt -- task )
128 : schedule-wait ( task -- task )
131 : (schedule) ( task -- )
134 { S_WAITPKT [ schedule-waitpkt schedule-run (schedule) ] }
135 { S_RUN [ f schedule-run (schedule) ] }
136 { S_RUNPKT [ f schedule-run (schedule) ] }
137 { S_WAIT [ schedule-wait (schedule) ] }
138 { S_HOLD [ schedule-wait (schedule) ] }
139 { S_HOLDPKT [ schedule-wait (schedule) ] }
140 { S_HOLDWAIT [ schedule-wait (schedule) ] }
141 { S_HOLDWAITPKT [ schedule-wait (schedule) ] }
147 task-list (schedule) ;
150 TUPLE: device-task < task v1 ;
152 : <device-task> ( id pri wkq -- task )
153 dup S_WAITPKT S_WAIT ? device-task new-task ;
155 M:: device-task fn ( pkt task -- task )
159 [ [ f ] change-v1 swap qpkt ] if
160 ] [ pkt task (>>v1) task hold ] if ;
162 TUPLE: handler-task < task workpkts devpkts ;
164 : <handler-task> ( id pri wkq -- task )
165 dup S_WAITPKT S_WAIT ? handler-task new-task ;
167 M:: handler-task fn ( pkt task -- task )
169 task over kind>> K_WORK =
170 [ [ append-to ] change-workpkts ]
171 [ [ append-to ] change-devpkts ]
176 [let* | devpkt [ task devpkts>> ]
177 workpkt [ task workpkts>> ]
178 count [ workpkt a1>> ] |
180 workpkt link>> task (>>workpkts)
184 devpkt link>> task (>>devpkts)
185 count workpkt a2>> nth devpkt (>>a1)
186 count 1+ workpkt (>>a1)
193 ] [ task wait-task ] if ;
196 TUPLE: idle-task < task { v1 fixnum } { v2 fixnum } ;
198 : <idle-task> ( i a1 a2 -- task )
199 [ 0 f S_RUN idle-task new-task ] 2dip
200 [ >>v1 ] [ >>v2 ] bi* ;
202 M: idle-task fn ( pkt task -- task )
205 dup v2>> 0 = [ hold ] [
206 dup v1>> 1 bitand 0 = [
207 [ -1 shift ] change-v1
210 [ -1 shift HEX: d008 bitor ] change-v1
216 TUPLE: work-task < task { handler fixnum } { n fixnum } ;
218 : <work-task> ( id pri w -- work-task )
219 dup S_WAITPKT S_WAIT ? work-task new-task
223 M:: work-task fn ( pkt task -- task )
225 task [ I_HANDLERA = I_HANDLERB I_HANDLERA ? ] change-handler drop
226 task handler>> pkt (>>id)
229 task [ 1+ ] change-n drop
230 task n>> 26 > [ 1 task (>>n) ] when
231 task n>> 1 - CHAR: A + i pkt a2>> set-nth
234 ] [ task wait-task ] if ;
238 task-tab-size f <array> to: task-tab
244 I_IDLE 1 10000 <idle-task> drop
247 f 0 K_WORK <packet> 0 K_WORK <packet>
251 f I_DEVA K_DEV <packet>
252 I_DEVA K_DEV <packet>
253 I_DEVA K_DEV <packet>
257 f I_DEVB K_DEV <packet>
258 I_DEVB K_DEV <packet>
259 I_DEVB K_DEV <packet>
262 I_DEVA 4000 f <device-task> drop
263 I_DEVB 4000 f <device-task> drop ;
266 qpkt-count 23246 assert=
267 hold-count 9297 assert= ;