--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CSa32/Constellation.S Thu Nov 21 14:55:10 2019 +0100
@@ -0,0 +1,155 @@
+ .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
+