IFN 0,[
 8-Nov-83 03:21:39-EST,0003381;000000000001
Date: 8 Nov 1983 0321-EST
From: Phil Budne <"JSOL.BUDD%MIT-OZ@MIT-MC.ARPA" at DECWRL>
To: BUDNE at MRFORT
Subject: ph2.mid
Mailed to: decwrl!rhea!mrsvax!mrfort!budne@SU-SHASTA.ARPA

Received: from DECWRL by RHEA with SMTP; Mon,  7 Nov 83 23:20-PDT
Received: from mit-ml by Shasta with TCP; Mon Nov  7 20:49:26 1983
Received: by DECWRL (3.327/4.08) 8 Nov 83 00:20:24 PST (Tue)
Date: Mon 7 Nov 83 23:48:30-EST
Message-Id: <8311080820.AA15531@DECWRL>
] ;IFN 0
title phil - osophers
.decsave

st$nul==0
st$thk==1
st$eat==2
st$get==3

stnam:	[asciz ' * ']
	[asciz 'think']
	[asciz 'eat']
	[asciz ' - ']
maxn==5.

; register declarations (per philosopher local)
a==1
b==2
c==3
t==4
n==11				;number of philosophers
x==12				;call linkage register

right==14
left==15
me==16

call=jsp x,			;jump and save PC in x
ret=jrstf (x)			;restore PC + flags from x

define p. sem
	aose sem
	 jrst .-1
	movem me, sem!.
termin

define v. sem
	setom sem!.
	setom sem
termin

aobptr:	0			;aobjn for n
flag:	-1			;fork interlock semaphore
flag.:	-1			;owner

fl2:	-1			;state semaphore
fl2.:	-1			;owner

state:	block maxn

forks:
repeat maxn, 2

names:	[asciz 'one']
	[asciz 'two']
	[asciz 'three']
	[asciz 'four']
	[asciz 'five']
	[0]

start:	reset
	hrroi 1, [asciz 'How many philosophers ?']
	psout

	movei 1, .priin
	movei 3, 10.
	nin
	 erjmp start
	caige 2, 2		;less then 2 ?
	 jrst toofew
	caile 2, maxn		;more than max?
	 jrst toomany

	move n, 2
	move t, 2		;make temp copy
	movni t, (t)		;negate
	hrlz t, t		;-n,,0
	movem t, aobptr

slop:	movei me, (t)		;get number from right half
	call mkp		;create this philosopher
	aobjn t, slop		;loop for all philosophers

;;	wait			;forever...
	pbin
	setom run
	skipe nrun
	 jrst .-1
	haltf
	
toofew:	hrroi 1, [asciz ' try again']
	trna
toomany: hrroi 1, [asciz '... thats too many']
	psout
	hrroi 1, [.byte 7 ? ^m ? ^j]
	psout
	jrst start

	subttl make a philosopher..
mkp:	setzm state(me)
; init local vars
; called with me loaded; set up left & right
	move a, me		;ME
	addi a, -1(n)		;+N-1
	idiv a, n		;MOD N
	move left, b		;number of left neighbor

	movei a, 1(me)		;ME+1
	idiv a, n		;MOD N
	move right, b		;number of right neighbor

; give indirect copy of our pages, copy our acs, start @philosopher
	move a, [cr%map\cr%acs\cr%st\philosopher]
	movei b, 0
	cfork
	 erjmp .+2
	  aos nrun
	ret

philosopher:
	call getmyforks		;obtain forks
	call eat		;eat some
	call returnmyforks	;release forks
	call think		;think some
	skipn run		;keep running?
	 jrst philosopher	;yes, loop back
	sos nrun
	haltf

getmyforks:
	movei a, st$get
	movem a, state(me)
	p. flag
	move a, forks(me)
	caie a, 2
	 jrst wt
	sos forks(left)
	sos forks(right)
	v. flag
	ret

wt:	v. flag
	movei a, 10.
	disms
	jrst getmyforks

returnmyforks:
	p. flag
	movei a, 2
	movem a, forks(me)
	aos forks(left)
	aos forks(right)
	v. flag
	ret

think:	movei a, st$thk		;think state
	jrst common

eat:	movei a, st$eat		;eat state

common:
	movem a, state(me)
	p. fl2

	move t, aobptr
coml:	move a, state(t)
	hrro a, stnam(a)
	psout
	movei a, ^i
	pbout
	aobjn t, coml
	hrroi a, [.byte 7 ? ^m ? ^j ? 0]
	psout
	v. fl2

	movei a, 7.
	disms
	setzm state(me)
	ret

run:	0
nrun:	0

end start
