.include "DS.S"
#-----------------------------------------------
# C O N S T E L L A T I O N O P E R A T I O N S
#-----------------------------------------------
ARGS
DS ssl # ssl switch
DS topo # topology
# returns: nothing
PROLOC
DL this, ConstellationL # this Constellation instance
DL thisP # -->this Constellation
DL deP # -->Debug
DL len
DL pid
DL stat
DL bad # "some node BAD" exit indicator
EPILOC
#-----------------------------------------------
.global Constellation
Constellation:
PROLOG
lea this(bp), b # -->this Constellation
mov b, thisP(bp) # save -->this Constellation
# lea this, b # -->this inst
# set debid
lea Cn.debug(b), a # -->Debug
mov a, deP(bp) # save -->Debug locally
mov C.csP, c # -->CS
cmp $Cn.ring, topo(bp) # ring topology ?
je 0f
mov C.mn(c), a # num. of nodes
mov a, Cn.nodes(b)
mov C.mp0(c), a # port # of fist node
mov a, Cn.first(b)
movl $Cn.mash, Cn.topo(b)
push $8f
jmp 1f
0: mov C.rn(c), a # num. of nodes
mov a, Cn.nodes(b)
mov C.rp0(c), a # port # of fist node
mov a, Cn.first(b)
movl $Cn.ring, Cn.topo(b)
push $7f
1: cmp $0, ssl(bp) # SSL ?
jz 2f # no
movl $1, Cn.ssl(b)
addl $500, Cn.first(b) # first SSL port #
push $6f
jmp 9f
2: movl $0, Cn.ssl(b)
push $5f
jmp 9f
5: .ascii "non\0"
6: .ascii "\0"
7: .ascii "RING\0"
8: .ascii "MASH\0"
9: DEBID "%sSSL %s", 2
# check # of nodes
movL $0, bad(bp)
cmp $1, Cn.nodes(b) # num of nodes
jl ConstellationR # < 1 ? nothing to do
jg 0f
LOG 0, "1 node configuration not implemented yet"
jmp ConstellationR
0: LOG 5, "initializing..."
# determine divisor for random next node choise
mov $1, a
shl $31, a
not a # MAX_INT
xor d, d
divl Cn.nodes(b)
mov a, Cn.div(b) # save divisor (MAX_INT / nodes)
# allocate "forward" indicator shared by nodes in constellation
push $0
push $-1
push $0x21 # PROT_READ | PROT_WRITE
push $0x03 # MAP_SHARED | MAP_ANONYMOUS
push $4
push $0
call mmap
cmp $-1, a
jne 0f
SYSERR "mmap"
0: mov thisP(bp), b
mov a, Cn.forwP(b) # save -->forw
movl $1, (a) # enable forwarding
mov C.csP, c # -->CS
push C.ttl(c)
push Cn.nodes(b)
LOG 1, "%d node(s), ttl=%d starting..."
# start processes for all nodes in constellation
mov Cn.first(b), d # first node#
mov d, c
add Cn.nodes(b), c # last node + 1
0: pusha
call fork
cmp $0, a
jnz 1f # parent
popa
push d # node's port#
push b # -->Cnstlln
call Node
1: mov a, pid(bp)
popa
push pid(bp) # nodes's pid
push d # node's port#
LOG 3, "node %u established in process %u", 2
inc d
cmp d, c # last node ?
jg 0b # no, continue forking
# wait for completion of node processes
LOG 5, "all nodes established, waiting for them to terminate..."
movl $0, bad(bp)
0: lea stat(bp), a
cmp $0, bad(bp) # status still OK ?
je 1f # yes
mov Cn.forwP(b), a # -->forward switch
movl $0, (a) # disable forwarding
1: mov a, (sp) # -->return status of task
call wait
mov thisP(bp), b
cmp $0, a # normal return from wait?
jl 3f # no, all subtasks finshed
mov a, pid(bp) # save subtask's pid
mov stat(bp), a
test $0x7f, a # subtask ended by exit ?
jnz 2f # no, killed
and $0xff00, a # extract subtask rc
jz 1f # rc = 0
movl $1, bad(bp) # non zero rc, turn on BAD switch
1: push a # rc
push pid(bp) # pid
LOG 4, "node process %u ended with exit(%d)"
jmp 0b # continue waiting for other subtasks
2: movl $1, bad(bp) # subtask killed, turn on BAD switch
push pid(bp)
LOG 4, "node process %u killed"
jmp 0b # continue waiting for other subtasks
# opers of all nodes finished
3: cmp $0, bad(bp) # all nodes ended OK ?
je 0f # yes
push $7f
jmp 9f
0: push $8f
jmp 9f
7: .ascii "with ERROR\0"
8: .ascii "OK\0"
9: LOG 1, "ENDED %s"
ConstellationR:
push bad(bp)
call exit
#-----------------------------------------------
.end