CSa32/Constellation.S
changeset 0 5c129dd80d4f
--- /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
+