|
0
|
1 |
.include "DS.S"
|
|
|
2 |
#-----------------------------------------------
|
|
|
3 |
# S T A T I C V A R I A B L E S
|
|
|
4 |
#-----------------------------------------------
|
|
|
5 |
.data
|
|
|
6 |
.global C.csP
|
|
|
7 |
C.csP: .int 0 # -->CS
|
|
|
8 |
.text
|
|
|
9 |
#-----------------------------------------------
|
|
|
10 |
# M A I N R O U T I N E
|
|
|
11 |
#-----------------------------------------------
|
|
|
12 |
# takes values from ENV, establishes task for comm nodes and waits for their completion
|
|
|
13 |
ARGS
|
|
|
14 |
DS prgP # -->progname
|
|
|
15 |
# returns nothing
|
|
|
16 |
PROLOC
|
|
|
17 |
DL this, CSL # CS - top level attr vector
|
|
|
18 |
DL deP # -->Debug
|
|
|
19 |
DL status # status returned from wait
|
|
|
20 |
DL pid # PID returned from wait
|
|
|
21 |
DL bad # cummulative subtask rc
|
|
|
22 |
DL s, 256 # string buf
|
|
|
23 |
EPILOC
|
|
|
24 |
#-----------------------------------------------
|
|
|
25 |
.global _start
|
|
|
26 |
_start:
|
|
|
27 |
PROLOG
|
|
|
28 |
lea this(bp), b # -->CS
|
|
|
29 |
mov b, C.csP # save -->CS
|
|
|
30 |
lea C.debug(b), a # -->Debug
|
|
|
31 |
mov a, deP(bp)
|
|
|
32 |
# initialize static debug vars
|
|
|
33 |
push prgP(bp) # argv[0] -->prgname
|
|
|
34 |
call D.init # initialize static debug vars
|
|
|
35 |
push D.prgNameP
|
|
|
36 |
# indetify itself
|
|
|
37 |
DEBID "client/server demo"
|
|
|
38 |
movl $1, C.debMaxLev(b) # default debug level
|
|
|
39 |
# initialize top level ctrl values vector
|
|
|
40 |
ShareA # allocate shared structure
|
|
|
41 |
mov C.csP, b
|
|
|
42 |
mov a, C.shP(b) # save -->shared struct in vector
|
|
|
43 |
movl $0, S.msgs(a) # init msg cntr
|
|
|
44 |
movl $0, S.conns(a) # init connection cntr
|
|
|
45 |
push $1 # initial semaphore value
|
|
|
46 |
push $1 # semaphore shared between processes
|
|
|
47 |
lea S.counter_sem(a), c
|
|
|
48 |
push c
|
|
|
49 |
# call sem_init # initialize shared counters semaphore
|
|
|
50 |
# cmp $0, a
|
|
|
51 |
# jz 0f
|
|
|
52 |
# SYSERR "sem_init of shared counters semaphore"
|
|
|
53 |
#0:
|
|
|
54 |
SYS sem_init
|
|
|
55 |
# set default values
|
|
|
56 |
mov C.csP, b
|
|
|
57 |
movl $3, C.ttl(b) # default TTL
|
|
|
58 |
movl $11000, C.rp0(b) # default bind port for the 1. node in ring
|
|
|
59 |
movl $12000, C.mp0(b) # default bind port for the 1. node in mash
|
|
|
60 |
movl $0, C.rn(b) # default # of nodes in ring
|
|
|
61 |
movl $0, C.mn(b) # default # of nodes in mash
|
|
|
62 |
movl $0, C.ssl(b) # default ssl switch - 0=noSSL
|
|
|
63 |
movl $77, C.connTh(b) # conn retries threshold
|
|
|
64 |
mov $0f, a
|
|
|
65 |
mov a, C.txtP(b) # default payload text
|
|
|
66 |
jmp 1f
|
|
|
67 |
0: .ascii "bla bla\0"
|
|
|
68 |
1:
|
|
|
69 |
# get control values from ENV
|
|
|
70 |
# get max debug level
|
|
|
71 |
GETINTENV "DEB"
|
|
|
72 |
mov C.csP, b
|
|
|
73 |
mov a, C.debMaxLev(b)
|
|
|
74 |
cmp $-1, a # debug level -1 means search subroutines
|
|
|
75 |
jne 0f
|
|
|
76 |
call D.subr
|
|
|
77 |
jmp C.ret
|
|
|
78 |
0:
|
|
|
79 |
# get message payload text
|
|
|
80 |
push $0f
|
|
|
81 |
call getenv
|
|
|
82 |
cmp $0, a
|
|
|
83 |
jz 1f
|
|
|
84 |
mov C.csP, b
|
|
|
85 |
mov a, C.txtP(b)
|
|
|
86 |
jmp 1f
|
|
|
87 |
0: .asciz "T"
|
|
|
88 |
1:
|
|
|
89 |
# get TTL
|
|
|
90 |
GETINTENV "TTL"
|
|
|
91 |
jz 0f
|
|
|
92 |
mov a, C.ttl(b)
|
|
|
93 |
0:
|
|
|
94 |
# get # of nodes in each topology
|
|
|
95 |
GETINTENV "I"
|
|
|
96 |
jz 0f
|
|
|
97 |
mov a, C.rn(b)
|
|
|
98 |
mov a, C.mn(b)
|
|
|
99 |
0:
|
|
|
100 |
# get # of nodes in ring
|
|
|
101 |
GETINTENV "RN"
|
|
|
102 |
jz 0f
|
|
|
103 |
mov a, C.rn(b)
|
|
|
104 |
0:
|
|
|
105 |
# get # of nodes in mash
|
|
|
106 |
GETINTENV "MN"
|
|
|
107 |
jz 0f
|
|
|
108 |
mov a, C.mn(b)
|
|
|
109 |
0:
|
|
|
110 |
add C.rn(b), a
|
|
|
111 |
cmp $3, C.ssl(b)
|
|
|
112 |
jne 1f
|
|
|
113 |
add a, a # double # of nodes when both SSL and nonSSL
|
|
|
114 |
1: mov C.shP(b), c # -->shared counters
|
|
|
115 |
mov a, S.act(c) # save # of active nodes
|
|
|
116 |
# get first ring node's bind port#
|
|
|
117 |
GETINTENV "RP0"
|
|
|
118 |
jz 0f
|
|
|
119 |
mov a, C.rp0(b)
|
|
|
120 |
0:
|
|
|
121 |
# get first mash node's bind port#
|
|
|
122 |
GETINTENV "MP0"
|
|
|
123 |
jz 0f
|
|
|
124 |
mov a, C.mp0(b)
|
|
|
125 |
0:
|
|
|
126 |
# get random() seed
|
|
|
127 |
GETINTENV "RS"
|
|
|
128 |
jz 0f
|
|
|
129 |
push a
|
|
|
130 |
call srandom
|
|
|
131 |
0:
|
|
|
132 |
# get pacing interval (real num in seconds)
|
|
|
133 |
movl $0, C.pace.tv_sec(b)
|
|
|
134 |
movl $0, C.pace.tv_nsec(b)
|
|
|
135 |
movl $0, C.pacing(b)
|
|
|
136 |
push $0f
|
|
|
137 |
call getenv
|
|
|
138 |
jmp 1f
|
|
|
139 |
0: .asciz "P"
|
|
|
140 |
1:
|
|
|
141 |
test a, a # env P set ?
|
|
|
142 |
jz 3f # no
|
|
|
143 |
push a
|
|
|
144 |
call atof # convert to double
|
|
|
145 |
fstl (sp) # tempor save
|
|
|
146 |
mov C.csP, b
|
|
|
147 |
fisttpl C.pace.tv_sec(b) # truncated integral part = secs
|
|
|
148 |
fldl (sp)
|
|
|
149 |
fisubl C.pace.tv_sec(b) # fraction part
|
|
|
150 |
fimull 1f # * 10^9 = nanosecs
|
|
|
151 |
fistl C.pace.tv_nsec(b)
|
|
|
152 |
jmp 2f
|
|
|
153 |
0: .double 0
|
|
|
154 |
1: .int 1000000000 # 10^9
|
|
|
155 |
2:
|
|
|
156 |
cmp $0, C.pace.tv_sec(b)
|
|
|
157 |
jnz 0f
|
|
|
158 |
cmp $0, C.pace.tv_nsec(b)
|
|
|
159 |
jz 3f
|
|
|
160 |
0: movl $1, C.pacing(b)
|
|
|
161 |
3:
|
|
|
162 |
# get ssl switch value and save it as mask
|
|
|
163 |
# switch: 0 = noSSL, 1 = SSL, 2 = both
|
|
|
164 |
# mask: 01B=noSSL, 10B=SSL, 11B=both
|
|
|
165 |
GETINTENV "SSL" # returned zero means SSL=0 or SSL by default 0
|
|
|
166 |
inc a # change switch to mask
|
|
|
167 |
mov a, C.ssl(b)
|
|
|
168 |
cmp $1, a
|
|
|
169 |
je C.cont # no SSL
|
|
|
170 |
cmp $2, a
|
|
|
171 |
je 0f # only SSL
|
|
|
172 |
mov C.shP(b), a # -->shared mem
|
|
|
173 |
shll $1, S.act(a) # double # of active nodes when running both SSL and nonSSL
|
|
|
174 |
# get SSL CA cert dir path
|
|
|
175 |
0:
|
|
|
176 |
push $0f
|
|
|
177 |
call getenv
|
|
|
178 |
jmp 1f
|
|
|
179 |
0: .asciz "CAP"
|
|
|
180 |
1:
|
|
|
181 |
test a, a
|
|
|
182 |
jnz 1f
|
|
|
183 |
mov $0f, a
|
|
|
184 |
jmp 1f
|
|
|
185 |
0: .asciz "/home/local/etc/ssl/certs/"
|
|
|
186 |
1:
|
|
|
187 |
mov C.csP, b
|
|
|
188 |
mov a, C.caPathP(b) # save -->SSL CA certs path
|
|
|
189 |
# get SSL dir path
|
|
|
190 |
push $0f
|
|
|
191 |
call getenv
|
|
|
192 |
jmp 1f
|
|
|
193 |
0: .asciz "CEP"
|
|
|
194 |
1:
|
|
|
195 |
test a, a
|
|
|
196 |
jz 0f # ceP not set, try to determine
|
|
|
197 |
mov C.csP, b
|
|
|
198 |
mov a, C.cePathP(b) # save -->SSL dir path
|
|
|
199 |
jmp 1f
|
|
|
200 |
# determine home path (needed to locate SSL keys & certificates)
|
|
|
201 |
0:
|
|
|
202 |
push prgP(bp) # -->first parm - progname w/ path
|
|
|
203 |
call dirname # get prog dirname
|
|
|
204 |
push a
|
|
|
205 |
call strlen # dirname length
|
|
|
206 |
lea 1f-0f(a), a # + suffix length
|
|
|
207 |
sub a, sp # allocate space for cePath
|
|
|
208 |
mov C.csP, b
|
|
|
209 |
mov sp, C.cePathP(b) # save -->SSL path
|
|
|
210 |
push prgP(bp)
|
|
|
211 |
call dirname # get home dirname
|
|
|
212 |
push a # -->home dirname
|
|
|
213 |
mov C.csP, b
|
|
|
214 |
push C.cePathP(b) # -->SSL path
|
|
|
215 |
call strcpy # copy dirname to SSL path
|
|
|
216 |
call strlen # end of dirname
|
|
|
217 |
push $0f # -->suffix
|
|
|
218 |
mov C.csP, b
|
|
|
219 |
mov C.cePathP(b), c
|
|
|
220 |
lea (c, a), a # -->end of dirname
|
|
|
221 |
push a
|
|
|
222 |
call strcpy # copy suffix to SSL path
|
|
|
223 |
jmp 1f
|
|
|
224 |
0: .asciz "/../CS/"
|
|
|
225 |
1:
|
|
|
226 |
# testing sandbox
|
|
|
227 |
mov C.csP, b
|
|
|
228 |
pushl C.debMaxLev(b)
|
|
|
229 |
cmp $9, C.debMaxLev(b)
|
|
|
230 |
jne C.cont
|
|
|
231 |
|
|
|
232 |
LOG 9, "debug=%u, testing...", 1
|
|
|
233 |
DebugA
|
|
|
234 |
mov a, deP(bp)
|
|
|
235 |
DEBID "TEST"
|
|
|
236 |
LOG 9, "progress"
|
|
|
237 |
|
|
|
238 |
mov C.csP, b
|
|
|
239 |
mov C.shP(b), a
|
|
|
240 |
push S.act(a)
|
|
|
241 |
LOG 9, "shared act=%u"
|
|
|
242 |
|
|
|
243 |
jmp C.ret
|
|
|
244 |
# normal execution
|
|
|
245 |
C.cont:
|
|
|
246 |
push C.debMaxLev(b)
|
|
|
247 |
push C.ssl(b)
|
|
|
248 |
push C.pace.tv_nsec(b)
|
|
|
249 |
push C.pace.tv_sec(b)
|
|
|
250 |
push C.ttl(b)
|
|
|
251 |
push C.rn(b)
|
|
|
252 |
push C.mn(b)
|
|
|
253 |
push D.prgNameP
|
|
|
254 |
LOG 1, "pgm=%s, mash nodes=%d, ring nodes=%d, ttl=%d, pacing=%ld.%09ld, SSL mask=0x%02x, debug=%u", 8
|
|
|
255 |
testl $2, C.ssl(b)
|
|
|
256 |
jz 0f
|
|
|
257 |
push C.caPathP(b)
|
|
|
258 |
push C.cePathP(b)
|
|
|
259 |
LOG 1, "SSL path=%s, SSL CA path=%s"
|
|
|
260 |
0:
|
|
|
261 |
# create constellation processes RING/MASH, nonSSL/SSL
|
|
|
262 |
mov $0, c # iter counter
|
|
|
263 |
mov C.ssl(b), d # SSL mask (01b = noSSL, 10b = SSL, 11b = both)
|
|
|
264 |
# iterate on SSL variants
|
|
|
265 |
C.iterateOnSsl:
|
|
|
266 |
test $1, d # check lowest bit of mask
|
|
|
267 |
jz C.nextSsslVar # next SSL variant
|
|
|
268 |
pusha
|
|
|
269 |
# create RING
|
|
|
270 |
SYS fork
|
|
|
271 |
jnz 1f # parent
|
|
|
272 |
popa
|
|
|
273 |
pushl $Cn.ring # RING topology
|
|
|
274 |
push c # use iter ctr as SSL switch
|
|
|
275 |
call Constellation # create RING constellation
|
|
|
276 |
1: push a
|
|
|
277 |
LOG 5, "RING started in process %d"
|
|
|
278 |
lea 4(sp), sp
|
|
|
279 |
# create MASH
|
|
|
280 |
SYS fork
|
|
|
281 |
jnz 1f # parent
|
|
|
282 |
popa
|
|
|
283 |
pushl $Cn.mash # MASH topology
|
|
|
284 |
push c # use iter ctr as SSL switch
|
|
|
285 |
call Constellation # create MASH constellation
|
|
|
286 |
1: push a
|
|
|
287 |
LOG 5, "MASH started in process %d"
|
|
|
288 |
lea 4(sp), sp
|
|
|
289 |
|
|
|
290 |
popa
|
|
|
291 |
C.nextSsslVar:
|
|
|
292 |
shr $1, d # shift to test next SSL bit
|
|
|
293 |
inc c # incr ctr
|
|
|
294 |
cmp $2, c
|
|
|
295 |
jl C.iterateOnSsl
|
|
|
296 |
# wait for constellation processes completion
|
|
|
297 |
LOG 5, "waiting for constellations to terminate"
|
|
|
298 |
movl $0, bad(bp) # clear cummulative rc
|
|
|
299 |
C.iterateOnWait:
|
|
|
300 |
lea status(bp), a
|
|
|
301 |
push a # -->return status of task
|
|
|
302 |
call wait
|
|
|
303 |
mov a, pid(bp) # save pid
|
|
|
304 |
cmp $-1, a # a task ended?
|
|
|
305 |
jne 0f # yes
|
|
|
306 |
call __errno_location
|
|
|
307 |
cmp $10, (a) # error == ECHILD ?
|
|
|
308 |
je C.ret # yes, no other subtasks
|
|
|
309 |
SYSERR "wait"
|
|
|
310 |
0:
|
|
|
311 |
# push status(bp) # status of task
|
|
|
312 |
# push a # pid
|
|
|
313 |
# LOG 5, "status returned from task %u: 0x%08x"
|
|
|
314 |
mov status(bp), d
|
|
|
315 |
test $0x7f, d
|
|
|
316 |
jnz 1f # task killed, ABEND
|
|
|
317 |
and $0xff00, d # task exited, extract rc
|
|
|
318 |
shr $8, d
|
|
|
319 |
or d, bad(bp) # accumulate rc
|
|
|
320 |
push d # task rc
|
|
|
321 |
push pid(bp) # task pid
|
|
|
322 |
LOG 5, "constellation task %u ended with exit(%d)"
|
|
|
323 |
jmp C.iterateOnWait # wait for other tasks
|
|
|
324 |
1: push d
|
|
|
325 |
push pid(bp)
|
|
|
326 |
LOG 5, "constellation task %u killed, status=0x%x", 2
|
|
|
327 |
2:
|
|
|
328 |
# ABEND
|
|
|
329 |
LOG 0, "ABEND, kill all tasks"
|
|
|
330 |
pushl $15 # SIGTERM
|
|
|
331 |
pushl $0 # all tasks
|
|
|
332 |
# call kill
|
|
|
333 |
SYS kill
|
|
|
334 |
pushl $1
|
|
|
335 |
call exit
|
|
|
336 |
# normal end
|
|
|
337 |
C.ret: movl C.csP, b # -->CS vector
|
|
|
338 |
movl C.shP(b), b # -->Share
|
|
|
339 |
pushl S.conns(b) # no. of connections made
|
|
|
340 |
pushl S.msgs(b) # no. of messages sent
|
|
|
341 |
LOG 1, "END, forwards=%d, connections=%d", 2
|
|
|
342 |
push bad(bp)
|
|
|
343 |
call exit
|
|
|
344 |
#-----------------------------------------------
|
|
|
345 |
# C O N S T E L L A T I O N O P E R A T I O N S
|
|
|
346 |
#-----------------------------------------------
|
|
|
347 |
ARGS
|
|
|
348 |
DS ssl # ssl switch
|
|
|
349 |
DS topo # topology
|
|
|
350 |
# returns: nothing
|
|
|
351 |
PROLOC
|
|
|
352 |
DL this, ConstellationL # this Constellation instance
|
|
|
353 |
DL thisP # -->this Constellation
|
|
|
354 |
DL deP # -->Debug
|
|
|
355 |
DL last # last node#
|
|
|
356 |
DL pid # pid returned from wait
|
|
|
357 |
DL stat # stat returned from wait
|
|
|
358 |
DL bad # "some node BAD" exit indicator
|
|
|
359 |
DL catched # count of returned node tasks
|
|
|
360 |
DL killed # count of killed node tasks
|
|
|
361 |
EPILOC
|
|
|
362 |
#-----------------------------------------------
|
|
|
363 |
.global Constellation
|
|
|
364 |
Constellation:
|
|
|
365 |
PROLOG
|
|
|
366 |
lea this(bp), b # -->this Constellation
|
|
|
367 |
mov b, thisP(bp) # save -->this Constellation
|
|
|
368 |
# set debid
|
|
|
369 |
lea Cn.debug(b), a # -->Debug
|
|
|
370 |
mov a, deP(bp) # save -->Debug locally
|
|
|
371 |
mov C.csP, c # -->CS
|
|
|
372 |
cmp $Cn.ring, topo(bp) # ring topology ?
|
|
|
373 |
je 0f
|
|
|
374 |
mov C.mn(c), a # num. of nodes
|
|
|
375 |
mov a, Cn.nodes(b)
|
|
|
376 |
mov C.mp0(c), a # port # of fist node
|
|
|
377 |
mov a, Cn.first(b)
|
|
|
378 |
movl $Cn.mash, Cn.topo(b)
|
|
|
379 |
push $8f
|
|
|
380 |
jmp 1f
|
|
|
381 |
0: mov C.rn(c), a # num. of nodes
|
|
|
382 |
mov a, Cn.nodes(b)
|
|
|
383 |
mov C.rp0(c), a # port # of fist node
|
|
|
384 |
mov a, Cn.first(b)
|
|
|
385 |
movl $Cn.ring, Cn.topo(b)
|
|
|
386 |
push $7f
|
|
|
387 |
1: cmp $0, ssl(bp) # SSL ?
|
|
|
388 |
jz 2f # no
|
|
|
389 |
movl $1, Cn.ssl(b)
|
|
|
390 |
addl $500, Cn.first(b) # first SSL port #
|
|
|
391 |
push $6f
|
|
|
392 |
jmp 9f
|
|
|
393 |
2: movl $0, Cn.ssl(b)
|
|
|
394 |
push $5f
|
|
|
395 |
jmp 9f
|
|
|
396 |
5: .ascii "non\0"
|
|
|
397 |
6: .ascii "\0"
|
|
|
398 |
7: .ascii "RING\0"
|
|
|
399 |
8: .ascii "MASH\0"
|
|
|
400 |
9: DEBID "%sSSL %s", 2
|
|
|
401 |
# check # of nodes
|
|
|
402 |
movL $0, bad(bp)
|
|
|
403 |
cmp $1, Cn.nodes(b) # num of nodes
|
|
|
404 |
jl Cn.ret # < 1 ? nothing to do
|
|
|
405 |
jg 0f
|
|
|
406 |
LOG 0, "1 node configuration not implemented yet"
|
|
|
407 |
jmp Cn.ret
|
|
|
408 |
0: LOG 5, "initializing..."
|
|
|
409 |
# determine divisor for random next node choise
|
|
|
410 |
mov $1, a
|
|
|
411 |
shl $31, a
|
|
|
412 |
not a # MAX_INT
|
|
|
413 |
xor d, d
|
|
|
414 |
divl Cn.nodes(b)
|
|
|
415 |
mov a, Cn.div(b) # save divisor (MAX_INT / nodes)
|
|
|
416 |
# allocate "forward" indicator shared by nodes in constellation
|
|
|
417 |
push $0
|
|
|
418 |
push $-1
|
|
|
419 |
push $0x21 # PROT_READ | PROT_WRITE
|
|
|
420 |
push $0x03 # MAP_SHARED | MAP_ANONYMOUS
|
|
|
421 |
push $4
|
|
|
422 |
push $0
|
|
|
423 |
# call mmap
|
|
|
424 |
# cmp $-1, a
|
|
|
425 |
# jne 0f
|
|
|
426 |
# SYSERR "mmap"
|
|
|
427 |
#0: mov thisP(bp), b
|
|
|
428 |
SYS mmap
|
|
|
429 |
mov a, Cn.forwP(b) # save -->forw
|
|
|
430 |
movl $1, (a) # enable forwarding
|
|
|
431 |
push Cn.nodes(b)
|
|
|
432 |
LOG 1, "%u nodes starting..."
|
|
|
433 |
# start processes for all nodes in constellation
|
|
|
434 |
mov Cn.first(b), d # first node#
|
|
|
435 |
mov d, c
|
|
|
436 |
add Cn.nodes(b), c # last node + 1
|
|
|
437 |
Cn.iterateOnFork:
|
|
|
438 |
pusha
|
|
|
439 |
# call fork
|
|
|
440 |
SYS fork
|
|
|
441 |
cmp $0, a
|
|
|
442 |
jnz 1f # parent
|
|
|
443 |
popa
|
|
|
444 |
push d # node's port#
|
|
|
445 |
push b # -->Cnstlln
|
|
|
446 |
call Node
|
|
|
447 |
1: mov a, pid(bp)
|
|
|
448 |
popa
|
|
|
449 |
push pid(bp) # nodes's pid
|
|
|
450 |
push d # node's port#
|
|
|
451 |
LOG 4, "node %u established in process %u", 2
|
|
|
452 |
inc d
|
|
|
453 |
cmp d, c # last node ?
|
|
|
454 |
jg Cn.iterateOnFork # no, continue forking
|
|
|
455 |
# wait for completion of node processes
|
|
|
456 |
LOG 2, "all nodes established, waiting for them to terminate..."
|
|
|
457 |
movl $0, bad(bp) # accumulated return status of node tasks
|
|
|
458 |
movl $0, killed(bp) # num. of killed node tasks
|
|
|
459 |
movl $0, catched(bp) # num. of returned node tasks
|
|
|
460 |
lea -12(sp), sp # prepare space for loop
|
|
|
461 |
Cn.iterateOnWait:
|
|
|
462 |
cmp $0, bad(bp) # constellation status still OK ?
|
|
|
463 |
je 1f # yes
|
|
|
464 |
mov Cn.forwP(b), a # -->forwarding switch
|
|
|
465 |
movl $0, (a) # disable forwarding between nodes
|
|
|
466 |
1:
|
|
|
467 |
lea stat(bp), c
|
|
|
468 |
mov c, (sp) # -->return status of task
|
|
|
469 |
call wait
|
|
|
470 |
mov thisP(bp), b
|
|
|
471 |
cmp $-1, a # normal return from wait?
|
|
|
472 |
jne 0f # yes
|
|
|
473 |
call __errno_location
|
|
|
474 |
cmp $10, (a) # error == ECHILD ?
|
|
|
475 |
je Cn.allFinished # yes, no subtasks
|
|
|
476 |
SYSERR "wait"
|
|
|
477 |
0:
|
|
|
478 |
incl catched(bp)
|
|
|
479 |
mov a, pid(bp) # save subtask's pid
|
|
|
480 |
mov a, (sp)
|
|
|
481 |
mov stat(bp), c # subtask return status
|
|
|
482 |
mov c, 4(sp)
|
|
|
483 |
test $0x7f, c # subtask ended by exit ?
|
|
|
484 |
jnz 2f # no, killed
|
|
|
485 |
and $0xff00, c # extract subtask rc
|
|
|
486 |
jz 1f # rc = 0
|
|
|
487 |
movl $1, bad(bp) # non zero rc, turn on BAD switch
|
|
|
488 |
1: shr $8, c
|
|
|
489 |
mov c, 4(sp) # rc
|
|
|
490 |
mov a, (sp) # pid
|
|
|
491 |
LOG 4, "node process %u ended by exit(%d)"
|
|
|
492 |
jmp Cn.iterateOnWait # continue waiting for other subtasks
|
|
|
493 |
2: movl $1, bad(bp) # subtask killed, turn on BAD switch
|
|
|
494 |
incl killed(bp) # counter of killed
|
|
|
495 |
mov c, 4(sp) # status
|
|
|
496 |
mov a, (sp) # pid
|
|
|
497 |
LOG 4, "node process %u killed, status=0x%x"
|
|
|
498 |
jmp Cn.iterateOnWait # continue waiting for other subtasks
|
|
|
499 |
|
|
|
500 |
# opers of all nodes finished
|
|
|
501 |
Cn.allFinished:
|
|
|
502 |
push killed(bp)
|
|
|
503 |
push catched(bp)
|
|
|
504 |
mov thisP(bp), b
|
|
|
505 |
push Cn.nodes(b)
|
|
|
506 |
cmp $0, bad(bp) # all nodes ended OK ?
|
|
|
507 |
je 0f # yes
|
|
|
508 |
push $7f
|
|
|
509 |
jmp 9f
|
|
|
510 |
0: push $8f
|
|
|
511 |
jmp 9f
|
|
|
512 |
7: .ascii "with ERROR\0"
|
|
|
513 |
8: .ascii "OK\0"
|
|
|
514 |
9: LOG 1, "ENDED %s, %u spawned, %u catched, %u killed"
|
|
|
515 |
Cn.ret:
|
|
|
516 |
push bad(bp)
|
|
|
517 |
call exit
|
|
|
518 |
#-----------------------------------------------
|
|
|
519 |
# G E T I N T V A L U E S F R O M E N V
|
|
|
520 |
#-----------------------------------------------
|
|
|
521 |
ARGS
|
|
|
522 |
DS key # -->env key string
|
|
|
523 |
# returns int value or 0 if not found
|
|
|
524 |
PROLOC
|
|
|
525 |
EPILOC
|
|
|
526 |
#-----------------------------------------------
|
|
|
527 |
C.getArg:
|
|
|
528 |
PROLOG
|
|
|
529 |
pushl key(bp) # -->env key string
|
|
|
530 |
call getenv # get value
|
|
|
531 |
test a, a
|
|
|
532 |
jz 0f # not found in ENV
|
|
|
533 |
push a
|
|
|
534 |
call atoi # convert to int
|
|
|
535 |
0:
|
|
|
536 |
EPILOG_R
|
|
|
537 |
#-----------------------------------------------
|
|
|
538 |
# A B N O R M A L E N D
|
|
|
539 |
#-----------------------------------------------
|
|
|
540 |
ARGS
|
|
|
541 |
DS deP # -->Debug
|
|
|
542 |
PROLOC
|
|
|
543 |
EPILOC
|
|
|
544 |
#-----------------------------------------------
|
|
|
545 |
.globl C.abend
|
|
|
546 |
C.abend:
|
|
|
547 |
PROLOG
|
|
|
548 |
LOG 0, "ABEND"
|
|
|
549 |
push $15 # SIGTERM
|
|
|
550 |
push $0 # kill all
|
|
|
551 |
# call kill
|
|
|
552 |
SYS kill
|
|
|
553 |
push $1
|
|
|
554 |
call exit
|
|
|
555 |
#-----------------------------------------------
|
|
|
556 |
.end
|