CSa32/CS.S
changeset 0 5c129dd80d4f
equal deleted inserted replaced
-1:000000000000 0:5c129dd80d4f
       
     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