%!
%%BoundingBox: (atend)
%%Pages: (atend)
%%DocumentFonts: (atend)
%%EndComments
%
% FrameMaker PostScript Prolog 3.0, for use with FrameMaker 3.0
% Copyright (c) 1986,87,89,90,91 by Frame Technology Corporation.
% All rights reserved.
%
% Known Problems:
% Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1
/FMversion (3.0) def
% Set up Color vs. Black-and-White
/FMPrintInColor systemdict /colorimage known
systemdict /currentcolortransfer known or def
% Uncomment this line to force b&w on color printer
% /FMPrintInColor false def
/FrameDict 295 dict def
systemdict /errordict known not {/errordict 10 dict def
errordict /rangecheck {stop} put} if
% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
FrameDict /tmprangecheck errordict /rangecheck get put
errordict /rangecheck {FrameDict /bug true put} put
FrameDict /bug false put
mark
% Some PS machines read past the CR, so keep the following 3 lines together!
currentfile 5 string readline
00
0000000000
cleartomark
errordict /rangecheck FrameDict /tmprangecheck get put
FrameDict /bug get {
/readline {
/gstring exch def
/gfile exch def
/gindex 0 def
{
gfile read pop
dup 10 eq {exit} if
dup 13 eq {exit} if
gstring exch gindex exch put
/gindex gindex 1 add def
} loop
pop
gstring 0 gindex getinterval true
} def
} if
/FMVERSION {
FMversion ne {
/Times-Roman findfont 18 scalefont setfont
100 100 moveto
(FrameMaker version does not match postscript_prolog!)
dup =
show showpage
} if
} def
/FMLOCAL {
FrameDict begin
0 def
end
} def
/gstring FMLOCAL
/gfile FMLOCAL
/gindex FMLOCAL
/orgxfer FMLOCAL
/orgproc FMLOCAL
/organgle FMLOCAL
/orgfreq FMLOCAL
/yscale FMLOCAL
/xscale FMLOCAL
/manualfeed FMLOCAL
/paperheight FMLOCAL
/paperwidth FMLOCAL
/FMDOCUMENT {
array /FMfonts exch def
/#copies exch def
FrameDict begin
0 ne dup {setmanualfeed} if
/manualfeed exch def
/paperheight exch def
/paperwidth exch def
/yscale exch def
/xscale exch def
currenttransfer cvlit /orgxfer exch def
currentscreen cvlit /orgproc exch def
/organgle exch def /orgfreq exch def
setpapername
manualfeed {true} {papersize} ifelse
{manualpapersize} {false} ifelse
{desperatepapersize} if
end
} def
/pagesave FMLOCAL
/orgmatrix FMLOCAL
/landscape FMLOCAL
/FMBEGINPAGE {
FrameDict begin
/pagesave save def
3.86 setmiterlimit
/landscape exch 0 ne def
landscape {
90 rotate 0 exch neg translate pop
}
{pop pop}
ifelse
xscale yscale scale
/orgmatrix matrix def
gsave
} def
/FMENDPAGE {
grestore
pagesave restore
end
showpage
} def
/FMFONTDEFINE {
FrameDict begin
findfont
ReEncode
1 index exch
definefont
FMfonts 3 1 roll
put
end
} def
/FMFILLS {
FrameDict begin
array /fillvals exch def
end
} def
/FMFILL {
FrameDict begin
fillvals 3 1 roll put
end
} def
/FMNORMALIZEGRAPHICS {
newpath
0.0 0.0 moveto
1 setlinewidth
0 setlinecap
0 0 0 sethsbcolor
0 setgray
} bind def
/fx FMLOCAL
/fy FMLOCAL
/fh FMLOCAL
/fw FMLOCAL
/llx FMLOCAL
/lly FMLOCAL
/urx FMLOCAL
/ury FMLOCAL
/FMBEGINEPSF {
end
/FMEPSF save def
/showpage {} def
FMNORMALIZEGRAPHICS
[/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall
fx fy translate
rotate
fw urx llx sub div fh ury lly sub div scale
llx neg lly neg translate
} bind def
/FMENDEPSF {
FMEPSF restore
FrameDict begin
} bind def
FrameDict begin
/setmanualfeed {
%%BeginFeature *ManualFeed True
statusdict /manualfeed true put
%%EndFeature
} def
/max {2 copy lt {exch} if pop} bind def
/min {2 copy gt {exch} if pop} bind def
/inch {72 mul} def
/pagedimen {
paperheight sub abs 16 lt exch
paperwidth sub abs 16 lt and
{/papername exch def} {pop} ifelse
} def
/papersizedict FMLOCAL
/setpapername {
/papersizedict 14 dict def
papersizedict begin
/papername /unknown def
/Letter 8.5 inch 11.0 inch pagedimen
/LetterSmall 7.68 inch 10.16 inch pagedimen
/Tabloid 11.0 inch 17.0 inch pagedimen
/Ledger 17.0 inch 11.0 inch pagedimen
/Legal 8.5 inch 14.0 inch pagedimen
/Statement 5.5 inch 8.5 inch pagedimen
/Executive 7.5 inch 10.0 inch pagedimen
/A3 11.69 inch 16.5 inch pagedimen
/A4 8.26 inch 11.69 inch pagedimen
/A4Small 7.47 inch 10.85 inch pagedimen
/B4 10.125 inch 14.33 inch pagedimen
/B5 7.16 inch 10.125 inch pagedimen
end
} def
/papersize {
papersizedict begin
/Letter {lettertray letter} def
/LetterSmall {lettertray lettersmall} def
/Tabloid {11x17tray 11x17} def
/Ledger {ledgertray ledger} def
/Legal {legaltray legal} def
/Statement {statementtray statement} def
/Executive {executivetray executive} def
/A3 {a3tray a3} def
/A4 {a4tray a4} def
/A4Small {a4tray a4small} def
/B4 {b4tray b4} def
/B5 {b5tray b5} def
/unknown {unknown} def
papersizedict dup papername known {papername} {/unknown} ifelse get
end
/FMdicttop countdictstack 1 add def
statusdict begin stopped end
countdictstack -1 FMdicttop {pop end} for
} def
/manualpapersize {
papersizedict begin
/Letter {letter} def
/LetterSmall {lettersmall} def
/Tabloid {11x17} def
/Ledger {ledger} def
/Legal {legal} def
/Statement {statement} def
/Executive {executive} def
/A3 {a3} def
/A4 {a4} def
/A4Small {a4small} def
/B4 {b4} def
/B5 {b5} def
/unknown {unknown} def
papersizedict dup papername known {papername} {/unknown} ifelse get
end
stopped
} def
/desperatepapersize {
statusdict /setpageparams known
{
paperwidth paperheight 0 1
statusdict begin
{setpageparams} stopped pop
end
} if
} def
/savematrix {
orgmatrix currentmatrix pop
} bind def
/restorematrix {
orgmatrix setmatrix
} bind def
/dmatrix matrix def
/dpi 72 0 dmatrix defaultmatrix dtransform
dup mul exch dup mul add sqrt def
/freq dpi 18.75 div 8 div round dup 0 eq {pop 1} if 8 mul dpi exch div def
/sangle 1 0 dmatrix defaultmatrix dtransform exch atan def
/DiacriticEncoding [
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl
/numbersign /dollar /percent /ampersand /quotesingle /parenleft
/parenright /asterisk /plus /comma /hyphen /period /slash /zero /one
/two /three /four /five /six /seven /eight /nine /colon /semicolon
/less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K
/L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash
/bracketright /asciicircum /underscore /grave /a /b /c /d /e /f /g /h
/i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar
/braceright /asciitilde /.notdef /Adieresis /Aring /Ccedilla /Eacute
/Ntilde /Odieresis /Udieresis /aacute /agrave /acircumflex /adieresis
/atilde /aring /ccedilla /eacute /egrave /ecircumflex /edieresis
/iacute /igrave /icircumflex /idieresis /ntilde /oacute /ograve
/ocircumflex /odieresis /otilde /uacute /ugrave /ucircumflex
/udieresis /dagger /.notdef /cent /sterling /section /bullet
/paragraph /germandbls /registered /copyright /trademark /acute
/dieresis /.notdef /AE /Oslash /.notdef /.notdef /.notdef /.notdef
/yen /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/ordfeminine /ordmasculine /.notdef /ae /oslash /questiondown
/exclamdown /logicalnot /.notdef /florin /.notdef /.notdef
/guillemotleft /guillemotright /ellipsis /.notdef /Agrave /Atilde
/Otilde /OE /oe /endash /emdash /quotedblleft /quotedblright
/quoteleft /quoteright /.notdef /.notdef /ydieresis /Ydieresis
/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
/periodcentered /quotesinglbase /quotedblbase /perthousand
/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
] def
/ReEncode {
dup
length
dict begin
{
1 index /FID ne
{def}
{pop pop} ifelse
} forall
0 eq {/Encoding DiacriticEncoding def} if
currentdict
end
} bind def
/graymode true def
/bwidth FMLOCAL
/bpside FMLOCAL
/bstring FMLOCAL
/onbits FMLOCAL
/offbits FMLOCAL
/xindex FMLOCAL
/yindex FMLOCAL
/x FMLOCAL
/y FMLOCAL
/setpattern {
/bwidth exch def
/bpside exch def
/bstring exch def
/onbits 0 def /offbits 0 def
freq sangle landscape {90 add} if
{/y exch def
/x exch def
/xindex x 1 add 2 div bpside mul cvi def
/yindex y 1 add 2 div bpside mul cvi def
bstring yindex bwidth mul xindex 8 idiv add get
1 7 xindex 8 mod sub bitshift and 0 ne
{/onbits onbits 1 add def 1}
{/offbits offbits 1 add def 0}
ifelse
}
setscreen
{} settransfer
offbits offbits onbits add div FMsetgray
/graymode false def
} bind def
/grayness {
FMsetgray
graymode not {
/graymode true def
orgxfer cvx settransfer
orgfreq organgle orgproc cvx setscreen
} if
} bind def
/HUE FMLOCAL
/SAT FMLOCAL
/BRIGHT FMLOCAL
/Colors FMLOCAL
FMPrintInColor
{
/HUE 0 def
/SAT 0 def
/BRIGHT 0 def
% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
/Colors
[[0 0 ] % black
[0 0 ] % white
[0.00 1.0] % red
[0.37 1.0] % green
[0.60 1.0] % blue
[0.50 1.0] % cyan
[0.83 1.0] % magenta
[0.16 1.0] % comment / yellow
] def
/BEGINBITMAPCOLOR {
BITMAPCOLOR} def
/BEGINBITMAPCOLORc {
BITMAPCOLORc} def
/BEGINBITMAPTRUECOLOR {
BITMAPTRUECOLOR } def
/BEGINBITMAPTRUECOLORc {
BITMAPTRUECOLORc } def
/K {
Colors exch get dup
0 get /HUE exch store
1 get /BRIGHT exch store
HUE 0 eq BRIGHT 0 eq and
{1.0 SAT sub setgray}
{HUE SAT BRIGHT sethsbcolor}
ifelse
} def
/FMsetgray {
/SAT exch 1.0 exch sub store
HUE 0 eq BRIGHT 0 eq and
{1.0 SAT sub setgray}
{HUE SAT BRIGHT sethsbcolor}
ifelse
} bind def
}
{
/BEGINBITMAPCOLOR {
BITMAPGRAY} def
/BEGINBITMAPCOLORc {
BITMAPGRAYc} def
/BEGINBITMAPTRUECOLOR {
BITMAPTRUEGRAY } def
/BEGINBITMAPTRUECOLORc {
BITMAPTRUEGRAYc } def
/FMsetgray {setgray} bind def
/K {
pop
} def
}
ifelse
/normalize {
transform round exch round exch itransform
} bind def
/dnormalize {
dtransform round exch round exch idtransform
} bind def
/lnormalize {
0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
} bind def
/H {
lnormalize setlinewidth
} bind def
/Z {
setlinecap
} bind def
/fillvals FMLOCAL
/X {
fillvals exch get
dup type /stringtype eq
{8 1 setpattern}
{grayness}
ifelse
} bind def
/V {
gsave eofill grestore
} bind def
/N {
stroke
} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
/n FMLOCAL
/L {
/n exch def
newpath
normalize
moveto
2 1 n {pop normalize lineto} for
} bind def
/Y {
L
closepath
} bind def
/x1 FMLOCAL
/x2 FMLOCAL
/y1 FMLOCAL
/y2 FMLOCAL
/rad FMLOCAL
/R {
/y2 exch def
/x2 exch def
/y1 exch def
/x1 exch def
x1 y1
x2 y1
x2 y2
x1 y2
4 Y
} bind def
% The following commented out code did not work for tangent lines of zero
% length. The code following it was provided by Frame to patch this error.
%
%/RR {
% /rad exch def
% normalize
% /y2 exch def
% /x2 exch def
% normalize
% /y1 exch def
% /x1 exch def
% newpath
% x1 y1 rad add moveto
% x1 y2 x2 y2 rad arcto
% x2 y2 x2 y1 rad arcto
% x2 y1 x1 y1 rad arcto
% x1 y1 x1 y2 rad arcto
% closepath
% 16 {pop} repeat
% } bind def
/rarc
{rad
{arcto} stopped
} bind def
/RR {
/rad exch def
normalize
/y2 exch def
/x2 exch def
normalize
/y1 exch def
/x1 exch def
mark
newpath
x1 y1 rad add moveto
x1 y2 x2 y2 rarc
x2 y2 x2 y1 rarc
x2 y1 x1 y1 rarc
% x2 y1 x1 y1 rarc
x1 y1 x1 y2 rarc
closepath
cleartomark
} bind def
/C {
grestore
gsave
R
clip
} bind def
/FMpointsize FMLOCAL
/F {
FMfonts exch get
FMpointsize scalefont
setfont
} bind def
/Q {
/FMpointsize exch def
F
} bind def
/T {
moveto show
} bind def
/RF {
rotate
0 ne {-1 1 scale} if
} bind def
/TF {
gsave
moveto
RF
show
grestore
} bind def
/P {
moveto
0 32 3 2 roll widthshow
} bind def
/PF {
gsave
moveto
RF
0 32 3 2 roll widthshow
grestore
} bind def
/S {
moveto
0 exch ashow
} bind def
/SF {
gsave
moveto
RF
0 exch ashow
grestore
} bind def
/B {
moveto
0 32 4 2 roll 0 exch awidthshow
} bind def
/BF {
gsave
moveto
RF
0 32 4 2 roll 0 exch awidthshow
grestore
} bind def
/G {
gsave
newpath
normalize translate 0.0 0.0 moveto
dnormalize scale
0.0 0.0 1.0 5 3 roll arc
closepath fill
grestore
} bind def
/A {
gsave
savematrix
newpath
2 index 2 div add exch 3 index 2 div sub exch
normalize 2 index 2 div sub exch 3 index 2 div add exch
translate
scale
0.0 0.0 1.0 5 3 roll arc
restorematrix
stroke
grestore
} bind def
/x FMLOCAL
/y FMLOCAL
/w FMLOCAL
/h FMLOCAL
/xx FMLOCAL
/yy FMLOCAL
/ww FMLOCAL
/hh FMLOCAL
/FMsaveobject FMLOCAL
/FMoptop FMLOCAL
/FMdicttop FMLOCAL
/BEGINPRINTCODE {
/FMdicttop countdictstack 1 add def
/FMoptop count 4 sub def
/FMsaveobject save def
userdict begin
/showpage {} def
FMNORMALIZEGRAPHICS
3 index neg 3 index neg translate
} bind def
/ENDPRINTCODE {
count -1 FMoptop {pop pop} for
countdictstack -1 FMdicttop {pop end} for
FMsaveobject restore
} bind def
/gn {
0
{ 46 mul
cf read pop
32 sub
dup 46 lt {exit} if
46 sub add
} loop
add
} bind def
/str FMLOCAL
/cfs {
/str sl string def
0 1 sl 1 sub {str exch val put} for
str def
} bind def
/ic [
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
0
{0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
{10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
{19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
{13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}
{4 wh} {5 wh} {6 wh} {7 wh} {8 wh} {9 wh} {10 wh} {11 wh} {12 wh}
{13 wh} {14 wh} {gn wh} {0 bl} {1 bl} {2 bl} {3 bl} {4 bl} {5 bl} {6 bl}
{7 bl} {8 bl} {9 bl} {10 bl} {11 bl} {12 bl} {13 bl} {14 bl} {gn bl}
{0 fl} {1 fl} {2 fl} {3 fl} {4 fl} {5 fl} {6 fl} {7 fl} {8 fl} {9 fl}
{10 fl} {11 fl} {12 fl} {13 fl} {14 fl} {gn fl}
] def
/sl FMLOCAL
/val FMLOCAL
/ws FMLOCAL
/im FMLOCAL
/bs FMLOCAL
/cs FMLOCAL
/len FMLOCAL
/pos FMLOCAL
/ms {
/sl exch def
/val 255 def
/ws cfs
/im cfs
/val 0 def
/bs cfs
/cs cfs
} bind def
400 ms
/cip {
is
0
cf cs readline pop
{ ic exch get exec
add
} forall
pop
/tot w 1 sub def
0 1 tot {
/indx exch def
/indxa is indx get def
/placer nredt indxa get def
/placeg ngreent indxa get def
/placeb nbluet indxa get def
cris indx placer 255 mul cvi put
cgis indx placeg 255 mul cvi put
cbis indx placeb 255 mul cvi put
} for pop cris
} bind def
/ip {
is
0
cf cs readline pop
{ ic exch get exec
add
} forall
pop
} bind def
/wh {
/len exch def
/pos exch def
ws 0 len getinterval im pos len getinterval copy pop
pos len
} bind def
/bl {
/len exch def
/pos exch def
bs 0 len getinterval im pos len getinterval copy pop
pos len
} bind def
/s1 1 string def
/fl {
/len exch def
/pos exch def
/val cf s1 readhexstring pop 0 get def
pos 1 pos len add 1 sub {im exch val put} for
pos len
} bind def
/hx {
3 copy getinterval
cf exch readhexstring pop pop
} bind def
/h FMLOCAL
/w FMLOCAL
/d FMLOCAL
/lb FMLOCAL
/bitmapsave FMLOCAL
/is FMLOCAL
/cf FMLOCAL
/wbytes {
dup
8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
} bind def
/BEGINBITMAPBWc {
1 {} COMMONBITMAPc
} bind def
/BEGINBITMAPGRAYc {
8 {} COMMONBITMAPc
} bind def
/BEGINBITMAP2BITc {
2 {} COMMONBITMAPc
} bind def
/COMMONBITMAPc {
/r exch def
/d exch def
gsave
translate rotate scale /h exch def /w exch def
/lb w d wbytes def
sl lb lt {lb ms} if
/bitmapsave save def
r
/is im 0 lb getinterval def
ws 0 lb getinterval is copy pop
/cf currentfile def
w h d [w 0 0 h neg 0 h]
{ip} image
bitmapsave restore
grestore
} bind def
/BEGINBITMAPBW {
1 {} COMMONBITMAP
} bind def
/BEGINBITMAPGRAY {
8 {} COMMONBITMAP
} bind def
/BEGINBITMAP2BIT {
2 {} COMMONBITMAP
} bind def
/COMMONBITMAP {
/r exch def
/d exch def
gsave
translate rotate scale /h exch def /w exch def
/bitmapsave save def
r
/is w d wbytes string def
/cf currentfile def
w h d [w 0 0 h neg 0 h]
{cf is readhexstring pop} image
bitmapsave restore
grestore
} bind def
/proc1 FMLOCAL
/proc2 FMLOCAL
/newproc FMLOCAL
/Fmcc {
/proc2 exch cvlit def
/proc1 exch cvlit def
/newproc proc1 length proc2 length add array def
newproc 0 proc1 putinterval
newproc proc1 length proc2 putinterval
newproc cvx
} bind def
/ngrayt 256 array def
/nredt 256 array def
/nbluet 256 array def
/ngreent 256 array def
/gryt FMLOCAL
/blut FMLOCAL
/grnt FMLOCAL
/redt FMLOCAL
/indx FMLOCAL
/cynu FMLOCAL
/magu FMLOCAL
/yelu FMLOCAL
/k FMLOCAL
/u FMLOCAL
/colorsetup {
currentcolortransfer
/gryt exch def
/blut exch def
/grnt exch def
/redt exch def
0 1 255 {
/indx exch def
/cynu 1 red indx get 255 div sub def
/magu 1 green indx get 255 div sub def
/yelu 1 blue indx get 255 div sub def
/k cynu magu min yelu min def
nredt indx 1 0 cynu max sub redt exec put
ngreent indx 1 0 magu max sub grnt exec put
nbluet indx 1 0 yelu max sub blut exec put
ngrayt indx 1 k sub gryt exec put
} for
} bind def
/tran FMLOCAL
/fakecolorsetup {
/tran 256 string def
0 1 255 {/indx exch def
tran indx
red indx get 77 mul
green indx get 151 mul
blue indx get 28 mul
add add 256 idiv put} for
currenttransfer
{255 mul cvi tran exch get 255.0 div}
exch Fmcc settransfer
} bind def
/BITMAPCOLOR {
/d 8 def
gsave
translate rotate scale /h exch def /w exch def
/bitmapsave save def
colorsetup
/is w d wbytes string def
/ris w d wbytes string def
/gis w d wbytes string def
/bis w d wbytes string def
/cf currentfile def
w h d [w 0 0 h neg 0 h]
{cf is readhexstring pop
/tot w 1 sub def
0 1 tot {
/indx exch def
/indxa is indx get def
/placer nredt indxa get def
/placeg ngreent indxa get def
/placeb nbluet indxa get def
ris indx placer 255 mul cvi put
gis indx placeg 255 mul cvi put
bis indx placeb 255 mul cvi put
} for pop ris}
{gis} {bis} true 3 colorimage
bitmapsave restore
grestore
} bind def
/BITMAPCOLORc {
/d 8 def
gsave
translate rotate scale /h exch def /w exch def
/lb w d wbytes def
sl lb lt {lb ms} if
/bitmapsave save def
colorsetup
/is im 0 lb getinterval def
/cris lb string def
/cgis lb string def
/cbis lb string def
ws 0 lb getinterval is copy pop
/cf currentfile def
w h d [w 0 0 h neg 0 h]
{cip} {cgis} {cbis} true 3 colorimage
bitmapsave restore
grestore
} bind def
/BITMAPTRUECOLORc {
gsave
translate rotate scale /h exch def /w exch def
/bitmapsave save def
/is w string def
ws 0 w getinterval is copy pop
/cf currentfile def
w h 8 [w 0 0 h neg 0 h]
{ip} {gip} {bip} true 3 colorimage
bitmapsave restore
grestore
} bind def
/BITMAPTRUECOLOR {
gsave
translate rotate scale /h exch def /w exch def
/bitmapsave save def
/is w string def
/gis w string def
/bis w string def
/cf currentfile def
w h 8 [w 0 0 h neg 0 h]
{ cf is readhexstring pop }
{ cf gis readhexstring pop }
{ cf bis readhexstring pop }
true 3 colorimage
bitmapsave restore
grestore
} bind def
/BITMAPTRUEGRAYc {
gsave
translate rotate scale /h exch def /w exch def
/bitmapsave save def
/is w string def
ws 0 w getinterval is copy pop
/cf currentfile def
w h 8 [w 0 0 h neg 0 h]
{ip gip bip w gray} image
bitmapsave restore
grestore
} bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray {
/ww exch def
/b exch def
/g exch def
/r exch def
0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
b i get .114 mul add add r i 3 -1 roll floor cvi put } for
r
} bind def
/BITMAPTRUEGRAY {
gsave
translate rotate scale /h exch def /w exch def
/bitmapsave save def
/is w string def
/gis w string def
/bis w string def
/cf currentfile def
w h 8 [w 0 0 h neg 0 h]
{ cf is readhexstring pop
cf gis readhexstring pop
cf bis readhexstring pop w gray} image
bitmapsave restore
grestore
} bind def
/BITMAPGRAY {
8 {fakecolorsetup} COMMONBITMAP
} bind def
/BITMAPGRAYc {
8 {fakecolorsetup} COMMONBITMAPc
} bind def
/ENDBITMAP {
} bind def
end
/ALDsave FMLOCAL
/ALDmatrix matrix def ALDmatrix currentmatrix pop
/StartALD {
/ALDsave save def
savematrix
ALDmatrix setmatrix
} bind def
/InALD {
restorematrix
} bind def
/DoneALD {
ALDsave restore
} bind def
%%EndProlog
%%BeginSetup
(3.0) FMVERSION
1 1 612 792 0 1 7 FMDOCUMENT
0 0 /Palatino-Roman FMFONTDEFINE
1 0 /Times-Roman FMFONTDEFINE
2 0 /Times-Bold FMFONTDEFINE
3 0 /Courier-Bold FMFONTDEFINE
32 FMFILLS
0 0 FMFILL
1 0.1 FMFILL
2 0.3 FMFILL
3 0.5 FMFILL
4 0.7 FMFILL
5 0.9 FMFILL
6 0.97 FMFILL
7 1 FMFILL
8 <0f1e3c78f0e1c387> FMFILL
9 <0f87c3e1f0783c1e> FMFILL
10 <cccccccccccccccc> FMFILL
11 <ffff0000ffff0000> FMFILL
12 <8142241818244281> FMFILL
13 <03060c183060c081> FMFILL
14 <8040201008040201> FMFILL
16 1 FMFILL
17 0.9 FMFILL
18 0.7 FMFILL
19 0.5 FMFILL
20 0.3 FMFILL
21 0.1 FMFILL
22 0.03 FMFILL
23 0 FMFILL
24 <f0e1c3870f1e3c78> FMFILL
25 <f0783c1e0f87c3e1> FMFILL
26 <3333333333333333> FMFILL
27 <0000ffff0000ffff> FMFILL
28 <7ebddbe7e7dbbd7e> FMFILL
29 <fcf9f3e7cf9f3f7e> FMFILL
30 <7fbfdfeff7fbfdfe> FMFILL
%%EndSetup
%%Page: "1" 1
%%BeginPaperSize: Letter
%%EndPaperSize
612 792 0 FMBEGINPAGE
0 8 Q
0 X
0 K
(Silicon Graphics Pr) 72 750.67 T
(oprietary) 139.57 750.67 T
72 54 540 54 2 L
0.25 H
2 Z
N
(xFS Message System Design) 72 42.62 T
(October 7, 1993) 260.9 42.62 T
(1) 500 42.62 T
1 24 Q
(xFS Message System Design) 166.41 704 T
2 12 Q
(Doug Doucette) 268.2 664 T
1 F
(This document is the design for the message system module of IRIX to be used by xFS.) 72 636 T
2 16 Q
(1.0 Intr) 72 595.33 T
(oduction) 127.23 595.33 T
1 12 Q
0.62 (A message system is provided for use by the \336lesystem implementation. The message system is) 72 568 P
0.64 (used to communicate between certain modules of the implementation, especially over interfaces) 72 554 P
0.08 (that will be remote in the future distributed implementation. W) 72 540 P
0.08 (e will also use the message system) 373.61 540 P
0.92 (\050along with the kernel threads implementation\051 if we can gain additional performance by doing) 72 526 P
(so.) 72 512 T
-0.25 (W) 72 486 P
-0.25 (e expect to use messages from the vnode layer for remote \336les to the \336le system implementation) 82.36 486 P
0.5 (vnode layers, for the distributed version of the \336lesystem. The volume managers in a distributed) 72 472 P
2.16 (system will use messages to communicate with each other) 72 458 P
2.16 (. The administrative interfaces are) 367.81 458 P
-0.22 (implemented using messages, so that they can be remote from the administered objects. The name) 72 444 P
-0.06 (manager needs messages to communicate with remote \336lesystems when crossing mount points. If) 72 430 P
-0.17 (remote devices are supported, then messages will need to be used in the specfs layer to implement) 72 416 P
(that.) 72 402 T
2 16 Q
(2.0 Overview) 72 361.33 T
1 12 Q
1 (The main requirement is speed and simplicity) 72 334 P
1 (, especially in the local case. W) 296.44 334 P
1 (e want local mes-) 452.72 334 P
0.18 (sages to be not much more costly to use than procedure calls, so that the mechanism will be used) 72 320 P
(in the local case, and when the remote system is implemented, there will be less work to do.) 72 306 T
0.73 (The model is that there are three kinds of entities: messages, queues, and threads. Messages are) 72 280 P
1.1 (delivered to \050placed in\051 queues by threads. Messages are removed from queues by threads. W) 72 266 P
1.1 (e) 534.67 266 P
-0.11 (require that multiple threads can remove messages from a queue, so messages are not delivered to) 72 252 P
0.91 (threads. W) 72 238 P
0.91 (e require that multiple threads can send messages to a single queue, as well. That is,) 123.91 238 P
(message transmission is many-to-many) 72 224 T
(.) 260.11 224 T
1.96 (The queue is a \322place\323 for messages to wait when there are no message consumers, and for) 72 198 P
0.96 (threads to wait when there are no message producers. It is a very simple data structure \050pair of) 72 184 P
0.12 (linked lists\051 with a \322name\323. For the moment we will assume that the name of a queue is a 128-bit) 72 170 P
(unique, opaque identi\336er; these will be discussed in a separate paper) 72 156 T
(.) 399.43 156 T
-0.04 (What we have said so far implies an implementation for the local case, but even there a few ques-) 72 130 P
(tions remain. For instance:) 72 116 T
3 F
(\245) 72 96 T
1 F
0.3 (Is the position of a thread or a message in a queue af) 85.75 96 P
0.3 (fected by any priority scheme? Messages) 340.97 96 P
(could have a priority associated with them, and threads certainly will.) 85.75 82 T
FMENDPAGE
%%EndPage: "1" 2
%%Page: "2" 2
612 792 0 FMBEGINPAGE
0 8 Q
0 X
0 K
(Silicon Graphics Pr) 72 750.67 T
(oprietary) 139.57 750.67 T
72 54 540 54 2 L
0.25 H
2 Z
N
(xFS Message System Design) 72 42.62 T
(October 7, 1993) 260.9 42.62 T
(2) 500 42.62 T
3 12 Q
(\245) 72 712 T
1 F
-0.05 (How does memory allocation work for messages: is the message system or its callers responsi-) 85.75 712 P
(ble for message allocation?) 85.75 698 T
(In the interests of simplicity we will make tentative answers for these questions, as follows:) 72 672 T
3 F
(\245) 72 652 T
1 F
-0.29 (No priority scheme, isolate that to the thread mechanism. High-priority messages can be sent to) 85.75 652 P
1.3 (separate queues and read by high-priority threads. A variable priority scheme which caused) 85.75 638 P
(reading a message to set thread priority is possible but probably overkill for us.) 85.75 624 T
3 F
(\245) 72 604 T
1 F
0.84 (W) 85.75 604 P
0.84 (e will make the message system responsible for memory allocation for messages, and pro-) 96.11 604 P
(pose the details of the message format that make that practical.) 85.75 590 T
0.55 (For now) 72 564 P
0.55 (, we will ignore the ef) 112.08 564 P
0.55 (fect on the interfaces of making these messages work in a distrib-) 219.86 564 P
(uted system.) 72 550 T
2 16 Q
(3.0 Operations) 72 509.33 T
2 14 Q
(3.1 Message Queue Operations) 72 474.67 T
1 12 Q
-0.02 (The following queue operations are needed: create, destroy) 72 448 P
-0.02 (, and \336nd. W) 354.87 448 P
-0.02 (e will propose the follow-) 416.15 448 P
(ing as interfaces \050don\325) 72 434 T
(t take the names too seriously\051:) 178.69 434 T
3 F
(\245) 72 414 T
1 F
(q = q_create\050identi\336er\051;) 85.75 414 T
3 F
(\245) 72 394 T
1 F
(q_destroy\050q\051;) 85.75 394 T
3 F
(\245) 72 374 T
1 F
(q = q_address\050identi\336er\051;) 85.75 374 T
1.85 (Only one queue can exist per identi\336er) 72 348 P
1.85 (, so) 268.47 348 P
2 F
1.85 (q_cr) 291.82 348 P
1.85 (eate) 314.92 348 P
1 F
1.85 ( fails \050returns NULL\051 if a queue already) 335.56 348 P
-0.01 (exists.) 72 334 P
2 F
-0.01 (q_destr) 105.31 334 P
-0.01 (oy) 143.74 334 P
1 F
-0.01 ( fails if the queue is active, or perhaps there is a force \337ag which sends the wait-) 155.73 334 P
1.14 (ers and queued messages away) 72 320 P
1.14 (.) 224.31 320 P
2 F
1.14 (q_addr) 231.45 320 P
1.14 (ess) 268.56 320 P
1 F
1.14 ( translates from identi\336er to queue structure address) 283.21 320 P
0.08 (\050returning the value that) 72 306 P
2 F
0.08 (q_cr) 190.89 306 P
0.08 (eate) 213.99 306 P
1 F
0.08 ( originally returned\051; it\325) 234.63 306 P
0.08 (s not clear if we need this as an external) 347.79 306 P
0.1 (interface. W) 72 292 P
0.1 (e may also need information operations to get back the identi\336er) 130.42 292 P
0.1 (, message count, and) 440.09 292 P
(thread count associated with a queue.) 72 278 T
2 14 Q
(3.2 Message Operations) 72 244.67 T
1 12 Q
-0.15 (The following message operations are needed: allocate, free, send, receive. Also some setup oper-) 72 218 P
(ations may be supplied to initialize common portions of the message.) 72 204 T
-0.25 (This is the basic, minimum set of operations. W) 72 178 P
-0.25 (e should consider if there are additional operations) 298.92 178 P
0.4 (we wish to specify that are useful beyond the minimal set. For instance, some form of send-and-) 72 164 P
(wait-for) 72 150 T
(-reply is useful.) 110.39 150 T
0.05 (Before we can specify interfaces, we need to know what common information is in the messages.) 72 124 P
0.25 (W) 72 110 P
0.25 (e will assert the following here, and discuss it further below: message type, response identi\336er) 82.36 110 P
0.25 (,) 537 110 P
2 (sending thread, tar) 72 96 P
2 (get identi\336er) 164.72 96 P
2 (, and enough information to deduce the message components\325) 227.2 96 P
1.46 (sizes. W) 72 82 P
1.46 (e will give each message a type \336eld which de\336nes which structure type describes it;) 113.14 82 P
0.43 (there is a reserved type value which indicates that the message is empty) 72 68 P
0.43 (. Each message structure) 420.14 68 P
FMENDPAGE
%%EndPage: "2" 3
%%Page: "3" 3
612 792 0 FMBEGINPAGE
0 8 Q
0 X
0 K
(Silicon Graphics Pr) 72 750.67 T
(oprietary) 139.57 750.67 T
72 54 540 54 2 L
0.25 H
2 Z
N
(xFS Message System Design) 72 42.62 T
(October 7, 1993) 260.9 42.62 T
(3) 500 42.62 T
1 12 Q
0.09 (will contain a message header structure at its start, containing all the common \336elds. The remain-) 72 712 P
0.37 (der of the message structure will contain \336elds speci\336c to the type. Some \336elds may be pointers;) 72 698 P
(the header must describe this so that the remote case will work.) 72 684 T
(W) 72 658 T
(e will propose the following interfaces \050again, names have not been checked for con\337icts\051:) 82.36 658 T
3 F
(\245) 72 638 T
1 F
(m = m_allocate\050type\051;) 85.75 638 T
3 F
(\245) 72 618 T
1 F
(m_init\050m, tar) 85.75 618 T
(get id, response id\051;) 148.83 618 T
3 F
(\245) 72 598 T
1 F
(m_free\050m\051;) 85.75 598 T
3 F
(\245) 72 578 T
1 F
(m_send\050m\051;) 85.75 578 T
3 F
(\245) 72 558 T
1 F
(m2 = m_send_receive\050m1\051;) 85.75 558 T
3 F
(\245) 72 538 T
1 F
(m = m_receive\050receive id or q\051;) 85.75 538 T
0.6 (Messages are allocated with the tar) 72 512 P
0.6 (get and response ids set to the null value. Allocation and ini-) 242.96 512 P
0.93 (tialization could be combined, but for now we\325ll make the primitives separate.) 72 498 P
2 F
0.93 (m_init) 461.6 498 P
1 F
0.93 ( can be a) 494.91 498 P
(simple macro, at least for the current information being set up.) 72 484 T
0.62 (The send and receive interfaces work solely with queue identi\336ers. While this can be made ef) 72 458 P
0.62 (\336-) 529.34 458 P
-0.28 (cient, it will always be slower than using addresses. This can be repaired by adding \322hint\323 \336elds to) 72 444 P
-0.3 (the messages, which contain the results of calling) 72 430 P
2 F
-0.3 (q_addr) 309.78 430 P
-0.3 (ess) 346.89 430 P
1 F
-0.3 ( on the identi\336er \050one for response id,) 361.55 430 P
0.4 (one for tar) 72 416 P
0.4 (get id\051. W) 122.54 416 P
0.4 (e can also assume that it is actually ok for the) 170.69 416 P
2 F
0.4 (m_r) 395.99 416 P
0.4 (eceive) 417.08 416 P
1 F
0.4 ( call to take a mes-) 447.71 416 P
0.02 (sage queue instead of a receive id as ar) 72 402 P
0.02 (gument. W) 258.46 402 P
0.02 (e put the tar) 310.82 402 P
0.02 (get id \050and address hint\051 in the mes-) 367.63 402 P
1.85 (sage instead of as ar) 72 388 P
1.85 (guments to) 175.75 388 P
2 F
1.85 (m_send) 235.41 388 P
1 F
1.85 (, since these will have to be in the remote messages) 274.73 388 P
(anyway) 72 374 T
(.) 108.52 374 T
-0.1 (W) 72 348 P
-0.1 (e need to decide whether a message receive call can be interrupted. It is clear we can add a non-) 82.36 348 P
-0.12 (blocking \050polling\051 version of) 72 334 P
2 F
-0.12 (m_r) 212.75 334 P
-0.12 (eceive) 233.85 334 P
1 F
-0.12 (, but how do we abort a thread waiting for a message on a) 264.48 334 P
1.06 (particular queue, and why would we be doing that? W) 72 320 P
1.06 (e could assert the existence of a) 340.38 320 P
2 F
1.06 (q_\337ush) 502.66 320 P
1 F
-0.06 (interface, which blocked further messages from being sent to a queue and then sent \322empty\323 mes-) 72 306 P
0.38 (sages to all waiters. This is probably suf) 72 292 P
0.38 (\336cient, and we don\325) 266.98 292 P
0.38 (t have to discuss thread semantics to) 363.17 292 P
(describe it.) 72 278 T
2 16 Q
(4.0 Allocation and Structur) 72 237.33 T
(es) 262.28 237.33 T
2 14 Q
(4.1 Message Queue Allocation and Structur) 72 202.67 T
(es) 334.87 202.67 T
1 12 Q
2.7 (The message queue structures are allocated from ordinary kernel memory by the interfaces) 72 176 P
(described in Section) 72 162 T
(20.1 on page) 172.26 162 T
(21. Each queue structure includes the following:) 236.88 162 T
3 F
(\245) 72 142 T
1 F
(queue identi\336er) 85.75 142 T
3 F
(\245) 72 122 T
1 F
(pointer to head of list of message structures) 85.75 122 T
3 F
(\245) 72 102 T
1 F
(pointer to head of list of thread structures) 85.75 102 T
3 F
(\245) 72 82 T
1 F
(lock control information) 85.75 82 T
FMENDPAGE
%%EndPage: "3" 4
%%Page: "4" 4
612 792 0 FMBEGINPAGE
0 8 Q
0 X
0 K
(Silicon Graphics Pr) 72 750.67 T
(oprietary) 139.57 750.67 T
72 54 540 54 2 L
0.25 H
2 Z
N
(xFS Message System Design) 72 42.62 T
(October 7, 1993) 260.9 42.62 T
(4) 500 42.62 T
3 12 Q
(\245) 72 712 T
1 F
(current and maximum length of message list) 85.75 712 T
3 F
(\245) 72 692 T
1 F
(current and maximum length of thread list) 85.75 692 T
3 F
(\245) 72 672 T
1 F
(if) 85.75 672 T
2 F
(q_\337ush) 96.07 672 T
1 F
( exists, a state \337ag for the queue) 133.41 672 T
3 F
(\245) 72 652 T
1 F
(a string naming the queue for debugging and statistics printing) 85.75 652 T
0.79 (Also needed are hashing or indexing structures for the translation of unique identi\336ers to queue) 72 626 P
1.97 (structure addresses. For the moment we will assume a simple hashing scheme, and a sibling) 72 612 P
(pointer in the queue structure to point to the next same-hash-value queue.) 72 598 T
2 14 Q
(4.2 Message Allocation and Structur) 72 564.67 T
(es) 292.51 564.67 T
1 12 Q
0.19 (As described in Section) 72 538 P
0.19 (20.2 on page) 189.15 538 P
0.19 (21, the messages are divided into a header \050the same for all) 254.15 538 P
(message types\051 and a body \050dif) 72 524 T
(ferent for all message types\051. The header includes the following:) 220.67 524 T
3 F
(\245) 72 504 T
1 F
(message type [small integer]) 85.75 504 T
3 F
(\245) 72 484 T
1 F
(tar) 85.75 484 T
(get queue identi\336er [unique id]) 98.18 484 T
3 F
(\245) 72 464 T
1 F
(tar) 85.75 464 T
(get queue address hint [queue structure pointer] \050and tar) 98.18 464 T
(get host identi\336er hint\051) 366.42 464 T
3 F
(\245) 72 444 T
1 F
(source thread \050and source host identi\336er\051, for debugging) 85.75 444 T
3 F
(\245) 72 424 T
1 F
(response queue identi\336er [unique id]) 85.75 424 T
3 F
(\245) 72 404 T
1 F
(response queue address hint [queue structure pointer] \050and response host identi\336er hint\051) 85.75 404 T
3 F
(\245) 72 384 T
1 F
(pointer to link the message on its queue) 85.75 384 T
-0.08 (The message type implies the value of a couple of other pieces of information: the size and layout) 72 358 P
0.32 (of the message body) 72 344 P
0.32 (. W) 170.44 344 P
0.32 (e will assume that each body is composed of a data portion and a pointer) 187.12 344 P
1.2 (portion. The size of the data portion is known based on the message type, as is the number of) 72 330 P
0.4 (pointers.) 72 316 P
2 K
0.4 (Question: do the pointers point to \336xed or variable-sized data? If \336xed, the pointer sec-) 117.04 316 P
-0.07 (tion is just pointers, and the length of data pointed to is known based on the message type. If vari-) 72 302 P
0.05 (able, each length must be stored in the structure along with the pointer) 72 288 P
0.05 (. Note that the size must be) 409.42 288 P
-0.24 (transmitted, in the remote case, for variable sizes; if the sizes are \336xed then they can be asserted to) 72 274 P
(be known on both sides.) 72 260 T
0 K
0.69 (Messages must be stored in global \050not procedure-local\051 memory to avoid the necessity of mes-) 72 234 P
-0.28 (sage copying. T) 72 220 P
-0.28 (o simplify this the) 146.87 220 P
2 F
-0.28 (m_allocate) 235.7 220 P
1 F
-0.28 ( and) 290.98 220 P
2 F
-0.28 (m_fr) 313.73 220 P
-0.28 (ee) 338.82 220 P
1 F
-0.28 ( interfaces are supplied. The model is as) 349.47 220 P
(follows:) 72 206 T
-0.15 (A message is allocated with) 72 180 P
2 F
-0.15 (m_allocate) 208.16 180 P
1 F
-0.15 (, then initialized for sending with) 263.45 180 P
2 F
-0.15 (m_init) 424.8 180 P
1 F
-0.15 (. It is then sent to) 458.12 180 P
-0.06 (the destination queue with) 72 166 P
2 F
-0.06 (m_send) 201.01 166 P
1 F
-0.06 ( \050for instance\051. This links it onto the tail of the list of messages) 240.32 166 P
0.31 (in the queue structure; the receiver removes the message from the head of the list of messages in) 72 152 P
0.42 (the queue structure. The receiver examines and processes the message, and then calls) 72 138 P
2 F
0.42 (m_fr) 488.84 138 P
0.42 (ee) 513.93 138 P
1 F
0.42 ( on) 524.58 138 P
(it.) 72 124 T
0.43 (In the remote message-passing case, the operations are the same as far as the message producers) 72 98 P
1.65 (and consumers are concerned. The pointer \336elds, if any) 72 84 P
1.65 (, in the message, are transformed into) 350.22 84 P
0.52 (arrays of bytes of data \050with lengths\051. The message is freed on the sending side once it has been) 72 70 P
FMENDPAGE
%%EndPage: "4" 5
%%Page: "5" 5
612 792 0 FMBEGINPAGE
0 8 Q
0 X
0 K
(Silicon Graphics Pr) 72 750.67 T
(oprietary) 139.57 750.67 T
72 54 540 54 2 L
0.25 H
2 Z
N
(xFS Message System Design) 72 42.62 T
(October 7, 1993) 260.9 42.62 T
(5) 500 42.62 T
1 12 Q
0.18 (successfully delivered \050) 72 712 P
2 K
0.18 (? we haven\325) 185.6 712 P
0.18 (t discussed what kind of protocol this is ?) 243.69 712 P
0 K
0.18 (\051. As the message is) 443.68 712 P
0.08 (received a new message structure is allocated to hold it, and the new structure is put on the queue) 72 698 P
1.17 (at that end. The arrays of bytes corresponding to the pointer section of the message are turned) 72 684 P
1.04 (back into pointers to data on the receiving end. Since the original pointed-at objects are on the) 72 670 P
(sending side, these are copies and can be allocated along with the other message data.) 72 656 T
0.25 (It is possible that the free operation will actually be a callback routine, defaulting to the behavior) 72 630 P
0.71 (given above. This would allow more \337exibility per subsystem on how message memory is allo-) 72 616 P
(cated. The callback would have to be registered for the message type.) 72 602 T
2 16 Q
(5.0 Distributed Message System Design) 72 561.33 T
1 12 Q
([T) 72 534 T
(o be supplied later) 82.48 534 T
(.]) 170.09 534 T
FMENDPAGE
%%EndPage: "5" 6
%%Trailer
%%BoundingBox: 0 0 612 792
%%Pages: 5 1
%%DocumentFonts: Palatino-Roman
%%+ Times-Roman
%%+ Times-Bold
%%+ Courier-Bold