New quickthreads-based threads package.
authorJosh Yelon <jyelon@uiuc.edu>
Mon, 5 May 1997 13:49:17 +0000 (13:49 +0000)
committerJosh Yelon <jyelon@uiuc.edu>
Mon, 5 May 1997 13:49:17 +0000 (13:49 +0000)
69 files changed:
src/QuickThreads/CHANGES [new file with mode: 0644]
src/QuickThreads/INSTALL [new file with mode: 0644]
src/QuickThreads/Makefile [new file with mode: 0644]
src/QuickThreads/README [new file with mode: 0644]
src/QuickThreads/configure [new file with mode: 0755]
src/QuickThreads/copyright.h [new file with mode: 0644]
src/QuickThreads/doc/qt.ps [new file with mode: 0644]
src/QuickThreads/md/axp.README [new file with mode: 0644]
src/QuickThreads/md/axp.h [new file with mode: 0644]
src/QuickThreads/md/axp.s [new file with mode: 0644]
src/QuickThreads/md/axp_b.s [new file with mode: 0644]
src/QuickThreads/md/hppa.h [new file with mode: 0644]
src/QuickThreads/md/hppa.s [new file with mode: 0644]
src/QuickThreads/md/hppa_b.s [new file with mode: 0644]
src/QuickThreads/md/i386.README [new file with mode: 0644]
src/QuickThreads/md/i386.h [new file with mode: 0644]
src/QuickThreads/md/i386.s [new file with mode: 0644]
src/QuickThreads/md/i386_b.s [new file with mode: 0644]
src/QuickThreads/md/ksr1.h [new file with mode: 0644]
src/QuickThreads/md/ksr1.s [new file with mode: 0644]
src/QuickThreads/md/ksr1_b.s [new file with mode: 0644]
src/QuickThreads/md/m88k.README [new file with mode: 0644]
src/QuickThreads/md/m88k.c [new file with mode: 0644]
src/QuickThreads/md/m88k.h [new file with mode: 0644]
src/QuickThreads/md/m88k.s [new file with mode: 0644]
src/QuickThreads/md/m88k_b.s [new file with mode: 0644]
src/QuickThreads/md/mips-irix5.s [new file with mode: 0644]
src/QuickThreads/md/mips.h [new file with mode: 0644]
src/QuickThreads/md/mips.s [new file with mode: 0644]
src/QuickThreads/md/mips_b.s [new file with mode: 0644]
src/QuickThreads/md/setjmp_b.c [new file with mode: 0644]
src/QuickThreads/md/sjalloca.c [new file with mode: 0644]
src/QuickThreads/md/sparc.h [new file with mode: 0644]
src/QuickThreads/md/sparc.s [new file with mode: 0644]
src/QuickThreads/md/sparc_b.s [new file with mode: 0644]
src/QuickThreads/md/stub.c [new file with mode: 0644]
src/QuickThreads/md/stub.h [new file with mode: 0644]
src/QuickThreads/md/stub_b.c [new file with mode: 0644]
src/QuickThreads/md/vax.h [new file with mode: 0644]
src/QuickThreads/md/vax.s [new file with mode: 0644]
src/QuickThreads/md/vax_b.s [new file with mode: 0644]
src/QuickThreads/meas.c [new file with mode: 0644]
src/QuickThreads/mkfiles/aix32-gcc [new file with mode: 0644]
src/QuickThreads/mkfiles/axp-gcc [new file with mode: 0644]
src/QuickThreads/mkfiles/axp-osf1-cc [new file with mode: 0644]
src/QuickThreads/mkfiles/axp-osf2-cc [new file with mode: 0644]
src/QuickThreads/mkfiles/convex-hppa [new file with mode: 0755]
src/QuickThreads/mkfiles/hpux-cc [new file with mode: 0644]
src/QuickThreads/mkfiles/i386-gcc [new file with mode: 0644]
src/QuickThreads/mkfiles/i386-gcc-ss [new file with mode: 0644]
src/QuickThreads/mkfiles/irix5-gcc [new file with mode: 0644]
src/QuickThreads/mkfiles/ksr1-cc [new file with mode: 0644]
src/QuickThreads/mkfiles/meerkat [new file with mode: 0644]
src/QuickThreads/mkfiles/solaris-cc [new file with mode: 0644]
src/QuickThreads/mkfiles/solaris-gcc [new file with mode: 0644]
src/QuickThreads/mkfiles/stub-gcc [new file with mode: 0644]
src/QuickThreads/mkfiles/sunos-gcc [new file with mode: 0644]
src/QuickThreads/qt.c [new file with mode: 0644]
src/QuickThreads/qt.h [new file with mode: 0644]
src/QuickThreads/qtb.h [new file with mode: 0644]
src/QuickThreads/stp.c [new file with mode: 0644]
src/QuickThreads/stp.h [new file with mode: 0644]
src/QuickThreads/time/README.time [new file with mode: 0644]
src/QuickThreads/time/assim [new file with mode: 0755]
src/QuickThreads/time/cswap [new file with mode: 0755]
src/QuickThreads/time/go [new file with mode: 0755]
src/QuickThreads/time/init [new file with mode: 0755]
src/QuickThreads/time/prim [new file with mode: 0755]
src/QuickThreads/time/raw [new file with mode: 0755]

diff --git a/src/QuickThreads/CHANGES b/src/QuickThreads/CHANGES
new file mode 100644 (file)
index 0000000..aac4baf
--- /dev/null
@@ -0,0 +1,23 @@
+QuickThreads 003: Changes since QuickThreads 002.
+
+ - Added setjmp_a portable version.
+ - Added the stub version.
+ - simplified makefile system.
+ - Modified sparc version and qt.c to eliminate leading _ dependency.
+ - Eliminated the iter counts for meas by using a better timer.
+
+QuickThreads 002: Changes since QuickThreads 001.
+
+ - Now can be used by C++ programs.
+ - Now *really* works with stacks that grow up.
+ - Supports AXP OSF 2.x cc's varargs.
+ - Supports HP Precision (HP-PA) on workstations and Convex.
+ - Supports assemblers for Intel iX86 ith only '//'-style comments.
+ - Supports Silicon Graphics Irix 5.x with dynamic linking.
+ - Supports System V and Solaris 2.x with no `_' on compiler-generated
+   identifiers; *some* platforms only.
+
+Note: not all "./config" arguments are compatible with QT 001.
+
+
+QuickThreads 001: Base version.
diff --git a/src/QuickThreads/INSTALL b/src/QuickThreads/INSTALL
new file mode 100644 (file)
index 0000000..a93ac68
--- /dev/null
@@ -0,0 +1,47 @@
+Installation of the `QuickThreads' threads-building toolkit.
+
+* Notice
+
+QuickThreads -- Threads-building toolkit.
+Copyright (c) 1993 by David Keppel
+
+Permission to use, copy, modify and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice and this notice
+appear in all copies.  This software is provided as a
+proof-of-concept and for demonstration purposes; there is no
+representation about the suitability of this software for any
+purpose.
+
+
+* Configuration
+
+Configure with
+
+       ./configure *machtype*
+
+where "*machtype*" is one of the supported target machines.  As of
+May 1997, the makefiles were revamped, and they aren't quite up-to-date.
+These are the machines for which we currently have working makefiles:
+
+       axp-gcc      convex-hppa  i386-gcc-ss  setjmp-gcc   stub-gcc
+       axp-osf1-cc  hppa-cc      ksr1-cc      solaris-cc
+       axp-osf2-cc  i386-gcc     meerkat      solaris-gcc
+
+However, there is also a vax version without a makefile, and several
+of these versions can be trivially ported to other operating systems
+with the same architecture by editing the makefiles.
+
+* Build
+
+To build the QuickThreads library, first configure (see above) then
+type `make' in the top-level directory.  This also builds the
+demonstration threads package, SimpleThreads, and the stress-test
+program.
+
+* Installation
+
+Build the QuickThreads library (see above) and then copy `libqt.a' to
+the installation library directory (e.g., /usr/local/lib) and `qt.h'
+and `qtmd.h' to the installation include directory (e.g.,
+/usr/local/include).
diff --git a/src/QuickThreads/Makefile b/src/QuickThreads/Makefile
new file mode 100644 (file)
index 0000000..579033e
--- /dev/null
@@ -0,0 +1,12 @@
+
+all: mostlyclean
+       @if [ ! -f Makescript ] ;then echo "Must configure first." ; exit 1; fi
+       ./Makescript
+
+mostlyclean:
+       rm -f qtmd.h libqt.a libstp.a meas.o stp.o qt.o
+       rm -f qtmdb.s qtmds.s qtmdc.o qtmdb.o qtmds.o run
+
+clean: mostlyclean
+       rm -f Makescript
+
diff --git a/src/QuickThreads/README b/src/QuickThreads/README
new file mode 100644 (file)
index 0000000..4d33c18
--- /dev/null
@@ -0,0 +1,205 @@
+This is a source code distribution for QuickThreads.  QuickThreads is a
+toolkit for building threads packages; it is described in detail in the
+University of Washington CS&E Technical report #93-05-06, available via
+anonymous ftp from `ftp.cs.washington.edu' (128.95.1.4, as of Oct. '94)
+in `tr/1993/05/UW-CSE-93-05-06.PS.Z'.
+
+This distribution shows basic ideas in QuickThreads and elaborates
+with example implementations for a gaggle of machines.  As of
+October '94 those machines included:
+
+       80386 faimly
+       88000 faimily
+       DEC AXP (Alpha) family
+       HP-PA family
+       KSR
+       MIPS family
+       SPARC V8 family
+       VAX family
+
+In May 1997, a setjmp-based version which is likely to compile on
+many platforms has been added.
+
+Be aware: that there is no varargs code for the KSR, or the setjmp
+version.
+
+The HP-PA port was designed to work with both HP workstations
+and Convex SPP computers. It was generously provided by Uwe Reder
+<uereder@cip.informatik.uni-erlangen.de>. It is part of the ELiTE
+(Erlangen Lightweight Thread Environment) project directed by 
+Frank Bellosa <bellosa@informatik.uni-erlangen.de> at the Operating 
+Systems Department of the University of Erlangen (Germany).
+
+Other contributors include: Weihaw Chuang, Richard O'Keefe,
+Laurent Perron, John Polstra, Shinji Suzuki, Assar Westerlund,
+thanks also to Peter Buhr and Dirk Grunwald.
+
+
+Here is a brief summary:
+
+QuickThreads is a toolkit for building threads packages.  It is my hope
+that you'll find it easier to use QuickThreads normally than to take it
+and modify the raw cswap code to fit your application.  The idea behind
+QuickThreads is that it should make it easy for you to write & retarget
+threads packages.  If you want the routine `t_create' to create threads
+and `t_block' to suspend threads, you write them using the QuickThreads
+`primitive' operations `QT_SP', `QT_INIT', and `QT_BLOCK', that perform
+machine-dependent initialization and blocking, plus code you supply for
+performing the portable operatons.  For example, you might write:
+
+       t_create (func, arg)
+       {
+         stk = malloc (STKSIZE);
+         stackbase = QT_SP (stk, STKSIZE);
+         sp = QT_INIT (stakcbase, func, arg);
+         qput (runq, sp);
+       }
+
+Threads block by doing something like:
+
+       t_block()
+       {
+         sp_next = qget (runq);
+         QT_BLOCK (helper, runq, sp_next);
+         // wake up again here
+       }
+
+       // called by QT_BLOCK after the old thread has blocked,
+       // puts the old thread on the queue `onq'.
+       helper (sp_old, onq)
+       {
+         qput (onq, sp_old);
+       }
+
+(Of course) it's actually a bit more complex than that, but the general
+idea is that you write portable code to allocate stacks and enqueue and
+dequeue threads.  Than, to get your threads package up and running on a
+different machine, you just reconfigure QuickThreads and recompile, and
+that's it.
+
+The QuickThreads `distribution' includes a sample threads package (look
+at stp.{c,h}) that is written in terms of QuickThreads operations.  The
+TR mentioned above explains the simple threads package in detail.
+
+If you do use QuickThreads, I'd like to hear both about what worked for
+you and what didn't work, problems you had, insights gleaned, etc.
+
+Let me know what you think.
+
+David Keppel <pardo@cs.washington.edu>
+
+
+-------------------------------------------------------------------------------
+
+Date: Tue, 11 Jan 94 13:23:11 -0800
+From: "pardo@cs.washington.edu" <pardo@meitner.cs.washington.edu>
+
+>[What's needed to get `qt' on an i860-based machine?]
+
+Almost certainly "some assembly required" (pun accepted).
+
+To write a cswap port, you need to understand the context switching
+model.  Turn to figure 2 in the QT TR.  Here's about what the assembly
+code looks like to implement that:
+
+       qt_cswap:
+               adjust stack pointer
+               save callee-save registers on to old's stack
+               argument register <- old sp
+               sp <- new sp
+               (*helper)(args...)
+               restore callee-save registers from new's stack
+               unadjust stack pointer
+               return
+
+Once more in slow motion:
+
+       - `old' thread calls context switch routine (new, a0, a1, h)
+       - cswap routine saves registers that have useful values
+       - cswap routine switches to new stack
+       - cswap routine calls helper function (*h)(old, a0, a1)
+       - when helper returns, cswap routine restores registers
+         that were saved the last time `new' was suspended
+       - cswap routine returns to whatever `new' routine called the
+         context switch routine
+
+There's a few tricks here.  First, how do you start a thread running
+for the very first time?  Answer is: fake some stuff on the stack
+so it *looks* like it was called from the middle of some routine.
+When the new thread is restarted, it is treated like any other
+thread.  It just so happens that it's never really run before, but
+you can't tell that because the saved state makes it look like like
+it's been run.  The return pc is set to point at a little stub of
+assembly code that loads up registers with the right values and
+then calls `only'.
+
+Second, I advise you to forget about varargs routines (at least
+until you get single-arg routines up and running).
+
+Third, on most machines `qt_abort' is the same as `qt_cswap' except
+that it need not save any callee-save registers.
+
+Fourth, `qt_cswap' needs to save and restore any floating-point
+registers that are callee-save (see your processor handbook).  On
+some machines, *no* floating-point registers are callee-save, so
+`qt_cswap' is exactly the same as the integer-only cswap routine.
+
+I suggest staring at the MIPS code for a few minutes.  It's "mostly"
+generic RISC code, so it gets a lot of the flavor across without
+getting too bogged down in little nitty details.
+
+
+
+Now for a bit more detail:  The stack is laid out to hold callee-save
+registers.  On many machines, I implemented fp cswap as save fp
+regs, call integer cswap, and when integer cswap returns (when the
+thread wakes up again), restore fp regs.
+
+For thread startup, I figure out some callee-save registers that
+I use to hold parameters to the startup routine (`only').  When
+the thread is being started it doesn't have any saved registers
+that need to be restored, but I go ahead and let the integer context
+switch routine restore some registers then "return" to the stub
+code.  The stub code then copies the "callee save" registers to
+argument registers and calls the startup routine.  That keeps the
+stub code pretty darn simple.
+
+For each machine I need to know the machine's procedure calling
+convention before I write a port.  I figure out how many callee-save
+registers are there and allocate enough stack space for those
+registers.  I also figure out how parameters are passed, since I
+will need to call the helper function.  On most RISC machines, I
+just need to put the old sp in the 0'th arg register and then call
+indirect through the 3rd arg register; the 1st and 2nd arg registers
+are already set up correctly.  Likewise, I don't touch the return
+value register between the helper's return and the context switch
+routine's return.
+
+I have a bunch of macros set up to do the stack initialization.
+The easiest way to debug this stuff is to go ahead and write a C
+routine to do stack initialization.  Once you're happy with it you
+can turn it in to a macro.
+
+In general there's a lot of ugly macros, but most of them do simple
+things like return constants, etc.  Any time you're looking at it
+and it looks confusing you just need to remember "this is actually
+simple code, the only tricky thing is calling the helper between
+the stack switch and the new thread's register restore."
+
+
+You will almost certainly need to write the assembly code fragment
+that starts a thread.  You might be able to do a lot of the context
+switch code with `setjmp' and `longjmp', if they *happen* to have
+the "right" implementation.  But getting all the details right (the
+helper can return a value to the new thread's cswap routine caller)
+is probaby trickier than writing code that does the minimum and
+thus doesn't have any extra instructions (or generality) to cause
+problems.
+
+I don't know of any ports besides those included with the source
+code distribution.   If you send me a port I will hapily add it to
+the distribution.
+
+Let me know as you have questions and/or comments.
+
+       ;-D on  ( Now *that*'s a switch... )  Pardo
diff --git a/src/QuickThreads/configure b/src/QuickThreads/configure
new file mode 100755 (executable)
index 0000000..166d4b4
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+if [ ! -f mkfiles/$1 ] ; then
+    echo "Usage: configure <version>"
+    echo ""
+    echo "Available versions are:"
+    echo ""
+    (cd mkfiles ; ls -C)
+    echo ""
+    exit 1
+fi
+
+rm -f Makescript
+ln -s mkfiles/$1 Makescript
+echo "You're ready to do a make now."
diff --git a/src/QuickThreads/copyright.h b/src/QuickThreads/copyright.h
new file mode 100644 (file)
index 0000000..8a2361f
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
diff --git a/src/QuickThreads/doc/qt.ps b/src/QuickThreads/doc/qt.ps
new file mode 100644 (file)
index 0000000..38e1e11
--- /dev/null
@@ -0,0 +1,16895 @@
+%!PS-Adobe-1.0
+%%Creator: gar.cs.washington.edu:pardo (David Keppel)
+%%Title: stdin (ditroff)
+%%CreationDate: Thu Dec 23 17:15:44 1993
+%%EndComments
+% lib/psdit.pro -- prolog for psdit (ditroff) files
+% Copyright (c) 1984, 1985 Adobe Systems, Inc. All Rights Reserved.
+
+/$DITroff 140 dict def $DITroff begin
+/xi
+ {0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto
+  /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def
+  F /firstpage true def /pagesave save def}def
+/arctoobig 90 def /arctoosmall .05 def
+/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def
+/tan{dup sin exch cos div}def
+/point{resolution 72 div mul}def
+/dround        {transform round exch round exch itransform}def
+/xT{/devname exch def}def
+/xr{/mh exch def /my exch def /resolution exch def}def
+/xp{}def
+/xs{docsave restore end}def
+/xt{showpage}def
+/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not
+ {fonts slotno fontname findfont put fontnames slotno fontname put}if}def
+/xH{/fontheight exch def}def
+/xS{/fontslant exch def}def
+/s{/fontsize exch def /fontheight fontsize def}def
+/f{/fontnum exch def}def
+/F {fontheight 0 le {/fontheight fontsize def}if
+    fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore
+    fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if
+    makefont setfont .04 fontsize point mul 0 dround pop setlinewidth
+   } def
+/X{exch currentpoint exch pop moveto show}def
+/N{3 1 roll moveto show}def
+/Y{exch currentpoint pop exch moveto show}def
+/S{show}def
+/MX{currentpoint exch pop moveto}def
+/MY{currentpoint pop exch moveto}def
+/MXY{moveto}def
+/cb{pop}def    % action on unknown char -- nothing for now
+/n{}def /w{}def
+/p{pop firstpage not{showpage}if pagesave restore /pagesave save def
+   /firstpage false def}def
+/abspoint{currentpoint exch pop add exch currentpoint pop add exch}def
+/distance{dup mul exch dup mul add sqrt}def
+/dstroke{currentpoint stroke moveto}def
+/Dl{2 copy gsave rlineto stroke grestore rmoveto}def
+/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop
+ currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def
+ currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def
+/Dc{dup arcellipse dstroke}def
+/De{arcellipse dstroke}def
+/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def
+ /cradius centerv centerv mul centerh centerh mul add sqrt def
+ /eradius endv endv mul endh endh mul add sqrt def
+ /endang endv endh atan def
+ /startang centerv neg centerh neg atan def
+ /sweep startang endang sub dup 0 lt{360 add}if def
+ sweep arctoobig gt
+ {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def
+  /midh midang cos midrad mul def /midv midang sin midrad mul def
+  midh neg midv neg endh endv centerh centerv midh midv Da
+  currentpoint moveto Da}
+ {sweep arctoosmall ge
+  {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def
+  centerv neg controldelt mul centerh controldelt mul
+  endv neg controldelt mul centerh add endh add
+  endh controldelt mul centerv add endv add
+  centerh endh add centerv endv add rcurveto dstroke}
+ {centerh endh add centerv endv add rlineto dstroke}ifelse}ifelse}def
+
+/Barray 200 array def % 200 values in a wiggle
+/D~{mark}def
+/D~~{counttomark Barray exch 0 exch getinterval astore /Bcontrol exch def pop
+ /Blen Bcontrol length def Blen 4 ge Blen 2 mod 0 eq and
+ {Bcontrol 0 get Bcontrol 1 get abspoint /Ycont exch def /Xcont exch def
+  Bcontrol 0 2 copy get 2 mul put Bcontrol 1 2 copy get 2 mul put
+  Bcontrol Blen 2 sub 2 copy get 2 mul put
+  Bcontrol Blen 1 sub 2 copy get 2 mul put
+  /Ybi /Xbi currentpoint 3 1 roll def def 0 2 Blen 4 sub
+  {/i exch def
+   Bcontrol i get 3 div Bcontrol i 1 add get 3 div
+   Bcontrol i get 3 mul Bcontrol i 2 add get add 6 div
+   Bcontrol i 1 add get 3 mul Bcontrol i 3 add get add 6 div
+   /Xbi Xcont Bcontrol i 2 add get 2 div add def
+   /Ybi Ycont Bcontrol i 3 add get 2 div add def
+   /Xcont Xcont Bcontrol i 2 add get add def
+   /Ycont Ycont Bcontrol i 3 add get add def
+   Xbi currentpoint pop sub Ybi currentpoint exch pop sub rcurveto
+  }for dstroke}if}def
+end
+/ditstart{$DITroff begin
+ /nfonts 10 def
+ /fonts[nfonts{0}repeat]def
+ /fontnames[nfonts{()}repeat]def
+1(Times-Roman)xf
+2(Times-Italic)xf
+3(Times-Bold)xf
+4(Times-BoldItalic)xf
+5(Helvetica)xf
+6(Courier)xf
+7(Symbol)xf
+/docsave save def
+}def
+
+% character outcalls
+/oc 
+  {/pswid exch def /cc exch def /name exch def
+   /ditwid pswid fontsize mul resolution mul 72000 div def
+   /ditsiz fontsize resolution mul 72 div def
+   ocprocs name known{ocprocs name get exec}{name cb}
+   ifelse}def
+/fractm [.65 0 0 .6 0 0] def
+/fraction
+ {/fden exch def /fnum exch def gsave /cf currentfont def
+  cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto
+  fnum show rmoveto currentfont cf setfont(\244)show setfont fden show 
+  grestore ditwid 0 rmoveto} def
+
+/ocb
+ {/s2 .5 dm def /s4 .25 dm def
+  2 setlinejoin gsave currentpoint newpath dround translate 0 0 moveto}def
+/oce {grestore ditwid 0 rmoveto}def
+/dm {ditsiz mul}def
+/4p {pop pop pop pop}def
+
+/ocprocs 50 dict def ocprocs begin
+(14) {(1)(4)fraction}def
+(12) {(1)(2)fraction}def
+(34) {(3)(4)fraction}def
+
+(sq) 
+ {gsave /len .64 dm def .08 dm 0 rmoveto currentpoint dround newpath moveto
+  len 0 rlineto 0 len neg rlineto len neg 0 rlineto closepath stroke oce}def
+(bx)
+ {gsave /len .64 dm def .08 dm 0 rmoveto currentpoint dround newpath moveto
+  len 0 rlineto 0 len neg rlineto len neg 0 rlineto closepath fill oce}def
+(ci)
+ {gsave .5 dm -.36 dm rmoveto currentpoint newpath .33 dm 0 360 arc 
+  .05 dm setlinewidth stroke oce}def
+(bv) {ocb s4 -.8 dm moveto 0 ditsiz rlineto stroke oce}def
+(br) {ocb 0 -.75 dm moveto 0 ditsiz rlineto stroke oce}def
+(sr) {gsave 0 .06 dm rmoveto(\326)show oce}def
+(rn) {gsave -.51 dm .06 dm rmoveto(\140)show oce}def
+(is) {gsave 0 .15 dm rmoveto(\362)show oce}def
+(ru) {ocb .5 dm 0 rlineto stroke oce}def
+(lt)% left top curly
+ {ocb s4 .2 dm moveto 0 -.55 dm rlineto currentpoint pop
+  -.8 dm 2 copy exch s4 add exch s4 arcto 4p stroke oce}def
+(lb)% left bot curly
+ {ocb s4 -.8 dm moveto 0 .55 dm rlineto currentpoint pop
+  .2 dm 2 copy exch s4 add exch s4 arcto 4p stroke oce}def
+(rt)% right top curly
+ {ocb s4 .2 dm moveto 0 -.55 dm rlineto currentpoint pop
+  -.8 dm 2 copy exch s4 sub exch s4 arcto 4p stroke oce}def
+(rb)% right bot curly
+ {ocb s4 -.8 dm moveto 0 .55 dm rlineto currentpoint pop
+  .2 dm 2 copy exch s4 sub exch s4 arcto 4p stroke oce}def
+(lk)% left mid curly
+ {ocb /s3 -.3 dm def s4 -.8 dm moveto s4 s3 0 s3 s4 arcto pop pop ditsiz 
+  add s4 s3 4 2 roll s4 arcto 4p s4 .2 dm lineto stroke oce}def
+(rk)% right mid curly
+ {ocb /s3 -.3 dm def s4 -.8 dm moveto s4 s3 s2 s3 s4 arcto pop pop ditsiz 
+  add s4 s3 4 2 roll s4 arcto 4p s4 .2 dm lineto stroke oce}def
+(lf)% left floor
+ {ocb s4 -.8 dm moveto 0 ditsiz rlineto s4 0 rlineto stroke oce}def
+(rf)% right floor
+ {ocb s4 -.8 dm moveto 0 ditsiz rlineto s4 neg 0 rlineto stroke oce}def
+(lc)% left ceil
+ {ocb s4 .2 dm moveto 0 ditsiz neg rlineto s4 0 rlineto stroke oce}def
+(rc)% right ceil
+ {ocb s4 .2 dm moveto 0 ditsiz neg rlineto s4 neg 0 rlineto stroke oce}def
+end
+
+ditstart
+(ps)xT
+576 1 1 xr
+1(Times-Roman)xf
+2(Times-Italic)xf
+3(Times-Bold)xf
+4(Times-BoldItalic)xf
+5(Helvetica)xf
+6(Helvetica-Bold)xf
+7(Courier)xf
+8(Courier-Bold)xf
+9(Symbol)xf
+xi
+%%EndProlog
+
+%%Page: 1 1
+1 p
+10 s 0 xH 0 xS 1 f F
+12 s 0 xH 0 xS 3 f F
+1045 984(Tools)N
+1293(and)X
+1471(Techniques)X
+1964(for)X
+2111(Building)X
+2487(Fast)X
+2687(Portable)X
+3064(Threads)X
+3429(Packages)X
+10 s 2 f F
+2205 1176(David)N
+2421(Keppel)X
+1 f F
+2011 1320(University)N
+2369(of)X
+2456(Washington)X
+1842 1416(Technical)N
+2179(Report)X
+2417(UWCSE)X
+2717(93-05-06)X
+2 f F
+2238 1704(ABSTRACT)N
+1 f F
+1067 1904(Threads)N
+1367(are)X
+1507(units)X
+1703(of)X
+1811(concurrent)X
+2195(execution)X
+2547(that)X
+2707(can)X
+2859(be)X
+2975(viewed)X
+3247(as)X
+3354(abstract)X
+3644(data)X
+3818(types)X
+867 2008(\(ADTs\))N
+1148(with)X
+1321(operations)X
+1686(to)X
+1779(initialize)X
+2090(and)X
+2237(run)X
+2375(them.)X
+2606(It)X
+2686(is)X
+2770(common)X
+3081(to)X
+3173(improve)X
+3470(performance)X
+3907(by)X
+867 2112(hard-coding)N
+1289(allocation)X
+1639(and)X
+1789(scheduling)X
+2170(policies,)X
+2473(but)X
+2609(that)X
+2763(has)X
+2904(led)X
+3036(to)X
+3131(the)X
+3262(development)X
+3709(of)X
+3809(many)X
+867 2216(threads)N
+1136(packages,)X
+1488(each)X
+1673(with)X
+1852(policies)X
+2138(tuned)X
+2353(for)X
+2484(a)X
+2557(particular)X
+2902(set)X
+3028(of)X
+3132(applications.)X
+3596(Further,)X
+3889(the)X
+867 2320(machine-dependence)N
+1570(of)X
+1661(threads)X
+1917(packages)X
+2236(restricts)X
+2514(the)X
+2636(availability)X
+3020(of)X
+3111(applications)X
+3522(built)X
+3692(on)X
+3795(top)X
+3920(of)X
+867 2424(them.)N
+1101(This)X
+1277(paper)X
+1490(examines)X
+1826(techniques)X
+2202(for)X
+2329(building)X
+2628(threads)X
+2893(packages)X
+3221(and)X
+3370(discusses)X
+3701(tradeoffs)X
+867 2528(between)N
+1172(performance,)X
+1635(\257exibility,)X
+2001(and)X
+2153(portability.)X
+2562(It)X
+2647(then)X
+2821(introduces)X
+3191(QuickThreads,)X
+3702(a)X
+3774(simple)X
+867 2632(threads)N
+1128(toolkit)X
+1365(with)X
+1536(a)X
+1601(portable)X
+1893(interface.)X
+2244(This)X
+2415(paper)X
+2623(shows)X
+2852(how)X
+3019(QuickThreads)X
+3503(can)X
+3644(be)X
+3749(used)X
+3925(to)X
+867 2736(implement)N
+1239(a)X
+1305(basic)X
+1500(uniprocessor)X
+1940(threads)X
+2202(package)X
+2496(and)X
+2642(discusses)X
+2970(the)X
+3097(implementation)X
+3628(of)X
+3724(portable)X
+867 2840(threads)N
+1124(packages)X
+1444(tuned)X
+1647(to)X
+1734(the)X
+1857(needs)X
+2065(of)X
+2157(particular)X
+2490(applications.)X
+2942(For)X
+3078(example,)X
+3395(QuickThreads)X
+3875(can)X
+867 2944(be)N
+969(used)X
+1142(to)X
+1230(build)X
+1420(barrier)X
+1661(synchronization)X
+2199(that)X
+2345(runs)X
+2508(in)X
+2 f F
+2595(O\()X
+1 f F
+2680(lg)X
+8 s F
+2742 2976(2)N
+10 s 2 f F
+2799 2944(processors\))N
+1 f F
+3198(time)X
+3365(units)X
+3545(instead)X
+3797(of)X
+3889(the)X
+867 3048(traditional)N
+2 f F
+1227(O\()X
+1 f F
+1312(lg)X
+8 s F
+1374 3080(2)N
+10 s 2 f F
+1437 3048(threads\))N
+1 f F
+1704(.)X
+1774(This)X
+1946(paper)X
+2155(also)X
+2314(reports)X
+2567(on)X
+2677(the)X
+2805(performance)X
+3242(and)X
+3388(implementation)X
+3920(of)X
+867 3152(QuickThreads)N
+1353(and)X
+1500(describes)X
+1830(some)X
+2030(experiences)X
+2441(using)X
+2645(it)X
+2720(to)X
+2813(reimplement)X
+3248(and)X
+3394(port)X
+3553(existing)X
+3836(mul-)X
+867 3256(tiprocessor)N
+1239(threads)X
+1491(packages.)X
+3 f F
+555 3560(1.)N
+655(Introduction)X
+1 f F
+555 3692(Programming)N
+1024(constructs)X
+1378(usually)X
+1638(trade)X
+1828(between)X
+2125(\257exibility)X
+2464(and)X
+2609(overhead.)X
+2973(For)X
+3113(example,)X
+3434(parallel)X
+3704(constructs)X
+4057(such)X
+4232(as)X
+555 3796(vector)N
+787(instructions)X
+1191(have)X
+1374(low)X
+1525(scheduling)X
+1903(overhead)X
+2229(but)X
+2362(are)X
+2492(in\257exible;)X
+2847(processes)X
+3186(are)X
+3315(more)X
+3510(\257exible)X
+3780(but)X
+3912(have)X
+4094(higher)X
+555 3900(scheduling)N
+930(costs.)X
+1158(Likewise,)X
+1500(constructs)X
+1853(often)X
+2046(trade)X
+2235(between)X
+2530(portability)X
+2890(and)X
+3033(overhead.)X
+3395(Thus,)X
+3602(programs)X
+3932(are)X
+4058(decom-)X
+555 4004(posed)N
+764(so)X
+857(that)X
+999(each)X
+1169(division)X
+1448(uses)X
+1608(the)X
+1728(construct)X
+2044(that)X
+2186(provides)X
+2484(the)X
+2604(best)X
+2755(match)X
+2973(between)X
+3263(\257exibility)X
+3595(and)X
+3733(performance;)X
+4183(and)X
+555 4108(where)N
+779(portable)X
+1069(constructs)X
+1421(are)X
+1547(inadequate,)X
+1942(nonportable)X
+2352(constructs)X
+2704(are)X
+2830(used.)X
+3044(Conversely,)X
+3456(system)X
+3704(designers)X
+4033(strive)X
+4237(to)X
+555 4212(reduce)N
+792(the)X
+912(overhead)X
+1229(of)X
+1318(constructs)X
+1664(and)X
+1801(remove)X
+2063(machine)X
+2356(dependencies)X
+2810(from)X
+2987(their)X
+3155(interfaces)X
+3489(so)X
+3581(that)X
+3722(the)X
+3841(constructs)X
+4187(can)X
+555 4316(be)N
+651(used)X
+818(by)X
+918(the)X
+1036(widest)X
+1265(variety)X
+1508(of)X
+1595(clients.)X
+755 4448(This)N
+928(paper)X
+1138(discusses)X
+1467(two)X
+1618(techniques)X
+1992(for)X
+2117(building)X
+2414(fast)X
+2561(portable)X
+2855(threads)X
+3118(packages.)X
+3484(The)X
+3640(\256rst)X
+3795(idea)X
+3960(is)X
+4043(to)X
+4135(build)X
+555 4552(threads)N
+819(packages)X
+1146(around)X
+1401(a)X
+1468(thread)X
+1700(abstract)X
+1981(data)X
+2146(type)X
+2315(\(ADT\))X
+2565(that)X
+2716(has)X
+2854(a)X
+2921(machine-independent)X
+3643(interface)X
+3956(and)X
+4103(which)X
+555 4656(encapsulates)N
+982(only)X
+1145(the)X
+1264(most)X
+1440(machine-dependent)X
+2090(operations:)X
+2467(thread)X
+2689(initialization)X
+3114(and)X
+3250(execution.)X
+3622(The)X
+3767(second)X
+4010(idea)X
+4164(is)X
+4237(to)X
+555 4760(expose)N
+803(portable)X
+1091(details)X
+1325(of)X
+1417(the)X
+1540(threads)X
+1797(package)X
+2086(implementation)X
+2613(so)X
+2709(that)X
+2854(higher-level)X
+3267(thread)X
+3492(operations)X
+3850(can)X
+3986(be)X
+4086(optim-)X
+555 4864(ized)N
+713(to)X
+799(the)X
+921(thread)X
+1146(implementation.)X
+1712(For)X
+1846(example,)X
+2161(a)X
+2220(barrier)X
+2458(can)X
+2593(be)X
+2692(built)X
+2861(using)X
+3057(a)X
+3116(dedicated)X
+3447(run)X
+3577(queue,)X
+3812(so)X
+3906(that)X
+4049(one)X
+4188(test)X
+555 4968(checks)N
+794(both)X
+956(for)X
+1070(queue)X
+1282(empty)X
+1502(and)X
+1638(whether)X
+1917(all)X
+2017(threads)X
+2269(have)X
+2441(reached)X
+2712(the)X
+2830(barrier.)X
+755 5100(These)N
+970(techniques)X
+1336(are)X
+1458(discussed)X
+1788(in)X
+1873(the)X
+1994(context)X
+2253(of)X
+2 f F
+2343(QuickThreads)X
+1 f F
+2797(,)X
+2840(a)X
+2899(threads)X
+3154(package)X
+3441(core.)X
+3643(QuickThreads)X
+4121(is)X
+4197(not)X
+555 5204(a)N
+612(standalone)X
+976(threads)X
+1228(package.)X
+1552(Rather,)X
+1806(it)X
+1870(is)X
+1943(used)X
+2110(to)X
+2192(build)X
+2376(nonpreemptive)X
+2877(user-space)X
+3237(threads)X
+3489(packages.)X
+3844(QuickThreads)X
+555 5308(provides)N
+858(a)X
+921(portable)X
+1211(interface)X
+1520(to)X
+1609(machine-dependent)X
+2265(code)X
+2444(that)X
+2590(performs)X
+2906(thread)X
+3133(initialization)X
+3563(and)X
+3705(context-switching.)X
+555 5412(The)N
+712(higher-level)X
+1132(threads)X
+1396(package,)X
+1712(referred)X
+2000(to)X
+2094(as)X
+2193(the)X
+2 f F
+2323(client)X
+1 f F
+2501(,)X
+2553(provides)X
+2861(portable)X
+3156(code)X
+3339(to)X
+3432(implement)X
+3805(scheduling)X
+4183(and)X
+8 s 9 f F
+555 5492 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+755 5592(The)N
+872(author)X
+1053(may)X
+1181(be)X
+1259(reach)X
+1414(as)X
+7 s 7 f F
+1503(pardo@cs.washin)X
+2013(gton.edu)X
+8 s 1 f F
+2303(or)X
+2373(at)X
+2436(the)X
+2531(Department)X
+2849(of)X
+2919(Computer)X
+3192(Science)X
+3407(and)X
+3516(Engineering,)X
+3861(FR-35,)X
+4058(Universi-)X
+755 5664(ty)N
+828(of)X
+904(Washington,)X
+1252(Seattle,)X
+1465(Washington)X
+1797(98195.)X
+2012(As)X
+2106(of)X
+2182(1993,)X
+2349(the)X
+2450(code)X
+2593(described)X
+2860(in)X
+2933(this)X
+3049(document)X
+3324(is)X
+3390(available)X
+3643(via)X
+3743(anonymous)X
+4060(ftp)X
+4153(from)X
+7 s F
+755 5736(`)N
+7 f F
+774(ftp.cs.washingt)X
+1284(on.edu)X
+1 f F
+1488(')X
+8 s F
+1523(in)X
+7 s F
+1587(`)X
+7 f F
+1606(pub/qt-001.tar.)X
+2116(Z)X
+1 f F
+2150(')X
+8 s F
+2169(.)X
+
+%%Page: 2 2
+2 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2360 392(-)N
+2407(2)X
+2467(-)X
+555 680(synchronization.)N
+755 812(QuickThreads)N
+1235(has)X
+1367(two)X
+1512(goals.)X
+1746(One)X
+1905(is)X
+1983(to)X
+2070(make)X
+2268(it)X
+2336(easy)X
+2503(to)X
+2589(write)X
+2778(and)X
+2918(port)X
+3071(threads)X
+3327(packages.)X
+3686(QuickThreads)X
+4165(pro-)X
+555 916(vides)N
+749(machine-dependent)X
+1403(code)X
+1580(for)X
+1699(creating,)X
+2003(running)X
+2277(and)X
+2418(stopping)X
+2718(threads.)X
+3015(If)X
+3094(the)X
+3217(QuickThreads)X
+3697(client)X
+3900(avoids)X
+4134(other)X
+555 1020(machine)N
+849(dependencies,)X
+1324(porting)X
+1576(a)X
+1633(threads)X
+1886(package)X
+2171(built)X
+2338(with)X
+2501(QuickThreads)X
+2977(is)X
+3051(as)X
+3139(easy)X
+3303(as)X
+3391(recon\256guring)X
+3844(QuickThreads)X
+555 1124(and)N
+691(recompiling.)X
+755 1256(A)N
+834(second)X
+1078(goal)X
+1237(is)X
+1311(to)X
+1394(make)X
+1589(threads)X
+1842(packages)X
+2158(with)X
+2321(replaceable)X
+2709(components,)X
+3137(such)X
+3305(as)X
+3393(PRESTO)X
+3710([BLL88],)X
+4035(but)X
+4157(with)X
+555 1360(performance)N
+989(closer)X
+1208(to)X
+1297(that)X
+1444(of)X
+1538(hand-coded)X
+1940(packages)X
+2262(with)X
+2431(\256xed)X
+2618(policies,)X
+2914(such)X
+3088(as)X
+3182(FastThreads)X
+3600([And90].)X
+3938(To)X
+4053(achieve)X
+555 1464(this,)N
+724(QuickThreads)X
+1213(separates)X
+1542(the)X
+1674(notion)X
+1912(of)X
+2013(execution)X
+2359(\(starting)X
+2660(and)X
+2810(stopping)X
+3119(threads\))X
+3411(from)X
+3600(thread)X
+3834(allocation)X
+4183(and)X
+555 1568(scheduling.)N
+968(For)X
+1105(example,)X
+1423(changing)X
+1743(scheduling)X
+2116(policies)X
+2391(can)X
+2529(be)X
+2631(as)X
+2724(simple)X
+2963(as)X
+3056(using)X
+3255(a)X
+3317(different)X
+3619(function)X
+3911(pointer,)X
+4183(and)X
+555 1672(can)N
+695(be)X
+799(done)X
+983(ef\256ciently)X
+1336(at)X
+1421(runtime.)X
+1737(Thus,)X
+1944(portable)X
+2234(details)X
+2470(of)X
+2564(the)X
+2689(threads)X
+2948(package)X
+3239(are)X
+3365(not)X
+3494(\256xed,)X
+3701(but)X
+3830(can)X
+3969(instead)X
+4223(be)X
+555 1776(tuned)N
+753(to)X
+835(the)X
+953(needs)X
+1156(of)X
+1243(the)X
+1361(application.)X
+755 1908(QuickThreads)N
+1233(is)X
+1309(\257exible,)X
+1592(which)X
+1811(can)X
+1946(make)X
+2143(it)X
+2210(slower)X
+2447(than)X
+2608(hand-coded)X
+3006(packages)X
+3324(with)X
+3489(\256xed)X
+3672(policies.)X
+3984(However,)X
+555 2012(QuickThreads)N
+1043(is)X
+1129(minimalist,)X
+1523(so)X
+1627(operations)X
+1994(in)X
+2089(QuickThreads)X
+2577(are)X
+2709(often)X
+2907(close)X
+3105(to)X
+3200(the)X
+3331(cost)X
+3493(for)X
+3620(the)X
+3750(equivalent)X
+4116(hand-)X
+555 2116(crafted)N
+815(operations.)X
+1225(QuickThreads)X
+1716(is)X
+1805(even)X
+1993(closer)X
+2220(to)X
+2317(hand-crafted)X
+2759(alternatives)X
+3164(on)X
+3279(machines)X
+3617(with)X
+3794(many)X
+4007(registers,)X
+555 2220(where)N
+773(the)X
+892(cost)X
+1041(of)X
+1128(saving)X
+1357(and)X
+1493(restoring)X
+1798(registers)X
+2090(dominates.)X
+2479(QuickThreads)X
+2954(has)X
+3081(been)X
+3253(used)X
+3420(to)X
+3502(reimplement)X
+3927(two)X
+4067(threads)X
+555 2324(packages,)N
+890(and)X
+1026(in)X
+1108(both)X
+1270(cases)X
+1460(the)X
+1578(performance)X
+2005(was)X
+2150(unchanged.)X
+755 2484(The)N
+902(rest)X
+1040(of)X
+1129(this)X
+1266(document)X
+1604(is)X
+1679(organized)X
+2018(as)X
+2107(follows.)X
+2409(First,)X
+2597(Section)X
+2859(2)X
+2921(discusses)X
+3241(general)X
+3500(tradeoffs)X
+3808(between)X
+4098(thread)X
+555 2588(context)N
+816(switching)X
+1152(models)X
+1408(and)X
+1549(the)X
+1671(idea)X
+1829(of)X
+1920(reducing)X
+2225(the)X
+2347(threads)X
+2603(core)X
+2766(to)X
+2852(just)X
+2991(the)X
+3113(most)X
+3292(machine-dependent)X
+3945(operations.)X
+555 2692(Then,)N
+763(Section)X
+1026(3)X
+1089(describes)X
+1411(the)X
+1532(QuickThreads)X
+2010(programming)X
+2468(model)X
+2690(and)X
+2828(programmer's)X
+3305(interface.)X
+3649(Section)X
+3911(4)X
+3973(elaborates)X
+555 2796(by)N
+657(showing)X
+950(how)X
+1110(QuickThreads)X
+1587(can)X
+1721(be)X
+1819(used)X
+1988(to)X
+2072(implement)X
+2436(a)X
+2494(simple)X
+2729(threads)X
+2983(package.)X
+3308(Next,)X
+3505(Section)X
+3766(5)X
+3827(describes)X
+4147(vari-)X
+555 2900(ous)N
+688(QuickThreads)X
+1165(considerations)X
+1650(and)X
+1788(idioms,)X
+2047(including)X
+2371(how)X
+2531(it)X
+2597(is)X
+2672(used)X
+2840(on)X
+2941(multiprocessors)X
+3469(and)X
+3606(how)X
+3765(various)X
+4022(mechan-)X
+555 3004(isms)N
+723(such)X
+892(as)X
+981(critical)X
+1226(sections)X
+1506(and)X
+1644(barriers)X
+1912(are)X
+2033(implemented)X
+2473(ef\256ciently)X
+2820(on)X
+2922(top)X
+3046(of)X
+3135(QuickThreads.)X
+3652(Section)X
+3914(6)X
+3975(reports)X
+4219(on)X
+555 3108(the)N
+679(performance)X
+1112(and)X
+1253(implementation)X
+1780(of)X
+1872(QuickThreads.)X
+2392(Section)X
+2657(7)X
+2722(describes)X
+3046(and)X
+3187(compares)X
+3520(related)X
+3764(work.)X
+3994(Section)X
+4259(8)X
+555 3212(describes)N
+881(experiences)X
+1288(using)X
+1488(QuickThreads)X
+1970(to)X
+2059(reimplement)X
+2491(other)X
+2682(threads)X
+2940(packages.)X
+3301(Section)X
+3567(9)X
+3633(describes)X
+3958(limitations)X
+555 3316(of)N
+642(QuickThreads)X
+1117(and)X
+1253(considers)X
+1576(future)X
+1788(work.)X
+2013(Section)X
+2273(10)X
+2373(concludes.)X
+3 f F
+555 3524(2.)N
+655(Design)X
+906(Decisions)X
+1 f F
+555 3656(This)N
+718(section)X
+966(describes)X
+1286(three)X
+1468(key)X
+1605(design)X
+1835(ideas:)X
+2043(pushing)X
+2317(synchronization)X
+2850(into)X
+2994(the)X
+3112(client,)X
+3330(so)X
+3421(that)X
+3561(the)X
+3679(threads)X
+3931(core)X
+4090(imple-)X
+555 3760(ments)N
+777(only)X
+950(context)X
+1217(switching)X
+1559(operations;)X
+1945(giving)X
+2179(up)X
+2289(some)X
+2488(performance)X
+2925(in)X
+3017(order)X
+3217(to)X
+3309(achieve)X
+3585(\257exibility,)X
+3945(but)X
+4077(cutting)X
+555 3864(corners)N
+821(carefully)X
+1136(so)X
+1236(that)X
+1385(core)X
+1553(operations)X
+1916(are)X
+2044(close)X
+2238(to)X
+2329(the)X
+2455(cost)X
+2612(of)X
+2707(hand-crafted)X
+3142(alternatives;)X
+3562(and)X
+3706(supporting)X
+4076(variant)X
+555 3968(argument)N
+878(lists)X
+1026(\(varargs\).)X
+3 f F
+555 4176(2.1.)N
+715(Synchronization)X
+1 f F
+555 4308(Threads)N
+837(can)X
+972(avoid)X
+1173(explicit)X
+1436(dependencies)X
+1891(on)X
+1993(synchronization)X
+2527(idioms)X
+2766(by)X
+2868(pushing)X
+3143(all)X
+3245(synchronization)X
+3779(operations)X
+4135(up)X
+4237(to)X
+555 4412(the)N
+679(threads)X
+937(client,)X
+1161(which)X
+1383(then)X
+1547(provides)X
+1849(synchronization)X
+2386(that)X
+2531(is)X
+2609(tailored)X
+2879(to)X
+2966(the)X
+3089(client's)X
+3350(speci\256c)X
+3620(needs.)X
+3868(The)X
+4018(key)X
+4159(is)X
+4237(to)X
+555 4516(ensure)N
+785(that)X
+925(the)X
+1043(threads)X
+1295(interface)X
+1597(does)X
+1764(not)X
+1886(require)X
+2134(or)X
+2221(prohibit)X
+2494(locking)X
+2754(across)X
+2975(thread)X
+3196(context)X
+3452(switches.)X
+755 4648(In)N
+844(many)X
+1044(threads)X
+1297(packages,)X
+1633(a)X
+1690(thread)X
+1912(that)X
+2053(blocks)X
+2283(is)X
+2357(put)X
+2480(on)X
+2581(a)X
+2638(queue)X
+2851(\(dead,)X
+3071(runable,)X
+3353(blocked\),)X
+3675(and)X
+3812(a)X
+3869(new)X
+4024(thread)X
+4246(is)X
+555 4752(removed)N
+859(from)X
+1038(the)X
+1159(runable)X
+1423(queue)X
+1638(and)X
+1777(restarted.)X
+2117(Races)X
+2332(can)X
+2467(occur)X
+2669(on)X
+2772(multiprocessors)X
+3302(if)X
+3374(a)X
+3433(blocking)X
+3736(thread)X
+3960(is)X
+4036(put)X
+4161(on)X
+4263(a)X
+555 4856(queue)N
+768(and)X
+905(some)X
+1095(other)X
+1281(processor)X
+1610(resumes)X
+1894(the)X
+2013(thread)X
+2235(while)X
+2434(the)X
+2553(blocking)X
+2854(thread's)X
+3134(stack)X
+3320(is)X
+3394(still)X
+3533(being)X
+3731(used)X
+3898(to)X
+3980(select)X
+4183(and)X
+555 4960(start)N
+725(a)X
+793(new)X
+959(thread.)X
+1232(Races)X
+1456(can)X
+1600(even)X
+1784(happen)X
+2048(in)X
+2142(uniprocessors)X
+2615(if)X
+2695(an)X
+2802(exiting)X
+3055(thread)X
+3287(attempts)X
+3589(to)X
+3682(free)X
+3839(its)X
+3945(own)X
+4114(stack.)X
+555 5064(There)N
+763(are)X
+882(various)X
+1138(ways)X
+1323(to)X
+1405(avoid)X
+1603(the)X
+1721(race)X
+1876(conditions:)X
+3 f F
+555 5196(Scheduler)N
+919(Threads)X
+1 f F
+1203(:)X
+1247(Each)X
+1430(blocking)X
+1732(operation)X
+2057(returns)X
+2302(control)X
+2550(to)X
+2633(a)X
+2690(central)X
+2 f F
+2930(scheduler)X
+1 f F
+3263(thread,)X
+3505(as)X
+3593(in)X
+3676(PRESTO)X
+3994([BLL88].)X
+555 5300(Usually)N
+829(there)X
+1015(is)X
+1093(one)X
+1234(scheduler)X
+1566(thread)X
+1791(per)X
+1918(processor.)X
+2290(The)X
+2439(scheduler)X
+2771(thread)X
+2996(enqueues)X
+3319(the)X
+3441(blocked)X
+3719(thread.)X
+3984(Races)X
+4200(are)X
+555 5404(avoided)N
+834(because)X
+1114(a)X
+1175(blocking)X
+1480(thread)X
+1706(is)X
+1784(enqueued)X
+2117(only)X
+2283(once)X
+2459(the)X
+2581(thread)X
+2806(is)X
+2883(completely)X
+3263(blocked)X
+3541(and)X
+3681(it's)X
+3807(stack)X
+3996(is)X
+4073(frozen.)X
+555 5508(The)N
+701(scheduler)X
+1030(thread)X
+1252(is)X
+1326(never)X
+1526(queued)X
+1778(with)X
+1940(other)X
+2125(threads,)X
+2397(so)X
+2488(races)X
+2674(never)X
+2873(occur)X
+3072(during)X
+3301(switches)X
+3597(to)X
+3679(and)X
+3815(from)X
+3991(scheduler)X
+555 5612(threads.)N
+864(A)X
+959(disadvantage)X
+1415(of)X
+1519(scheduler)X
+1864(threads)X
+2133(is)X
+2223(that)X
+2380(each)X
+2564(blocking)X
+2880(operation)X
+3219(requires)X
+3514(a)X
+3586(context)X
+3858(switch)X
+4103(to)X
+4201(the)X
+555 5716(scheduler)N
+890(then)X
+1054(a)X
+1116(second)X
+1365(context)X
+1627(switch)X
+1862(to)X
+1950(the)X
+2074(next)X
+2238(thread.)X
+2505(Another)X
+2794(disadvantage)X
+3239(is)X
+3318(that)X
+3464(on)X
+3570(machines)X
+3899(without)X
+4169(per-)X
+555 5820(processor)N
+893(private)X
+1146(memory)X
+1443(it)X
+1517(is)X
+1600(dif\256cult)X
+1883(to)X
+1975(locate)X
+2197(per-processor)X
+2664(schedulers)X
+3032(cheaply)X
+3311([TSS88,)X
+3604(CLBL92])X
+3944(and)X
+4089(shared)X
+
+%%Page: 3 3
+3 p
+10 s 0 xH 0 xS 1 f F
+2360 392(-)N
+2407(3)X
+2467(-)X
+555 680(schedulers)N
+914(must)X
+1089(be)X
+1185(protected)X
+1504(with)X
+1666(locks.)X
+3 f F
+555 812(Locking)N
+1 f F
+834(:)X
+881(The)X
+1031(extra)X
+1217(context)X
+1478(switch)X
+1712(to)X
+1799(the)X
+1922(scheduler)X
+2255(can)X
+2392(be)X
+2493(avoided)X
+2772(if)X
+2846(the)X
+2969(blocking)X
+3274(thread)X
+3500(locks)X
+3693(the)X
+3815(queue)X
+4031(until)X
+4201(the)X
+555 916(old)N
+681(thread's)X
+964(stack)X
+1153(is)X
+1230(no)X
+1334(longer)X
+1563(being)X
+1765(used.)X
+1976(Some)X
+2182(implementations)X
+2739(hand-code)X
+3098(an)X
+3198(unlocking)X
+3542(operation)X
+3869(in)X
+3955(the)X
+4077(middle)X
+555 1020(of)N
+643(the)X
+762(context)X
+1019(switch.)X
+1289(Other)X
+1493(implementations)X
+2047(provide)X
+2313(portability)X
+2667(and)X
+2804(\257exibility)X
+3135(by)X
+3236(keeping)X
+3511(the)X
+3629(lock)X
+3787(operation)X
+4110(out)X
+4232(of)X
+555 1124(line,)N
+717(but)X
+841(at)X
+921(the)X
+1041(expense)X
+1322(of)X
+1411(longer)X
+1638(lock)X
+1798(holding)X
+2064(times.)X
+2299(When)X
+2513(the)X
+2632(context)X
+2889(switch)X
+3119(operation)X
+3443(relies)X
+3638(on)X
+3739(separate)X
+4024(lock)X
+4183(and)X
+555 1228(unlock)N
+797(operations,)X
+1175(it)X
+1243(becomes)X
+1548(hard)X
+1715(to)X
+1801(implement)X
+2167(nonblocking)X
+2591(synchronization)X
+3127([Her88],)X
+3426(which)X
+3646(uses)X
+3808(a)X
+3867(single)X
+4081(atomic)X
+555 1332(operation.)N
+3 f F
+555 1464(State)N
+760(in)X
+857(Registers)X
+1 f F
+1174(:)X
+1227(Stack)X
+1436(sharing)X
+1703(problems)X
+2032(can)X
+2175(also)X
+2335(be)X
+2442(avoided)X
+2727(if)X
+2807(all)X
+2918(transitional)X
+3309(state)X
+3486(\256ts)X
+3613(in)X
+3705(machine)X
+4007(registers.)X
+555 1568(Thus,)N
+757(some)X
+948(other)X
+1135(processor)X
+1465(can)X
+1599(start)X
+1759(running)X
+2030(the)X
+2150(old)X
+2274(thread)X
+2497(even)X
+2671(though)X
+2915(the)X
+3035(processor)X
+3364(that)X
+3505(blocked)X
+3780(it)X
+3845(is)X
+3919(still)X
+4059(starting)X
+555 1672(a)N
+613(new)X
+769(runable)X
+1032(thread.)X
+1295(A)X
+1375(disadvantage)X
+1816(of)X
+1905(this)X
+2042(approach)X
+2359(is)X
+2434(that)X
+2576(the)X
+2696(space)X
+2897(is)X
+2972(limited)X
+3220(to)X
+3304(machine)X
+3598(registers,)X
+3911(so)X
+4003(only)X
+4166(lim-)X
+555 1776(ited)N
+700(kinds)X
+898(of)X
+990(operations)X
+1349(can)X
+1486(be)X
+1587(performed.)X
+1987(For)X
+2123(example,)X
+2440(a)X
+2501(stackless)X
+2811(thread)X
+3037(cannot)X
+3276(perform)X
+3560(procedure)X
+3906(calls.)X
+4117(Some)X
+555 1880(architectures)N
+986([SPA92])X
+1286(and)X
+1422(operating)X
+1745(systems)X
+2018([BVML92])X
+2403(do)X
+2503(not)X
+2625(allow)X
+2823(a)X
+2879(thread)X
+3100(to)X
+3182(be)X
+3278(temporarily)X
+3672(stackless.)X
+3 f F
+555 2012(Preswitch)N
+1 f F
+894(:)X
+943(A)X
+1028(fourth)X
+1251(approach)X
+1573(is)X
+1653(to)X
+1742(block)X
+1947(the)X
+2071(old)X
+2199(thread,)X
+2446(switch)X
+2681(to)X
+2769(the)X
+2893(new)X
+3053(thread's)X
+3338(stack,)X
+3549(then)X
+3713(run)X
+3846(some)X
+4041(code)X
+4219(on)X
+555 2116(behalf)N
+777(of)X
+865(the)X
+984(old)X
+1107(thread,)X
+1349(but)X
+1472(using)X
+1666(the)X
+1785(new)X
+1940(thread's)X
+2220(stack.)X
+2446(Races)X
+2659(are)X
+2779(avoided)X
+3054(just)X
+3190(as)X
+3278(they)X
+3437(are)X
+3557(with)X
+3719(scheduler)X
+4047(threads,)X
+555 2220(but)N
+678(the)X
+797(extra)X
+979(context)X
+1236(switch)X
+1466(is)X
+1540(avoided.)X
+1855(There)X
+2064(are)X
+2184(two)X
+2325(innocent-seeming)X
+2916(disadvantages)X
+3387(that)X
+3528(have)X
+3701(important)X
+4032(implica-)X
+555 2324(tions.)N
+781(First,)X
+977(it)X
+1051(must)X
+1236(be)X
+1342(possible)X
+1634(to)X
+1726(perform)X
+2015(thread)X
+2246(operations)X
+2610(transparently)X
+3059(on)X
+3169(the)X
+3297(stack)X
+3492(of)X
+3589(the)X
+3717(new)X
+3881(thread.)X
+4152(That)X
+555 2428(means)N
+786(the)X
+910(new)X
+1070(thread)X
+1297(must)X
+2 f F
+1478(have)X
+1 f F
+1655(a)X
+1716(stack,)X
+1926(which)X
+2147(may)X
+2310(make)X
+2509(lazy)X
+2668(stack)X
+2858(allocation)X
+3199(dif\256cult.)X
+3517(Second,)X
+3798(a)X
+3859(thread)X
+4085(cannot)X
+555 2532(context)N
+811(switch)X
+1040(to)X
+1122(itself;)X
+1324(thus,)X
+1497(a)X
+1553(second)X
+1796(runable)X
+2057(thread)X
+2278(must)X
+2453(always)X
+2696(be)X
+2792(available.)X
+3 f F
+555 2664(Stateless)N
+870(Schedulers)X
+1 f F
+(:)S
+1286(A)X
+1365(\256fth)X
+1519(approach)X
+1835(is)X
+1909(to)X
+1992(create)X
+2206(\252lightweight\272)X
+2663(scheduler)X
+2992(threads)X
+3244(that)X
+3384(consist)X
+3626(of)X
+3713(stack)X
+3898(space)X
+4097(but)X
+4219(no)X
+555 2768(initialized)N
+901(state.)X
+1114(A)X
+1198(context)X
+1460(switch)X
+1695(saves)X
+1894(the)X
+2017(old)X
+2144(thread)X
+2370(state)X
+2542(then)X
+2705(switches)X
+3006(to)X
+3093(the)X
+3216(scheduler)X
+3549(stack,)X
+3759(but)X
+3886(no)X
+3991(scheduler)X
+555 2872(state)N
+729(is)X
+809(restored.)X
+1135(The)X
+1287(scheduler)X
+1622(stack)X
+1814(is)X
+1894(simply)X
+2138(used)X
+2312(as)X
+2406(a)X
+2469(place)X
+2666(to)X
+2755(call)X
+2898(a)X
+2961(function)X
+3255(on)X
+3362(behalf)X
+3590(of)X
+3684(the)X
+3809(thread)X
+4037(that)X
+4184(just)X
+555 2976(blocked.)N
+873(Likewise,)X
+1211(when)X
+1409(the)X
+1531(new)X
+1689(thread)X
+1913(is)X
+1989(started,)X
+2246(no)X
+2349(scheduler)X
+2680(state)X
+2850(is)X
+2926(saved.)X
+3172(Stateless)X
+3475(schedulers)X
+3837(are)X
+3959(faster)X
+4161(than)X
+555 3080(using)N
+750(heavyweight)X
+1182(scheduler)X
+1512(threads,)X
+1786(because)X
+2063(no)X
+2165(scheduler)X
+2495(state)X
+2664(is)X
+2739(saved)X
+2944(or)X
+3033(restored.)X
+3354(However,)X
+3691(it)X
+3757(may)X
+3917(still)X
+4058(be)X
+4156(hard)X
+555 3184(to)N
+639(locate)X
+853(schedulers)X
+1214(cheaply)X
+1486(on)X
+1588(machines)X
+1913(without)X
+2179(per-processor)X
+2639(private)X
+2884(memory.)X
+3213(Stateless)X
+3514(schedulers)X
+3874(are)X
+3994(similar)X
+4237(to)X
+555 3288(storing)N
+801(all)X
+905(transitional)X
+1289(state)X
+1460(in)X
+1546(registers,)X
+1862(insofar)X
+2108(as)X
+2198(scheduler)X
+2529(state)X
+2699(exists)X
+2904(only)X
+3069(during)X
+3301(the)X
+3422(context)X
+3681(switch;)X
+3935(lightweight)X
+555 3392(schedulers)N
+914(are)X
+1033(slightly)X
+1292(slower,)X
+1546(but)X
+1668(are)X
+1787(more)X
+1972(general)X
+2229(because)X
+2504(they)X
+2662(can)X
+2794(perform)X
+3073(function)X
+3360(calls.)X
+755 3524(QuickThreads)N
+1246(uses)X
+1420(preswitch.)X
+1808(The)X
+1969(interface)X
+2287(is)X
+2376(designed)X
+2697(so)X
+2804(that)X
+2960(QuickThreads)X
+3450(can)X
+3597(emulate)X
+3886(all)X
+4001(the)X
+4134(other)X
+555 3628(models)N
+806(except)X
+1036(storing)X
+1278(transitional)X
+1658(state)X
+1825(in)X
+1907(machine)X
+2199(registers.)X
+755 3760(Since)N
+956(locking)X
+1219(is)X
+1295(not)X
+1420(a)X
+1479(part)X
+1627(of)X
+1717(the)X
+1838(QuickThreads)X
+2316(context)X
+2575(switch)X
+2807(primitives,)X
+3173(threads)X
+3427(packages)X
+3744(built)X
+3912(with)X
+4076(Quick-)X
+555 3864(Threads)N
+841(must)X
+1023(perform)X
+1309(locking)X
+1576(at)X
+1661(the)X
+1786(\252ends\272)X
+2032(of)X
+2126(the)X
+2251(context)X
+2514(switch.)X
+2790(Typically)X
+3124(this)X
+3266(takes)X
+3458(teh)X
+3583(form)X
+3766(of)X
+3859(a)X
+3921(lock/unlock)X
+555 3968(operation)N
+878(before)X
+1104(the)X
+1222(context)X
+1478(switch)X
+1707(to)X
+1789(get)X
+1907(the)X
+2025(next)X
+2183(thread)X
+2404(and)X
+2540(another)X
+2801(afterwards)X
+3161(to)X
+3243(enque)X
+3455(the)X
+3573(blocked)X
+3847(thread.)X
+755 4100(Hard-coding)N
+1195(synchronization)X
+1741(might)X
+1961(improve)X
+2262(performance)X
+2703(but)X
+2839(is)X
+2926(avoided)X
+3213(for)X
+3340(the)X
+3471(reasons)X
+3745(discussed)X
+4085(above:)X
+555 4204(First,)N
+749(avoiding)X
+1057(embedded)X
+1415(synchronization)X
+1955(improves)X
+2281(portability.)X
+2682(Second,)X
+2966(it)X
+3038(keeps)X
+3249(the)X
+3375(programming)X
+3839(model)X
+4066(simple.)X
+555 4308(Third,)N
+781(synchronization)X
+1321(isn't)X
+1491(always)X
+1742(needed)X
+1998(\(e.g.,)X
+2189(for)X
+2311(a)X
+2374(new)X
+2535(thread)X
+2763(that)X
+2910(isn't)X
+3079(in)X
+3168(any)X
+3311(locked)X
+3552(queue\),)X
+3818(so)X
+3916(the)X
+4041(client)X
+4246(is)X
+555 4412(free)N
+703(to)X
+787(use)X
+916(just)X
+1053(the)X
+1173(minimum.)X
+1545(Fourth,)X
+1800(it)X
+1866(may)X
+2025(be)X
+2122(the)X
+2 f F
+2241(end)X
+2378(user)X
+1 f F
+2537(\(the)X
+2683(client)X
+2882(of)X
+2970(the)X
+3089(threads)X
+3342(package\))X
+3654(that)X
+3795(knows)X
+4025(the)X
+4144(most)X
+555 4516(about)N
+764(the)X
+893(basic)X
+1089(synchronization)X
+1632(operations)X
+1996(and)X
+2142(scheduling,)X
+2539(so)X
+2640(sometimes)X
+3012(even)X
+3194(the)X
+3322(threads)X
+3584(package)X
+3878(should)X
+4121(avoid)X
+555 4620(supplying)N
+892(them;)X
+1096(indeed,)X
+1351(this)X
+1487(is)X
+1561(a)X
+1618(central)X
+1858(part)X
+2004(of)X
+2092(the)X
+2211(motivation)X
+2578(for)X
+2693(PRESTO)X
+3011([BLL88])X
+3317(and)X
+3454(dynamic)X
+3751(processor)X
+4080(alloca-)X
+555 4724(tion)N
+705(policies)X
+980([MVZ90].)X
+1358(Fifth,)X
+1558(it)X
+1627(would)X
+1852(be)X
+1953(harder)X
+2184(to)X
+2271(perform)X
+2555(synchronization)X
+3092(inline)X
+3299(in)X
+3386(QuickThreads)X
+3866(than)X
+4029(in)X
+4116(hand-)X
+555 4828(coded)N
+771(systems,)X
+1068(and)X
+1208(an)X
+1308(out-of-line)X
+1675(call)X
+1814(would)X
+2037(make)X
+2234(context)X
+2493(switches)X
+2792(slower.)X
+3069(Thus,)X
+3272(QuickThreads)X
+3750(performs)X
+4063(context)X
+555 4932(switching)N
+886(without)X
+1150(any)X
+1286(locking.)X
+3 f F
+555 5140(2.2.)N
+715(Flexability)X
+1099(and)X
+1247(Simplicity)X
+1 f F
+555 5272(Flexibility)N
+917(can)X
+1059(be)X
+1165(achieved)X
+1481(several)X
+1739(ways:)X
+1956(by)X
+2066(using)X
+2269(powerful)X
+2589(operations,)X
+2973(by)X
+3083(using)X
+3286(customizable)X
+3739(operations,)X
+4123(or)X
+4219(by)X
+555 5376(stripping)N
+860(away)X
+1051(operations)X
+1406(that)X
+1547(limit)X
+1718(\257exibility.)X
+2089(Each,)X
+2290(however,)X
+2607(has)X
+2734(disadvantages)X
+3204([Kep93].)X
+3532(Powerful)X
+3846(operations)X
+4200(are)X
+555 5480(often)N
+754(slower.)X
+1042(Customizable)X
+1516(operations)X
+1884(are)X
+2017(sometimes)X
+2393(slower)X
+2641(and)X
+2791(existing)X
+3078(languages)X
+3433(often)X
+3631(do)X
+3744(not)X
+3879(support)X
+4152(\256ne-)X
+555 5584(grained)N
+819(customization.)X
+1331(Stripping)X
+1651(removes)X
+1946(operations)X
+2303(that)X
+2446(are)X
+2568(in\257exible,)X
+2913(but)X
+3038(which)X
+3257(also)X
+3409(serve)X
+3602(a)X
+3661(useful)X
+3880(purpose;)X
+4179(that)X
+555 5688(in)N
+639(turn)X
+790(forces)X
+1009(the)X
+1129(client)X
+1329(to)X
+1413(reimplement)X
+1840(the)X
+1960(functionality)X
+2391(of)X
+2479(the)X
+2598(stripped)X
+2877(operations.)X
+3272(QuickThreads)X
+3748(achieves)X
+4046(\257exibil-)X
+555 5792(ity)N
+659(by)X
+759(stripping)X
+1063(all)X
+1163(but)X
+1285(the)X
+1403(most)X
+1578(essential)X
+1874(operations,)X
+2248(leaving)X
+2504(just)X
+2639(thread)X
+2860(initialization)X
+3284(and)X
+3420(context)X
+3676(switch.)X
+
+%%Page: 4 4
+4 p
+10 s 0 xH 0 xS 1 f F
+2360 392(-)N
+2407(4)X
+2467(-)X
+755 680(QuickThreads)N
+1232(makes)X
+1459(several)X
+1709(key)X
+1847(decisions:)X
+2189(First,)X
+2377(the)X
+2497(QuickThreads)X
+2974(operations)X
+3329(\(initialize,)X
+3677(start,)X
+3856(stop\))X
+4037(are)X
+4157(sim-)X
+555 784(ple)N
+675(enough)X
+933(that)X
+1075(they)X
+1235(are)X
+1356(close)X
+1543(to)X
+1627(the)X
+1747(cost)X
+1898(of)X
+1987(\256xed)X
+2168(alternatives.)X
+2599(Second,)X
+2876(QuickThreads)X
+3352(does)X
+3520(not)X
+3643(depend)X
+3896(on)X
+3997(any)X
+4134(other)X
+555 888(routines.)N
+885(The)X
+1042(client)X
+1251(need)X
+1434(not)X
+1567(worry)X
+1790(about)X
+1999(QuickThreads)X
+2485(introducing)X
+2885(spurious)X
+3187(races)X
+3384(or)X
+3482(deadlock)X
+3803(by)X
+3914(calling)X
+4163(e.g.,)X
+555 992(memory)N
+849(allocation)X
+1192(routines)X
+1477(that)X
+1624(are)X
+1750(protected)X
+2076(by)X
+2183(locks.)X
+2419(Third,)X
+2643(although)X
+2949(the)X
+3073(client)X
+3277(is)X
+3356(made)X
+3556(responsible)X
+3947(for)X
+4067(storage)X
+555 1096(allocation,)N
+920(the)X
+1047(client)X
+1253(is)X
+1334(also)X
+1491(free)X
+1645(to)X
+1735(use)X
+1870(whatever)X
+2193(best)X
+2350(suits)X
+2524(the)X
+2650(client)X
+2856(and)X
+3000(end)X
+3144(user.)X
+3346(Fourth,)X
+3607(QuickThreads)X
+4090(imple-)X
+555 1200(ments)N
+783(no)X
+900(scheduling)X
+1284(policies)X
+1570(or)X
+1673(mechanisms;)X
+2127(clients)X
+2372(that)X
+2528(need)X
+2716(fancy)X
+2931(policies)X
+3216(\(e.g.,)X
+3415(priority\))X
+3718(can)X
+3866(provide)X
+4147(code)X
+555 1304(tailored)N
+829(to)X
+920(the)X
+1047(job,)X
+1198(while)X
+1405(those)X
+1603(that)X
+1752(need)X
+1933(less)X
+2081(\(FIFO,)X
+2329(LIFO\))X
+2562(or)X
+2657(none)X
+2841(\(coroutines\))X
+3257(can)X
+3397(provide)X
+3670(whatever)X
+3993(is)X
+4074(fastest.)X
+555 1408(Finally,)N
+831(QuickThreads)X
+1316(likewise)X
+1613(lacks)X
+1808(semaphores,)X
+2237(monitors,)X
+2570(nonblocking)X
+2999(I/O,)X
+3155(and)X
+3300(so)X
+3400(on.)X
+3549(Clients)X
+3804(that)X
+3953(need)X
+4134(these)X
+555 1512(operations)N
+909(can)X
+1041(implement)X
+1403(them,)X
+1603(while)X
+1801(those)X
+1990(that)X
+2130(don't)X
+2319(need)X
+2491(the)X
+2609(operations)X
+2963(do)X
+3063(not)X
+3185(pay)X
+3321(for)X
+3435(them.)X
+755 1644(QuickThreads)N
+1233(provides)X
+1532(only)X
+1697(very)X
+1863(basic)X
+2051(machine-dependent)X
+2703(operations)X
+3059(to)X
+3143(save)X
+3308(and)X
+3446(restore)X
+3687(thread)X
+3910(state.)X
+4119(Thus,)X
+555 1748(it)N
+622(rarely)X
+833(stands)X
+1056(in)X
+1141(the)X
+1262(way)X
+1419(of)X
+1509(the)X
+1630(rest)X
+1769(of)X
+1859(a)X
+1918(thread)X
+2141(package's)X
+2485(implementation.)X
+3049(The)X
+3196(chief)X
+3379(bottleneck)X
+3735(of)X
+3824(QuickThreads,)X
+555 1852(compared)N
+900(to)X
+990(other)X
+1183(threads)X
+1442(packages,)X
+1784(is)X
+1864(that)X
+2011(scheduling)X
+2385(and)X
+2528(locking)X
+2795(operations)X
+3156(are)X
+3282(supplied)X
+3580(by)X
+3687(the)X
+3812(client)X
+4017(and)X
+4160(exe-)X
+555 1956(cuted)N
+755(via)X
+879(an)X
+981(indirect)X
+1252(procedure)X
+1600(call.)X
+1782(QuickThreads)X
+2263(is)X
+2341(designed)X
+2651(to)X
+2738(minimize)X
+3065(the)X
+3188(number)X
+3458(of)X
+3550(excess)X
+3785(procedure)X
+4132(calls,)X
+555 2060(using)N
+759(two)X
+910(procedure)X
+1263(calls)X
+1441(on)X
+1552(each)X
+1731(context)X
+1998(switch.)X
+2278(Hand-coded)X
+2702(threads)X
+2965(packages)X
+3290(are)X
+3419(faster)X
+3628(because)X
+3913(locking)X
+4183(and)X
+555 2164(scheduling)N
+928(policies)X
+1203(are)X
+1328(\256xed,)X
+1534(typically)X
+1840(simple,)X
+2099(and)X
+2240(are)X
+2364(inlined)X
+2611(to)X
+2698(minimize)X
+3025(holding)X
+3294(times)X
+3492(and)X
+3633(avoid)X
+3836(procedure)X
+4183(call)X
+555 2268(overhead.)N
+3 f F
+555 2476(2.3.)N
+715(Variant)X
+1002(Argument)X
+1374(Lists)X
+1 f F
+555 2608(Thread)N
+809(creation)X
+1094(primitives)X
+1444(often)X
+1635(take)X
+1795(as)X
+1888(arguments)X
+2248(a)X
+2310(function)X
+2603(pointer)X
+2856(and)X
+2997(zero)X
+3161(or)X
+3253(more)X
+3443(arguments)X
+3802(to)X
+3889(the)X
+4012(function.)X
+555 2712(Although)N
+887(this)X
+1032(variant)X
+1285(argument)X
+1617(list)X
+1743(or)X
+2 f F
+1839(varargs)X
+1 f F
+2117(interface)X
+2428(is)X
+2510(convenient)X
+2891(for)X
+3014(the)X
+3141(end-user,)X
+3467(it)X
+3540(is)X
+3622(unreliable)X
+3972(and)X
+4117(slows)X
+555 2816(thread)N
+779(creation)X
+1061(and)X
+1200(startup.)X
+1481(The)X
+1629(problem)X
+1919(is)X
+1995(that)X
+2138(when)X
+2335(the)X
+2455(thread)X
+2678(creation)X
+2959(function)X
+3248(is)X
+3323(called,)X
+3557(it)X
+3623(must)X
+3800(have)X
+3974(some)X
+4165(way)X
+555 2920(of)N
+653(discovering)X
+1058(and)X
+1205(setting)X
+1449(aside)X
+1645(the)X
+1774(parameters.)X
+2198(Doing)X
+2429(so)X
+2531(is)X
+2615(hard.)X
+2829(For)X
+2971(example,)X
+7 f F
+3294(printf)X
+1 f F
+3613(discovers)X
+3947(the)X
+4075(correct)X
+555 3024(number)N
+827(of)X
+921(arguments)X
+1282(by)X
+1389(examining)X
+1754(the)X
+1879(\256rst)X
+2030(argument;)X
+2382(the)X
+2507(threads)X
+2766(package)X
+3057(has)X
+3191(no)X
+3298(equivalent)X
+3659(way)X
+3819(of)X
+3912(determining)X
+555 3128(the)N
+673(number)X
+938(of)X
+1025(arguments.)X
+1419(Appendix)X
+1755(A)X
+1833(discusses)X
+2151(the)X
+2269(varargs)X
+2526(problems)X
+2844(in)X
+2926(more)X
+3111(detail.)X
+755 3260(From)N
+949(the)X
+1068(view)X
+1245(of)X
+1333(the)X
+1452(threads)X
+1705(package,)X
+2010(a)X
+2066(better)X
+2269(interface)X
+2571(passes)X
+2796(only)X
+2958(one)X
+3094(argument,)X
+3437(a)X
+3493(pointer)X
+3740(to)X
+3822(a)X
+3878(structure)X
+4179(that)X
+555 3364(contains)N
+845(the)X
+966(actual)X
+1181(arguments.)X
+1578(\(It)X
+1677(may)X
+1838(be)X
+1937(necessary)X
+2272(to)X
+2356(copy)X
+2534(the)X
+2654(structure)X
+2957(to)X
+3041(thread-speci\256c)X
+3536(storage.\))X
+3837(This)X
+4001(is)X
+4076(the)X
+4196(ap-)X
+555 3468(proach)N
+805(used)X
+983(by,)X
+1114(e.g.,)X
+1281(NewThreads)X
+1723([FM92].)X
+2043(However,)X
+2389(many)X
+2598(packages)X
+2924(provide)X
+3200(a)X
+3267(varargs)X
+3534(interface,)X
+3866(so)X
+3967(building)X
+4263(a)X
+555 3572(threads)N
+807(toolkit)X
+1035(that)X
+1175(supports)X
+1466(only)X
+1628(single-argument)X
+2169(thread)X
+2390(functions)X
+2708(is)X
+2781(unacceptable.)X
+755 3704(Although)N
+1087(varargs)X
+1353(can)X
+1494(implement)X
+1865(a)X
+1930(single-argument)X
+2480(interface,)X
+2811(doing)X
+3022(so)X
+3122(typically)X
+3431(makes)X
+3665(thread)X
+3895(initialization)X
+555 3808(and)N
+702(invocation)X
+1071(two)X
+1222(times)X
+1426(slower.)X
+1711(Therefore,)X
+2080(two)X
+2230(interfaces)X
+2573(are)X
+2702(provided:)X
+3039(one)X
+3185(for)X
+3309(varargs,)X
+3596(one)X
+3742(for)X
+3866(the)X
+3994(fast)X
+4140(case.)X
+555 3912(\(The)N
+735(difference)X
+1090(is)X
+1171(only)X
+1341(visible)X
+1582(in)X
+1672(thread)X
+1901(initialization;)X
+2354(single-argument)X
+2902(and)X
+3045(varargs)X
+3309(threads)X
+3568(are)X
+3694(otherwise)X
+4033(indistin-)X
+555 4016(guishable)N
+885(and)X
+1024(may)X
+1185(be)X
+1284(mixed)X
+1507(freely)X
+1718(on)X
+1821(run)X
+1951(queues,)X
+2217(etc.\))X
+2380(However,)X
+2717(using)X
+2912(two)X
+3054(interfaces)X
+3389(makes)X
+3616(QuickThreads)X
+4093(harder)X
+555 4120(to)N
+637(retarget)X
+903(and)X
+1039(understand.)X
+1451(In)X
+1538(this)X
+1673(case,)X
+1852(the)X
+1970(cost)X
+2119(is)X
+2192(deemed)X
+2462(worthwhile)X
+2847(because)X
+3122(varargs)X
+3379(is)X
+3452(typically)X
+3752(so)X
+3843(much)X
+4041(slower.)X
+3 f F
+555 4328(3.)N
+655(QuickThreads)X
+1167(Programming)X
+555 4536(3.1.)N
+715(QuickThreads)X
+1227(Programming)X
+1728(Model)X
+1 f F
+555 4668(QuickThreads)N
+1042(does)X
+1221(not)X
+1355(perform)X
+1646(any)X
+1794(allocation.)X
+2182(It)X
+2263(relies)X
+2469(on)X
+2581(the)X
+2710(client)X
+2919(threads)X
+3182(package)X
+3477(to)X
+3570(allocate)X
+3851(stacks,)X
+4098(thread)X
+555 4772(queues,)N
+822(and)X
+962(other)X
+1151(auxiliary)X
+1460(data)X
+1618(structures.)X
+1994(Likewise,)X
+2332(QuickThreads)X
+2811(does)X
+2981(not)X
+3106(manipulate)X
+3485(any)X
+3624(run)X
+3754(queues)X
+4000(or)X
+4090(imple-)X
+555 4876(ment)N
+745(semaphores,)X
+1174(monitors,)X
+1508(and)X
+1654(so)X
+1755(on.)X
+1905(Instead,)X
+2187(it)X
+2261(provides)X
+2567(a)X
+2633(simple)X
+2876(mechanism)X
+3271(that)X
+3421(performs)X
+3740(a)X
+3805(context)X
+4070(switch,)X
+555 4980(then)N
+723(invokes)X
+1002(a)X
+1068(client)X
+1276(function)X
+1573(on)X
+1683(behalf)X
+1913(of)X
+2009(the)X
+2136(halted)X
+2361(thread.)X
+2631(The)X
+2785(client)X
+2992(function)X
+3288(can)X
+3429(then)X
+3596(\252clean)X
+3831(up\272)X
+3976(the)X
+4103(halted)X
+555 5084(thread,)N
+796(putting)X
+1042(it)X
+1106(on)X
+1206(an)X
+1302(appropriate)X
+1688(queue,)X
+1920(deallocating)X
+2332(it,)X
+2416(etc.)X
+755 5216(A)N
+837(thread)X
+1062(may)X
+1224(be)X
+1324(in)X
+1410(various)X
+1669(states:)X
+2 f F
+1892(uninitialized)X
+1 f F
+2291(;)X
+2 f F
+2336(initialized)X
+1 f F
+2678(and)X
+2817(ready)X
+3019(to)X
+3104(run,)X
+3254(but)X
+3379(not)X
+3504(yet)X
+3625(started;)X
+2 f F
+3884(running)X
+1 f F
+4160(on)X
+4263(a)X
+555 5320(processor;)N
+2 f F
+909(blocked)X
+1 f F
+1159(,)X
+1203(and)X
+1343(waiting)X
+1607(to)X
+1693(be)X
+1793(reawakened;)X
+2224(or)X
+2 f F
+2315(aborted)X
+1 f F
+2588(\(or)X
+2 f F
+2705(dead)X
+1 f F
+2861(\),)X
+2931(in)X
+3016(which)X
+3235(case)X
+3397(the)X
+3518(thread)X
+3742(can)X
+3877(never)X
+4079(be)X
+4178(res-)X
+555 5424(tarted.)N
+802(Initialized)X
+1151(threads)X
+1407(are)X
+1530(started)X
+1768(the)X
+1890(same)X
+2078(way)X
+2235(that)X
+2378(blocked)X
+2655(threads)X
+2910(are)X
+3032(restarted;)X
+3354(when)X
+3551(the)X
+3672(distinction)X
+4032(is)X
+4108(unim-)X
+555 5528(portant,)N
+822(they)X
+980(are)X
+1099(both)X
+1261(considered)X
+2 f F
+1629(runable)X
+1 f F
+1878(.)X
+755 5660(QuickThreads)N
+1234(performs)X
+1548(all)X
+1652(thread)X
+1877(manipulation)X
+2323(using)X
+2520(the)X
+2642(thread's)X
+2925(stack)X
+3114(pointer.)X
+3405(A)X
+3487(client)X
+3689(creates)X
+3936(a)X
+3995(thread)X
+4219(by)X
+555 5764(allocating)N
+898(a)X
+960(stack)X
+1151(region.)X
+1422(The)X
+1573(machine)X
+1871(architecture)X
+2277(determines)X
+2655(whether)X
+2940(the)X
+3064(stack)X
+3255(grows)X
+3477(up)X
+3583(or)X
+3676(down,)X
+3900(so)X
+3997(the)X
+4121(client)X
+
+%%Page: 5 5
+5 p
+10 s 0 xH 0 xS 1 f F
+2360 392(-)N
+2407(5)X
+2467(-)X
+555 680(calls)N
+727(a)X
+788(QuickThreads)X
+1268(routine,)X
+1540(passing)X
+1805(in)X
+1892(the)X
+2014(address)X
+2279(and)X
+2419(size)X
+2568(of)X
+2659(the)X
+2781(stack)X
+2970(region)X
+3199(and)X
+3339(getting)X
+3585(back)X
+3761(the)X
+3883(stack)X
+4072(pointer)X
+555 784(of)N
+652(the)X
+779(uninitialized)X
+1208(thread.)X
+1478(The)X
+1632(client)X
+1839(initializes)X
+2179(a)X
+2244(thread)X
+2474(by)X
+2583(calling)X
+2830(a)X
+2895(QuickThreads)X
+3379(initialization)X
+3812(primitive.)X
+4174(The)X
+555 888(primitive)N
+868(initializes)X
+1199(the)X
+1317(stack)X
+1502(with)X
+1664(functions)X
+1982(and)X
+2118(arguments)X
+2472(that)X
+2612(will)X
+2756(be)X
+2852(used)X
+3019(once)X
+3191(the)X
+3309(thread)X
+3530(is)X
+3603(started.)X
+755 1020(An)N
+876(initialized)X
+1219(thread)X
+1442(is)X
+1517(indistinguishable)X
+2085(from)X
+2263(a)X
+2321(suspended)X
+2677(thread.)X
+2940(Thus,)X
+3142(the)X
+3262(initialized)X
+3604(thread)X
+3827(may)X
+3987(be)X
+4085(started)X
+555 1124(by)N
+655(passing)X
+915(the)X
+1033(initialized)X
+1373(thread's)X
+1652(stack)X
+1837(pointer)X
+2084(to)X
+2166(the)X
+2284(QuickThreads)X
+2759(context)X
+3015(switching)X
+3346(primitive.)X
+755 1256(The)N
+903(QuickThreads)X
+1381(context)X
+1640(switching)X
+1974(primitive)X
+2290(is)X
+2366(called)X
+2580(with)X
+2744(the)X
+2864(stack)X
+3051(pointer)X
+3300(of)X
+3389(the)X
+3509(next)X
+3669(thread)X
+3892(to)X
+3976(run,)X
+4125(and)X
+4263(a)X
+2 f F
+555 1360(helper)N
+1 f F
+786(function)X
+1079(and)X
+1221(arguments)X
+1581(used)X
+1754(to)X
+1842(clean)X
+2038(up)X
+2144(the)X
+2268(old)X
+2396(thread)X
+2622(once)X
+2799(the)X
+2922(context)X
+3183(switch)X
+3417(has)X
+3549(completed.)X
+3948(The)X
+4098(helper)X
+555 1464(function)N
+847(is)X
+925(a)X
+986(parameter)X
+1333(to)X
+1420(the)X
+1543(QuickThreads)X
+2023(context)X
+2284(switch)X
+2518(primitive)X
+2836(\(called)X
+7 f F
+3080(qt_cswap)X
+1 f F
+3489(in)X
+3576(Figure)X
+3810(1\),)X
+3922(so)X
+4018(it)X
+4087(can)X
+4223(be)X
+555 1568(changed)N
+843(dynamically)X
+1259(and)X
+1395(can)X
+1527(be)X
+1623(different)X
+1920(for)X
+2034(each)X
+2202(context)X
+2458(switch)X
+2687(site)X
+2818(and)X
+2954(for)X
+3068(each)X
+3236(thread.)X
+8 s 7 f F
+843 1704(client_cswap\(\))N
+843 1792({)N
+919 1880(new)N
+1071(=)X
+1147(schedule)X
+1489(\(runq\))X
+919 1968(qt_cswap)N
+1261(\(new,)X
+1489(runq,)X
+1717(helper\))X
+919 2056(runs_when_restart)N
+1565(ed\(\))X
+843 2144(})N
+843 2320(helper)N
+1109(\(old,)X
+1337(runq\))X
+843 2408({)N
+919 2496(deschedule)N
+1337(\(old,)X
+1565(runq\))X
+843 2584(})N
+9 s 3 f F
+1783 2736(Figure)N
+2005(1.)X
+1 f F
+2095(A)X
+2165(context)X
+2395(switch)X
+2601(implementation.)X
+10 s F
+755 2972(The)N
+908(context)X
+1172(switch)X
+1409(primitive)X
+1730(works)X
+1954(as)X
+2049(follows.)X
+2357(First)X
+2531(it)X
+2603(saves)X
+2804(the)X
+2929(register)X
+3197(values)X
+3429(of)X
+3523(the)X
+3648(old)X
+3777(thread)X
+4005(on)X
+4112(to)X
+4201(the)X
+555 3076(stack)N
+743(of)X
+833(the)X
+954(old)X
+1079(thread,)X
+1323(adjusting)X
+1639(the)X
+1759(stack)X
+1946(pointer)X
+2195(as)X
+2284(needed.)X
+2574(It)X
+2645(then)X
+2805(switches)X
+3103(to)X
+3187(the)X
+3307(stack)X
+3494(of)X
+3583(the)X
+3703(new)X
+3859(thread;)X
+4104(at)X
+4184(this)X
+555 3180(point)N
+749(the)X
+877(old)X
+1009(thread)X
+1240(has)X
+1377(been)X
+1559(suspended.)X
+1963(Before)X
+2211(the)X
+2338(new)X
+2501(thread)X
+2731(is)X
+2813(restarted,)X
+3139(the)X
+3266(context)X
+3531(switch)X
+3769(routine)X
+4025(calls)X
+4201(the)X
+555 3284(client-supplied)N
+1057(helper)X
+1284(function.)X
+1617(The)X
+1768(helper)X
+1995(function)X
+2288(is)X
+2367(passed)X
+2607(the)X
+2731(stack)X
+2922(pointer)X
+3175(of)X
+3268(the)X
+3391(old)X
+3518(thread)X
+3744(and)X
+3885(certain)X
+4129(argu-)X
+555 3388(ments)N
+769(that)X
+912(were)X
+1092(passed)X
+1329(by)X
+1432(the)X
+1553(old)X
+1677(thread)X
+1900(as)X
+1989(arguments)X
+2345(to)X
+2429(the)X
+2549(context)X
+2807(switch)X
+3038(primitive.)X
+3393(Often,)X
+3618(one)X
+3756(of)X
+3845(the)X
+3965(arguments)X
+555 3492(is)N
+629(a)X
+686(queue,)X
+919(and)X
+1056(the)X
+1175(helper)X
+1397(function)X
+1685(puts)X
+1839(the)X
+1958(blocked)X
+2233(thread)X
+2455(in)X
+2538(that)X
+2679(queue.)X
+2932(When)X
+3145(the)X
+3264(helper)X
+3486(function)X
+3774(returns,)X
+4038(the)X
+4156(con-)X
+555 3596(text)N
+695(switch)X
+924(routine)X
+1171(restores)X
+1441(the)X
+1559(registers)X
+1851(of)X
+1938(the)X
+2056(new)X
+2210(thread)X
+2431(and)X
+2567(restarts)X
+2819(it.)X
+755 3728(Figure)N
+989(2)X
+1054(shows)X
+1279(a)X
+1340(context)X
+1600(switch)X
+1833(in)X
+1919(progress.)X
+2255(The)X
+2404(old)X
+2530(thread)X
+2755(has)X
+2886(been)X
+3062(suspended)X
+3420(and)X
+3560(control)X
+3811(is)X
+3888(now)X
+4050(running)X
+555 3832(on)N
+657(the)X
+777(new)X
+933(thread's)X
+1214(stack.)X
+1441(However,)X
+1778(the)X
+1898(new)X
+2054(thread)X
+2277(has)X
+2406(not)X
+2530(yet)X
+2650(been)X
+2824(resumed;)X
+3140(a)X
+3197(helper)X
+3419(is)X
+3493(executing)X
+3826(on)X
+3927(the)X
+4046(stack)X
+4232(of)X
+555 3936(the)N
+682(new)X
+845(thread)X
+1075(\(stacks)X
+1327(grow)X
+1521(up)X
+1630(in)X
+1721(this)X
+1865(\256gure\).)X
+2148(When)X
+2369(the)X
+2496(helper)X
+2725(returns,)X
+2996(the)X
+3122(new)X
+3284(thread)X
+3513(will)X
+3665(be)X
+3769(resumed.)X
+4109(Later,)X
+555 4040(when)N
+7 f F
+749(old)X
+1 f F
+913(is)X
+986(resumed,)X
+1298(a)X
+1354(helper)X
+1575(will)X
+1719(run)X
+1846(on)X
+1946(it's)X
+2068(stack.)X
+8 s 7 f F
+1603 4144(|)N
+1907(|)X
+1603 4200(|)N
+1755(:)X
+1907(|)X
+1603 4256(|)N
+1755(:)X
+1907(|)X
+919 4312(|)N
+1223(|)X
+1603(+-------+)X
+1983(<-)X
+2097(sp)X
+919 4368(|)N
+1071(:)X
+1223(|)X
+1603(|)X
+1679(helper|)X
+919 4424(|)N
+1071(:)X
+1223(|)X
+1603(|)X
+1717(call)X
+1907(|)X
+919 4480(+-------+)N
+1299(<-)X
+1413(old)X
+1603(|)X
+1679(frame)X
+1907(|)X
+919 4536(|)N
+995(saved)X
+1223(|)X
+1603(|)X
+1907(|)X
+919 4592(|)N
+995(regs.)X
+1223(|)X
+1603(+-------+)X
+1983(<-)X
+2097(new)X
+919 4648(+-------+)N
+1603(|)X
+1679(saved)X
+1907(|)X
+919 4704(|)N
+1223(|)X
+1603(|)X
+1679(regs.)X
+1907(|)X
+919 4760(|)N
+1223(|)X
+1603(+-------+)X
+919 4816(|)N
+1223(|)X
+1603(|)X
+1907(|)X
+919 4872(|)N
+1223(|)X
+1603(|)X
+1907(|)X
+919 4928(|)N
+1223(|)X
+1603(|)X
+1907(|)X
+919 4984(|)N
+1223(|)X
+1603(|)X
+1907(|)X
+919 5040(+-------+)N
+1603(+-------+)X
+995 5096(old's)N
+1679(new's)X
+995 5152(stack)N
+1679(stack)X
+9 s 3 f F
+1847 5304(Figure)N
+2069(2.)X
+1 f F
+2159(Stacks)X
+2365(during)X
+2571(context)X
+2801(switch.)X
+10 s F
+755 5540(Threads)N
+1046(are)X
+1177(generally)X
+1508(said)X
+1669(to)X
+1763(be)X
+1871(in)X
+1965(some)X
+2166(kind)X
+2340(of)X
+2439(queue)X
+2663(except)X
+2905(when)X
+3111(they)X
+3280(are)X
+3410(running.)X
+3730(However,)X
+4076(Quick-)X
+555 5644(Threads)N
+847(allows)X
+1089(use)X
+1229(of)X
+1328(arbitrary)X
+1637(data)X
+1803(structures)X
+2147(\(arrays,)X
+2423(graphs,)X
+2689(\256xed)X
+2881(memory)X
+3180(locations\))X
+3528(and)X
+3676(threads)X
+3940(can)X
+4084(be)X
+4192(run)X
+555 5748(while)N
+753(they)X
+911(are)X
+1030(still)X
+1169(embedded)X
+1519(in)X
+1601(a)X
+1657(data)X
+1811(structure.)X
+
+%%Page: 6 6
+6 p
+10 s 0 xH 0 xS 1 f F
+2360 392(-)N
+2407(6)X
+2467(-)X
+3 f F
+555 680(3.2.)N
+715(Programming)X
+1216(Interface)X
+1 f F
+555 812(QuickThreads)N
+1035(is)X
+1113(written)X
+1365(in)X
+1452(C)X
+1530(and)X
+1671(assembler)X
+2017(and)X
+2158(is)X
+2236(designed)X
+2546(to)X
+2633(work)X
+2823(with)X
+2990(threads)X
+3246(packages)X
+3565(written)X
+3816(in)X
+3902(C.)X
+4019(Modules)X
+555 916(that)N
+695(use)X
+822(QuickThreads)X
+1297(primitives)X
+1641(must)X
+1816(include)X
+2072(the)X
+2190(QuickThreads)X
+2665(header)X
+2900(\256le:)X
+8 s 7 f F
+843 1052(#include)N
+1185(<qt.h>)X
+10 s 1 f F
+755 1232(Typically)N
+1089(the)X
+2 f F
+1214(include)X
+1477(path)X
+1 f F
+1646(option)X
+1877(is)X
+1957(used)X
+2131(to)X
+2220(tell)X
+2349(the)X
+2474(C)X
+2554(compiler)X
+2866(where)X
+3090(to)X
+3179(locate)X
+3398(the)X
+3523(header.)X
+3804(The)X
+3955(executable)X
+555 1336(must)N
+737(be)X
+840(linked)X
+1067(with)X
+1236(the)X
+1361(QuickThreads)X
+1843(runtime)X
+2119(library.)X
+2400(The)X
+2552(command)X
+2895(below)X
+3118(is)X
+3197(typical,)X
+3461(but)X
+3589(varies)X
+3807(from)X
+3989(system)X
+4237(to)X
+555 1440(system.)N
+8 s 7 f F
+843 1576(cc)N
+957(-I/usr/local/incl)X
+1603(ude)X
+1755(-L/usr/local/lib)X
+2401(...)X
+2553(-lqt)X
+10 s 1 f F
+755 1756(The)N
+900(basic)X
+1085(interface)X
+1387(consists)X
+1660(of)X
+1747(routines)X
+2025(\(either)X
+2255(macros)X
+2507(or)X
+2594(functions\))X
+2939(to)X
+3021(create,)X
+3254(initialize,)X
+3574(run,)X
+3721(and)X
+3857(stop)X
+4010(threads.)X
+3 f F
+555 1964(3.2.1.)N
+775(Thread)X
+1048(Creation)X
+8 s 7 f F
+843 2128(int)N
+995(QT_STKALIGN)X
+843 2216(qt_t)N
+1033(*QT_SP)X
+1299(\(void)X
+1527(*sto,)X
+1755(int)X
+1907(size\))X
+10 s 1 f F
+555 2368(The)N
+705(QuickThreads)X
+1185(client)X
+1388(allocates)X
+1693(stacks.)X
+1953(QuickThreads)X
+2432(then)X
+2594(manipulates)X
+3005(threads)X
+3261(using)X
+3458(the)X
+3580(thread's)X
+3863(stack)X
+4052(pointer.)X
+555 2472(Stacks)N
+792(grow)X
+985(up)X
+1093(on)X
+1201(some)X
+1398(machines)X
+1729(and)X
+1873(down)X
+2079(on)X
+2186(others,)X
+2429(so)X
+2527(the)X
+2652(thread's)X
+2938(stack)X
+3130(pointer)X
+3384(is)X
+3464(discovered)X
+3839(using)X
+7 f F
+4039(QT_SP)X
+1 f F
+(,)S
+555 2576(which)N
+781(takes)X
+976(a)X
+1042(pointer)X
+1299(to)X
+1391(the)X
+1519(client-allocated)X
+2044(stack)X
+2239(and)X
+2385(the)X
+2513(size)X
+2668(of)X
+2765(the)X
+2893(stack,)X
+3107(and)X
+3252(returns)X
+3504(the)X
+3631(thread's)X
+3919(initial)X
+4134(stack)X
+555 2680(pointer.)N
+844(Different)X
+1160(machines)X
+1484(have)X
+1657(different)X
+1955(alignment)X
+2296(requirements,)X
+2756(so)X
+2848(the)X
+2967(storage)X
+7 f F
+3220(sto)X
+1 f F
+3385(must)X
+3561(be)X
+3658(aligned)X
+3915(on)X
+4016(at)X
+4095(least)X
+4263(a)X
+7 f F
+555 2784(QT_STKALIGN)N
+1 f F
+(-byte)S
+1279(boundary,)X
+1633(where)X
+7 f F
+1861(QT_STKALIGN)X
+1 f F
+2420(is)X
+2504(a)X
+2571(power)X
+2803(of)X
+2901(2.)X
+3012(Likewise,)X
+7 f F
+3357(size)X
+1 f F
+3579(must)X
+3764(be)X
+3870(a)X
+3936(multiple)X
+4232(of)X
+7 f F
+555 2888(QT_STKALIGN)N
+1 f F
+(.)S
+755 3020(This)N
+918(interface)X
+1221(fails)X
+1379(to)X
+1461(be)X
+1557(machine-independent)X
+2268(in)X
+2350(an)X
+2446(important)X
+2777(way:)X
+2953(there)X
+3134(is)X
+3207(no)X
+3307(easy)X
+3470(way)X
+3624(to)X
+3706(get)X
+3824(QuickThreads,)X
+555 3124(the)N
+678(client,)X
+901(and)X
+1042(the)X
+1165(end)X
+1306(user)X
+1465(of)X
+1557(the)X
+1680(threads)X
+1937(package)X
+2225(to)X
+2311(cooperate)X
+2648(to)X
+2734(estimate)X
+3025(the)X
+3147(stack)X
+3336(size.)X
+8 s F
+3481 3084(1)N
+10 s F
+3537 3124(The)N
+3686(usual)X
+3879(solution)X
+4160(is)X
+4237(to)X
+555 3228(overestimate)N
+985(the)X
+1103(stack)X
+1288(size.)X
+3 f F
+555 3436(3.2.2.)N
+775(Single-Argument)X
+1382(Thread)X
+1655(Initialization)X
+8 s 7 f F
+843 3600(typedef)N
+1147(void)X
+1337(*\(qt_userf_t\)\(voi)X
+1983(d)X
+2059(*u\);)X
+843 3688(typedef)N
+1147(void)X
+1337(\(qt_only_t\)\(void)X
+1983(*u,)X
+2135(void)X
+2325(*t,)X
+2477(qt_userf_t)X
+2895(*userf\);)X
+843 3864(qt_t)N
+1033(*QT_ARGS)X
+1375(\(qt_t)X
+1603(*sp,)X
+1793(void)X
+1983(*u,)X
+2135(void)X
+2325(*t,)X
+1413 3952(qt_userf_t)N
+1831(*userf,)X
+2135(qt_only_t)X
+2515(*only\);)X
+10 s 1 f F
+555 4104(A)N
+635(thread)X
+858(is)X
+933(initialized)X
+1275(by)X
+1377(saving)X
+1608(state)X
+1777(on)X
+1879(the)X
+1999(thread's)X
+2279(stack.)X
+2505(The)X
+2651(state)X
+2819(is)X
+2893(saved)X
+3097(in)X
+3180(a)X
+3237(way)X
+3392(that)X
+3533(makes)X
+3759(it)X
+3824(appear)X
+4060(that)X
+4201(the)X
+555 4208(thread)N
+779(has)X
+909(been)X
+1084(suspended)X
+1441(just)X
+1579(as)X
+1669(it)X
+1736(is)X
+1812(about)X
+2013(to)X
+2098(call)X
+2237(a)X
+2296(client-supplied)X
+2795(function.)X
+3125(The)X
+3272(initialization)X
+3698(routines)X
+3978(take)X
+4134(stack)X
+555 4312(pointers)N
+833(returned)X
+1121(by)X
+7 f F
+1221(QT_SP)X
+1 f F
+(;)S
+1503(the)X
+1621(initialization)X
+2045(routines)X
+2323(return)X
+2535(initialized)X
+2875(stack)X
+3060(pointers.)X
+755 4444(The)N
+7 f F
+903(QT_ARGS)X
+1 f F
+1262(routine)X
+1512(is)X
+1588(used)X
+1758(for)X
+1874(implementing)X
+2340(threads)X
+2594(packages)X
+2911(that)X
+3053(use)X
+3182(a)X
+3240(fast)X
+3378(calling)X
+3618(sequence)X
+3935(with)X
+4099(only)X
+4263(a)X
+555 4548(single)N
+769(\256xed)X
+952(argument.)X
+7 f F
+1318(QT_VARGS)X
+1 f F
+1725(is)X
+1801(used)X
+1971(when)X
+2168(varargs)X
+2428(is)X
+2504(used.)X
+2714(Once)X
+2906(a)X
+2964(thread)X
+3187(has)X
+3316(been)X
+3490(initialized)X
+3832(the)X
+3952(client)X
+4152(does)X
+555 4652(not)N
+677(need)X
+849(to)X
+931(distinguish)X
+1301(between)X
+1589(threads)X
+1841(that)X
+1981(are)X
+2100(initialized)X
+2440(but)X
+2562(not)X
+2684(yet)X
+2802(run)X
+2929(and)X
+3065(those)X
+3254(that)X
+3394(have)X
+3566(run.)X
+7 f F
+755 4784(QT_ARGS)N
+1 f F
+1114(initializes)X
+1448(a)X
+1507(thread)X
+1730(so)X
+1823(that)X
+1965(when)X
+2161(the)X
+2281(thread)X
+2504(runs,)X
+2684(the)X
+2804(function)X
+7 f F
+3093(only)X
+1 f F
+3307(is)X
+3382(called)X
+3596(with)X
+3760(three)X
+3943(arguments:)X
+7 f F
+555 4888(u)N
+1 f F
+(,)S
+7 f F
+644(t)X
+1 f F
+(,)S
+733(and)X
+7 f F
+870(userf)X
+1 f F
+(.)S
+1170(It)X
+1239(is)X
+1312(expected)X
+1618(that)X
+7 f F
+1758(only)X
+1 f F
+1970(will)X
+2114(perform)X
+2393(thread-speci\256c)X
+2886(initialization,)X
+3330(call)X
+7 f F
+3466(userf)X
+1 f F
+(,)S
+3746(and)X
+3882(then)X
+4040(perform)X
+555 4992(thread-speci\256c)N
+1059(cleanup.)X
+1379(The)X
+1534(cleanup)X
+1814(must)X
+1999(halt)X
+2149(the)X
+2277(thread;)X
+2530(it)X
+2604(is)X
+2687(an)X
+2793(error)X
+2980(for)X
+7 f F
+3104(only)X
+1 f F
+3326(to)X
+3418(return.)X
+3680(The)X
+3835(argument)X
+7 f F
+4168(u)X
+1 f F
+4246(is)X
+555 5096(passed)N
+790(to)X
+873(the)X
+992(user)X
+1147(function,)X
+1455(while)X
+7 f F
+1654(t)X
+1 f F
+1723(is)X
+1797(thread)X
+2018(information)X
+2416(for)X
+2530(initialization)X
+2954(and)X
+3090(cleanup.)X
+3400(Figure)X
+3629(3)X
+3689(shows)X
+3909(typical)X
+4147(code)X
+555 5200(for)N
+7 f F
+669(thread_create)X
+1 f F
+1313(and)X
+7 f F
+1449(only)X
+1 f F
+(.)S
+8 s 9 f F
+555 5484 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5584(1.)N
+651(Choosing)X
+915(the)X
+1011(stack)X
+1160(size)X
+1277(is)X
+1338(a)X
+1384(portability)X
+1669(problem)X
+1900(with)X
+2032(most)X
+2175(threads)X
+2377(packages.)X
+2660(The)X
+2777(principal)X
+3021(exception)X
+3286(is)X
+3346(threads)X
+3547(for)X
+3638(languages)X
+3910(that)X
+4023(allow)X
+4182(non-)X
+651 5656(contiguious)N
+966(allocation)X
+1234(of)X
+1303(stack)X
+1450(frames.)X
+
+%%Page: 7 7
+7 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2360 392(-)N
+2407(7)X
+2467(-)X
+8 s 7 f F
+919 712(thread_t)N
+1261(*)X
+843 800(thread_create)N
+1375(\(userf,)X
+1679(arg\))X
+843 888({)N
+919 976(t)N
+995(=)X
+1071(allocate_thread)X
+1679(\(...\);)X
+919 1064(t->sp)N
+1147(=)X
+1223(QT_ARGS)X
+1527(\(t->sp,)X
+1831(arg,)X
+2021(t,)X
+2135(userf,)X
+2401(only\);)X
+919 1152(return)N
+1185(\(t\);)X
+843 1240(})N
+843 1416(only)N
+1033(\(u,)X
+1185(t,)X
+1299(userf\))X
+843 1504({)N
+919 1592(global_current_th)N
+1565(read)X
+1755(=)X
+1831(\(thread_t)X
+2211(*\)t;)X
+919 1680(\(*userf\)\(u\);)N
+919 1768(next)N
+1109(=)X
+1185(dequeue)X
+1489(\(runable_queue\);)X
+919 1856(QT_ABORT)N
+1261(\(...,)X
+1489(t,)X
+1603(next\);)X
+2325(/*)X
+2439(Halt)X
+2629(the)X
+2781(thread.)X
+3085(*/)X
+843 1944(})N
+9 s 3 f F
+1665 2096(Figure)N
+1887(3.)X
+1 f F
+1977(Example)X
+2251(thread)X
+2449(creation)X
+2699(and)X
+2821(startup)X
+3035(code.)X
+10 s 3 f F
+555 2304(3.3.)N
+715(Varargs)X
+1016(Thread)X
+1289(Initialization)X
+8 s 7 f F
+843 2468(typedef)N
+1147(void)X
+1337(*\(qt_vuserf_t\)\(..)X
+1983(.\);)X
+843 2556(typedef)N
+1147(void)X
+1337(\(qt_startup_t\)\(vo)X
+1983(id)X
+2097(*t\);)X
+843 2644(typedef)N
+1147(void)X
+1337(\(qt_cleanup_t\)\(vo)X
+1983(id)X
+2097(*t,)X
+2249(void)X
+2439(*vuserf_return\);)X
+843 2820(qt_t)N
+1033(*QT_VARGS)X
+1413(\(qt_t)X
+1641(*sp,)X
+1831(int)X
+1983(nbytes,)X
+2287(void)X
+2477(*vargs,)X
+2781(void)X
+2971(*t,)X
+1451 2908(qt_startup_t)N
+1945(*startup,)X
+2325(qt_vuserf_t)X
+2781(*userf,)X
+1451 2996(qt_cleanup_t)N
+1945(*cleanup\);)X
+10 s 1 f F
+555 3148(When)N
+768(varargs)X
+1026(is)X
+1100(needed,)X
+7 f F
+1368(QT_VARGS)X
+1 f F
+1772(is)X
+1845(used)X
+2012(to)X
+2094(initialize)X
+2394(the)X
+2512(thread.)X
+2773(It)X
+2842(pushes)X
+3080(the)X
+7 f F
+3198(nbytes)X
+1 f F
+3506(of)X
+3593(arguments,)X
+3967(with)X
+4129(argu-)X
+555 3252(ments)N
+771(described)X
+1104(by)X
+7 f F
+1209(vargs)X
+1 f F
+(,)S
+1494(a)X
+1555(value)X
+1754(returned)X
+2047(by)X
+2152(the)X
+2274(C)X
+2 f F
+2351(stdargs)X
+1 f F
+2610(facility.)X
+2901(The)X
+3050(initialization)X
+3478(routine)X
+3729(also)X
+3882(arranges)X
+4179(that)X
+555 3356(the)N
+675(function)X
+7 f F
+964(startup)X
+1 f F
+1322(will)X
+1468(be)X
+1566(called)X
+1780(with)X
+1944(parameter)X
+7 f F
+2288(t)X
+1 f F
+(,)S
+2378(then)X
+7 f F
+2537(userf)X
+1 f F
+2798(will)X
+2943(be)X
+3040(called)X
+3253(with)X
+3416(the)X
+3535(arguments)X
+3890(described)X
+4219(by)X
+7 f F
+555 3460(varargs)N
+1 f F
+(,)S
+976(\(but)X
+2 f F
+1170(not)X
+1 f F
+1337(the)X
+7 f F
+1500(nbytes)X
+1 f F
+1853(parameter\),)X
+2287(then)X
+7 f F
+2490(cleanup)X
+1 f F
+2891(will)X
+3080(be)X
+3221(called)X
+3478(with)X
+3685(parameter)X
+7 f F
+4071(t)X
+1 f F
+4183(and)X
+7 f F
+555 3564(vuserf_return)N
+1 f F
+(,)S
+1249(the)X
+1397(return)X
+1639(value)X
+1863(from)X
+7 f F
+2069(vuserf)X
+1 f F
+(.)S
+2447(Figure)X
+2706(4)X
+2795(shows)X
+3044(typical)X
+3311(code)X
+3512(for)X
+7 f F
+3655(thread_create)X
+1 f F
+(,)S
+7 f F
+555 3668(startup)N
+1 f F
+(,)S
+931(and)X
+7 f F
+1067(cleanup)X
+1 f F
+(.)S
+8 s F
+3628(2)Y
+10 s F
+755 3800(The)N
+7 f F
+913(QA_VARGS)X
+1 f F
+1330(interface)X
+1645(has)X
+7 f F
+1785(userf)X
+1 f F
+2058(called)X
+2283(directly,)X
+2581(because)X
+2869(that)X
+3022(is)X
+3108(what)X
+3297(is)X
+3383(most)X
+3571(ef\256cient)X
+3867(and)X
+4016(portable.)X
+555 3904(However,)N
+898(the)X
+1024(functions)X
+7 f F
+1350(startup)X
+1 f F
+1714(and)X
+7 f F
+1858(cleanup)X
+1 f F
+2222(must)X
+2405(be)X
+2509(called)X
+2729(separately,)X
+3102(instead)X
+3356(of)X
+3450(being)X
+3655(inlined)X
+3904(in)X
+7 f F
+3993(only)X
+1 f F
+(,)S
+4232(as)X
+555 4008(they)N
+713(were)X
+890(with)X
+7 f F
+1052(QT_ARGS)X
+1 f F
+(.)S
+7 f F
+1448(QT_VARGS)X
+1 f F
+1852(also)X
+2001(requires)X
+2280(more)X
+2465(copying,)X
+2763(which)X
+2979(slows)X
+3181(thread)X
+3402(initialization)X
+3826(and)X
+3962(startup.)X
+755 4140(Except)N
+1006(for)X
+1128(initialization,)X
+1580(QuickThreads)X
+2063(does)X
+2238(not)X
+2368(distinguish)X
+2746(between)X
+3042(threads)X
+3302(initialized)X
+3650(with)X
+7 f F
+3820(QT_ARGS)X
+1 f F
+4183(and)X
+555 4244(those)N
+744(initialized)X
+1084(with)X
+7 f F
+1246(QT_VARGS)X
+1 f F
+(.)S
+1690(Thus,)X
+1890(single-argument)X
+2431(and)X
+2567(varargs)X
+2824(threads)X
+3076(may)X
+3234(be)X
+3330(mixed)X
+3550(freely.)X
+3 f F
+555 4452(3.3.1.)N
+775(Context)X
+1067(Switching)X
+8 s 9 f F
+555 5556 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5656(2.)N
+651(The)X
+766(code)X
+902(is)X
+961(typical,)X
+1167(but)X
+1265(not)X
+1363(strictly)X
+1557(portable.)X
+1814(Unfortunately,)X
+2204(there)X
+2347(is)X
+2406(no)X
+2486(truly)X
+2623(portable)X
+2848(way)X
+2970(to)X
+3036(do)X
+3116(varargs)X
+3319(in)X
+3385(C.)X
+3476(See)X
+3584(Appendix)X
+3852(A)X
+3914(for)X
+4004(details.)X
+
+%%Page: 8 8
+8 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2360 392(-)N
+2407(8)X
+2467(-)X
+8 s 7 f F
+843 712(#include)N
+1185(<stdarg.h>)X
+919 888(thread_t)N
+1261(*)X
+843 976(thread_create)N
+1375(\(func,)X
+1641(nargs,)X
+1907(...\))X
+843 1064({)N
+919 1152(t)N
+995(=)X
+1071(allocate_thread)X
+1679(\(...\);)X
+919 1240(va_start)N
+1261(\(ap,)X
+1451(nargs\);)X
+919 1328(t->sp)N
+1147(=)X
+1223(QT_VARGS)X
+1565(\(t->sp,)X
+1869(nargs)X
+2097(*)X
+2173(sizeof\(word\),)X
+2705(ap,)X
+2857(t,)X
+1603 1416(startup,)N
+1945(func,)X
+2173(cleanup\);)X
+919 1504(va_end)N
+1185(\(ap\);)X
+919 1592(return)N
+1185(\(t\);)X
+843 1680(})N
+843 1856(startup)N
+1147(\(t\))X
+843 1944({)N
+919 2032(global_current_th)N
+1565(read)X
+1755(=)X
+1831(\(thread_t)X
+2211(*\)t;)X
+843 2120(})N
+843 2296(cleanup)N
+1147(\(t,)X
+1299(vuserf_return\))X
+843 2384({)N
+919 2472(\(\(thread_t)N
+1337(*\)t\)->retval)X
+1831(=)X
+1907(vuserf_return;)X
+919 2560(next)N
+1109(=)X
+1185(dequeue)X
+1489(\(runable_queue\);)X
+919 2648(QT_ABORT)N
+1261(\(...,)X
+1489(t,)X
+1603(next\);)X
+2325(/*)X
+2439(Halt)X
+2629(the)X
+2781(thread.)X
+3085(*/)X
+843 2736(})N
+9 s 3 f F
+1502 2888(Figure)N
+1724(4.)X
+1 f F
+1814(Typical)X
+2052(code)X
+2206(for)X
+2308(thread)X
+2506(creation,)X
+2774(startup)X
+2988(and)X
+3110(cleanup.)X
+8 s 7 f F
+843 3128(typedef)N
+1147(void)X
+1337(*\(qt_helper_t\)\(qt)X
+1983(_t)X
+2097(*old,)X
+2325(void)X
+2515(*a0,)X
+2705(void)X
+2895(*a1\);)X
+843 3216(typedef)N
+1147(void)X
+1337(*\(qt_block_t\)\(qt_)X
+1983(helper_t)X
+2325(*helper,)X
+2667(void)X
+2857(*a0,)X
+3047(void)X
+3237(*a1,)X
+1869 3304(qt_t)N
+2059(*new\);)X
+843 3480(qt_block_t)N
+1261(QT_ABORT,)X
+1641(QT_BLOCK,)X
+2021(QT_BLOCKI;)X
+10 s 1 f F
+755 3660(A)N
+836(thread)X
+1060(blocks)X
+1291(by)X
+1393(calling)X
+1633(a)X
+1691(QuickThreads)X
+2 f F
+2168(blocking)X
+2466(routine)X
+1 f F
+2697(,)X
+7 f F
+2739(QT_ABORT)X
+1 f F
+(,)S
+7 f F
+3165(QT_BLOCK)X
+1 f F
+(,)S
+3591(or)X
+7 f F
+3680(QT_BLOCKI)X
+1 f F
+(.)S
+4174(The)X
+555 3764(blocking)N
+862(routines)X
+1147(halt)X
+1294(the)X
+1419(old)X
+1548(thread,)X
+1796(move)X
+2001(to)X
+2090(the)X
+2215(stack)X
+2407(of)X
+2501(the)X
+2626(thread)X
+7 f F
+2853(new)X
+1 f F
+(,)S
+3043(and)X
+3185(call)X
+3327(the)X
+3451(helper)X
+3678(function,)X
+7 f F
+3991(helper)X
+1 f F
+(,)S
+555 3868(with)N
+723(the)X
+847(stack)X
+1038(pointer)X
+1291(of)X
+1384(the)X
+1508(old)X
+1636(\(blocked\))X
+1970(thread)X
+2197(and)X
+2339(the)X
+2462(arguments)X
+7 f F
+2821(a0)X
+1 f F
+2942(and)X
+7 f F
+3083(a1)X
+1 f F
+(.)S
+3244(When)X
+7 f F
+3461(helper)X
+1 f F
+3774(returns,)X
+4042(the)X
+4165(new)X
+555 3972(thread)N
+776(is)X
+849(unblocked)X
+1203(and)X
+1339(resumed.)X
+2 f F
+755 4104(Note:)N
+1 f F
+953(a)X
+1009(thread)X
+1230(cannot)X
+1464(context)X
+1720(switch)X
+1949(to)X
+2031(itself.)X
+755 4236(The)N
+903(blocking)X
+1206(routines)X
+1487(vary)X
+1653(in)X
+1738(how)X
+1899(much)X
+2100(state)X
+2270(they)X
+2431(save)X
+2597(on)X
+2700(a)X
+2758(context)X
+3016(switch.)X
+7 f F
+3287(QT_BLOCK)X
+1 f F
+3693(saves)X
+3889(all)X
+3991(processor)X
+555 4340(registers.)N
+7 f F
+895(QT_BLOCKI)X
+1 f F
+1355(saves)X
+1557(just)X
+1700(the)X
+1826(integer)X
+2077(registers,)X
+2397(reducing)X
+2706(the)X
+2831(context)X
+3094(switch)X
+3330(overhead.)X
+7 f F
+3692(QT_ABORT)X
+1 f F
+4103(aborts)X
+555 4444(the)N
+684(old)X
+817(thread.)X
+7 f F
+1089(QT_ABORT)X
+1 f F
+1504(saves)X
+1709(no)X
+1820(registers)X
+2123(and)X
+2270(passes)X
+2506(a)X
+2573(garbage)X
+7 f F
+2859(old)X
+1 f F
+3034(value)X
+3239(to)X
+3331(the)X
+3459(helper)X
+3690(function;)X
+4009(it)X
+4083(is)X
+4166(thus)X
+555 4548(fastest,)N
+802(but)X
+926(the)X
+1046(thread)X
+1269(cannot)X
+1505(later)X
+1670(be)X
+1768(resumed.)X
+2102(\(Some)X
+2333(calling)X
+2573(conventions)X
+2982(require)X
+3232(a)X
+3290(stack)X
+3477(walk)X
+3654(when)X
+3849(a)X
+3906(thread)X
+4128(exits.)X
+555 4652(In)N
+642(these)X
+827(cases)X
+7 f F
+1017(QT_ABORT)X
+1 f F
+1421(may)X
+1579(be)X
+2 f F
+1675(slowest)X
+1 f F
+1910(,)X
+1950(but)X
+2072(it)X
+2136(still)X
+2275(must)X
+2450(be)X
+2546(used)X
+2713(to)X
+2795(terminate)X
+3118(a)X
+3174(thread.\))X
+755 4784(The)N
+905(return)X
+1122(value)X
+1321(from)X
+1502(the)X
+1625(blocking)X
+1930(routines)X
+2213(is)X
+2290(a)X
+2350(pointer)X
+2601(used)X
+2772(to)X
+2858(support)X
+3122(communication)X
+3644(between)X
+3936(threads.)X
+4232(In)X
+555 4888(some)N
+748(systems,)X
+1045(a)X
+1105(blocking)X
+1409(thread's)X
+1692(helper)X
+1917(function)X
+2208(is)X
+2285(called)X
+2501(on)X
+2605(a)X
+2665(scheduler's)X
+3055(stack.)X
+3284(QuickThreads)X
+3762(arranges)X
+4058(that)X
+4201(the)X
+555 4992(return)N
+769(value)X
+965(from)X
+1143(the)X
+1263(helper)X
+1486(function)X
+1775(is)X
+1850(used)X
+2019(as)X
+2108(the)X
+2228(return)X
+2442(value)X
+2638(from)X
+2816(the)X
+2935(scheduler's)X
+3322(call)X
+3459(to)X
+3542(a)X
+3599(blocking)X
+3900(routine.)X
+4188(For)X
+555 5096(example,)N
+870(the)X
+991(scheduler)X
+1322(calls)X
+7 f F
+1492(QT_BLOCKI)X
+1 f F
+1947(to)X
+2032(run)X
+2162(a)X
+2220(thread,)X
+2463(the)X
+2583(thread)X
+2806(runs)X
+2966(for)X
+3082(a)X
+3140(while)X
+3340(then)X
+3500(calls)X
+7 f F
+3669(QT_ABORT)X
+1 f F
+4075(to)X
+4159(halt,)X
+555 5200(call)N
+693(the)X
+812(helper,)X
+1054(and)X
+1191(then)X
+1350(resume)X
+1603(the)X
+1722(scheduler)X
+2051(by)X
+2152(letting)X
+2377(the)X
+2496(scheduler's)X
+7 f F
+2883(QT_BLOCKI)X
+1 f F
+3336(return.)X
+3589(The)X
+3735(return)X
+3948(value)X
+4143(from)X
+555 5304(the)N
+679(helper)X
+906(is)X
+985(used)X
+1158(as)X
+1251(the)X
+1375(return)X
+1593(value)X
+1793(from)X
+1975(the)X
+2099(scheduler's)X
+2491(call)X
+2632(to)X
+7 f F
+2719(QT_BLOCKI)X
+1 f F
+(.)S
+3216(This)X
+3383(return)X
+3600(mechanism)X
+3990(is)X
+4068(usually)X
+555 5408(avoided)N
+830(because)X
+1106(the)X
+1225(blocking)X
+1526(thread)X
+1748(generally)X
+2068(knows)X
+2298(best)X
+2448(what)X
+2625(cleanup)X
+2896(code)X
+3069(should)X
+3303(be)X
+3399(run)X
+3526(and)X
+3662(because)X
+3937(it)X
+4001(is)X
+4074(hard)X
+4237(to)X
+555 5512(pass)N
+713(multiple)X
+999(arguments)X
+1353(through)X
+1622(a)X
+1678(single)X
+1889(return)X
+2101(value.)X
+
+%%Page: 9 9
+9 p
+10 s 0 xH 0 xS 1 f F
+2360 392(-)N
+2407(9)X
+2467(-)X
+3 f F
+555 680(3.3.2.)N
+775(Allocating)X
+1146(Space)X
+1366(On)X
+1492(The)X
+1645(Stack)X
+8 s 7 f F
+843 844(void)N
+1033(*QT_SALLOC)X
+1451(\(qt_t)X
+1679(*sp,)X
+1869(unsigned)X
+2211(size\);)X
+843 932(qt_t)N
+1033(*QT_SADJ)X
+1375(\(qt_t)X
+1603(*sp,)X
+1793(unsigned)X
+2135(size\);)X
+843 1020(qt_t)N
+1033(*QT_SUNADJ)X
+1451(\(qt_t)X
+1679(*sp,)X
+1869(unsigned)X
+2211(size\);)X
+10 s 1 f F
+755 1200(Sometimes)N
+1137(it)X
+1208(is)X
+1288(useful)X
+1511(to)X
+1600(allocate)X
+1877(temporary)X
+2234(space)X
+2439(on)X
+2545(the)X
+2669(stack)X
+2860(of)X
+2953(a)X
+3015(blocked)X
+3295(thread.)X
+3562(Stacks)X
+3797(can)X
+3935(grow)X
+4126(up)X
+4232(or)X
+555 1304(down,)N
+782(so)X
+882(the)X
+1009(routines)X
+7 f F
+1296(QT_SALLOC)X
+1 f F
+(,)S
+7 f F
+1777(QT_SADJ)X
+1 f F
+(,)S
+2162(and)X
+7 f F
+2307(QT_SUNADJ)X
+1 f F
+2768(hide)X
+2935(stack)X
+3129(direction)X
+3443(and)X
+3588(ensure)X
+3827(that)X
+3976(valid)X
+4165(data)X
+555 1408(remains)N
+829(unclobbered.)X
+7 f F
+755 1540(QT_SALLOC)N
+1 f F
+1219(is)X
+1304(similar)X
+1558(to)X
+1652(the)X
+1782(standard)X
+2086(library's)X
+7 f F
+2390(malloc)X
+1 f F
+(,)S
+2730(but)X
+2864(the)X
+7 f F
+2994(size)X
+1 f F
+3218(parameter)X
+3572(must)X
+3759(be)X
+3867(a)X
+3935(multiple)X
+4232(of)X
+7 f F
+555 1644(QT_STKALIGN)N
+1 f F
+1107(and)X
+1247(it)X
+1315(returns)X
+1562(storage)X
+1818(that)X
+1962(is)X
+2039(aligned)X
+2299(on)X
+7 f F
+2403(QT_STKALIGN)X
+1 f F
+(-byte)S
+3120(boundaries.)X
+3536(Note)X
+3715(that)X
+3858(on)X
+3961(essentially)X
+555 1748(all)N
+658(machines,)X
+1004(the)X
+1125(stack)X
+1313(is)X
+1389(at)X
+1470(least)X
+1640(maximally)X
+2005(aligned.)X
+2304(That)X
+2474(is,)X
+2570(the)X
+2691(stack)X
+2879(must)X
+3057(be)X
+3155(at)X
+3235(least)X
+3404(as)X
+3493(aligned)X
+3751(as)X
+3840(any)X
+3978(other)X
+4165(data)X
+555 1852(type.)N
+756(However,)X
+1094(the)X
+1215(stack)X
+1403(may)X
+1564(have)X
+1739(much)X
+2 f F
+1940(stricter)X
+1 f F
+2194(alignment)X
+2536(than)X
+2696(other)X
+2883(data)X
+3039(types,)X
+3250(so)X
+3343(allocating)X
+3681(a)X
+3739(small)X
+3934(region)X
+4161(may)X
+555 1956(consume)N
+860(substantially)X
+1284(more)X
+1469(memory.)X
+7 f F
+755 2088(QT_SALLOC)N
+1 f F
+1210(does)X
+1380(not)X
+1505(adjust)X
+1719(the)X
+1840(stack)X
+2028(pointer,)X
+2298(so)X
+2392(if)X
+2464(it)X
+2530(is)X
+2605(used)X
+2774(several)X
+3024(times)X
+3219(in)X
+3303(succession,)X
+7 f F
+3688(QT_SADJ)X
+1 f F
+4046(must)X
+4223(be)X
+555 2192(called)N
+773(before)X
+1005(each)X
+1179(call)X
+1320(except)X
+1555(the)X
+1678(\256rst.)X
+1867(It)X
+1941(is)X
+2019(usd)X
+2155(each)X
+2328(time)X
+2495(with)X
+2662(the)X
+2785(same)X
+7 f F
+2975(size)X
+1 f F
+3192(parameter)X
+3539(as)X
+3631(the)X
+3754(preceding)X
+4096(call)X
+4237(to)X
+7 f F
+555 2296(QT_SALLOC)N
+1 f F
+(;)S
+1036(a)X
+1099(new)X
+1260(stack)X
+1452(pointer)X
+1706(is)X
+1786(returned.)X
+2121(When)X
+2340(the)X
+2465(thread)X
+2693(is)X
+2773(restarted,)X
+3097(the)X
+3222(unadjusted)X
+3596(stack)X
+3788(pointer)X
+4042(must)X
+4223(be)X
+555 2400(used.)N
+762(The)X
+907(stack)X
+1092(pointer)X
+1339(can)X
+1471(be)X
+1567(\252unadjusted\272)X
+2006(either)X
+2209(by)X
+2309(saving)X
+2538(the)X
+2656(unadjusted)X
+3023(value)X
+3217(or)X
+3304(by)X
+3404(calling)X
+7 f F
+3642(QT_SUNADJ)X
+1 f F
+(.)S
+2 f F
+755 2532(Note:)N
+1 f F
+994(For)X
+1166(each)X
+1375(call)X
+1552(to)X
+7 f F
+1675(QT_SADJ)X
+1 f F
+2071(there)X
+2292(must)X
+2507(be)X
+2643(a)X
+2739(distinct)X
+3034(call)X
+3210(to)X
+7 f F
+3332(QT_SUNADJ)X
+1 f F
+(,)S
+3844(because)X
+7 f F
+755 2636(QT_SUNADJ)N
+1235(\(x+y\))X
+1 f F
+1495(is)X
+1568(not)X
+1690(the)X
+1808(same)X
+1993(as)X
+7 f F
+2080(QT_SUNADJ)X
+2560(\(x\);)X
+2772(QT_SUNADJ)X
+3252(\(y\))X
+1 f F
+(.)S
+3 f F
+555 2844(3.3.3.)N
+775(Starting)X
+1075(QuickThreads)X
+1 f F
+555 2976(Most)N
+750(threads)X
+1013(packages)X
+1339(explicitly)X
+1672(move)X
+1881(from)X
+2068(running)X
+2347(as)X
+2444(a)X
+2510(single-threaded)X
+3035(process)X
+3306(to)X
+3398(running)X
+3677(threads.)X
+3979(In)X
+4076(Quick-)X
+555 3080(Threads,)N
+855(a)X
+912(thread)X
+1134(is)X
+1208(represented)X
+1600(only)X
+1763(by)X
+1864(its)X
+1960(stack)X
+2146(pointer.)X
+2434(The)X
+2580(main)X
+2761(process)X
+3023(has)X
+3151(a)X
+3208(stack)X
+3393(pointer,)X
+3660(and,)X
+3816(thus,)X
+3989(is)X
+4062(already)X
+555 3184(a)N
+613(thread.)X
+876(Since)X
+1076(it)X
+1142(is)X
+1217(already)X
+1476(running,)X
+1767(it)X
+1833(does)X
+2002(not)X
+2126(need)X
+2300(to)X
+2384(be)X
+2482(initialized.)X
+2864(The)X
+3011(main)X
+3193(thread)X
+3416(is)X
+3491(blocked)X
+3766(and)X
+3903(restarted)X
+4201(us-)X
+555 3288(ing)N
+677(the)X
+795(normal)X
+1042(QuickThreads)X
+1517(primitives.)X
+3 f F
+555 3496(3.3.4.)N
+775(Debugging)X
+1 f F
+555 3628(If)N
+633(the)X
+755(macro)X
+7 f F
+980(QT_DEBUG)X
+1 f F
+1388(is)X
+1464(de\256ned,)X
+1743(some)X
+1935(of)X
+2025(the)X
+2146(operations)X
+2503(will)X
+2650(do)X
+2753(extra)X
+2937(work)X
+3125(to)X
+3210(help)X
+3371(with)X
+3536(debugging.)X
+3937(The)X
+4085(goal)X
+4246(is)X
+555 3732(to)N
+637(get)X
+755(errors)X
+963(reported)X
+1251(more)X
+1436(quickly.)X
+1736(This)X
+1898(functionality)X
+2327(is)X
+2400(less)X
+2540(than)X
+2698(great,)X
+2899(but)X
+3021(better)X
+3224(than)X
+3382(nothing.)X
+2 f F
+755 3864(Note:)N
+1 f F
+953(A)X
+1031(given)X
+1229(implementation)X
+1751(may)X
+1909(provide)X
+2174(anything)X
+2474(from)X
+2650(lots)X
+2785(of)X
+2872(help)X
+3030(no)X
+3130(help)X
+3288(at)X
+3366(all.)X
+3 f F
+555 4072(4.)N
+655(Examples)X
+1 f F
+555 4204(This)N
+723(section)X
+976(walks)X
+1189(through)X
+1464(a)X
+1526(simple)X
+1765(uniprocessor)X
+2201(package,)X
+2511(SimpleThreads,)X
+3042(built)X
+3214(using)X
+3413(QuickThreads.)X
+8 s F
+3888 4164(3)N
+10 s F
+3966 4204(In)N
+4059(the)X
+4183(fol-)X
+555 4308(lowing,)N
+819(names)X
+1046(starting)X
+1308(with)X
+7 f F
+1472(qt_)X
+1 f F
+1638(and)X
+7 f F
+1776(QT_)X
+1 f F
+1942(are)X
+2062(all)X
+2163(parts)X
+2340(of)X
+2428(the)X
+2547(QuickThreads)X
+3023(package)X
+3308(described)X
+3637(above.)X
+3890(Names)X
+4134(start-)X
+555 4412(ing)N
+682(with)X
+7 f F
+849(stp_)X
+1 f F
+1066(and)X
+7 f F
+1207(STP_)X
+1 f F
+1424(are)X
+1548(parts)X
+1729(of)X
+1821(SimpleThreads.)X
+2371(The)X
+2521(meaning)X
+2822(of)X
+2914(other)X
+3104(names)X
+3334(should)X
+3572(be)X
+3673(clear)X
+3854(from)X
+4034(the)X
+4156(con-)X
+555 4516(text.)N
+3 f F
+555 4724(4.1.)N
+715(Data)X
+900(Structures)X
+1 f F
+555 4856(The)N
+700(basic)X
+885(SimpleThreads)X
+1390(thread)X
+1611(is:)X
+8 s 7 f F
+843 4992(typedef)N
+1147(struct)X
+1413(stp_t)X
+1641({)X
+919 5080(qt_t)N
+1109(*sp;)X
+1793(/*)X
+1907(QuickThreads)X
+2401(handle.)X
+2705(*/)X
+919 5168(void)N
+1109(*sto;)X
+1793(/*)X
+1907(`malloc'-allocate)X
+2553(d)X
+2629(stack.)X
+2895(*/)X
+919 5256(struct)N
+1185(stp_t)X
+1413(*next;)X
+1793(/*)X
+1907(Next)X
+2097(thread)X
+2363(in)X
+2477(the)X
+2629(queue.)X
+2895(*/)X
+843 5344(})N
+919(stp_t;)X
+9 f F
+555 5556 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5656(3.)N
+651(See)X
+7 s 7 f F
+777(stp.c)X
+8 s 1 f F
+963(and)X
+7 s 7 f F
+1089(stp.h)X
+8 s 1 f F
+1275(in)X
+1341(the)X
+1435(QuickThreads)X
+1812(distribution.)X
+
+%%Page: 10 10
+10 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2340 392(-)N
+2387(10)X
+2487(-)X
+755 680(Threads)N
+1037(are)X
+1159(enqueued)X
+1490(on)X
+1593(a)X
+1652(singly-linked)X
+2097(list)X
+2217(that)X
+2360(uses)X
+2521(the)X
+7 f F
+2642(next)X
+1 f F
+2857(\256eld)X
+3022(in)X
+3107(each)X
+3278(thread.)X
+3542(Queues)X
+3806(are)X
+3928(represented)X
+555 784(with)N
+717(an)X
+7 f F
+813(stp_q_t)X
+1 f F
+(,)S
+1189(and)X
+1325(are)X
+1444(accessed)X
+1746(with)X
+1908(these)X
+2093(routines:)X
+8 s 7 f F
+843 920(void)N
+1033(stp_qinit)X
+1413(\(stp_q_t)X
+1755(*q\))X
+843 1008(void)N
+1033(stp_qput)X
+1375(\(stp_q_t)X
+1717(*q,)X
+1869(stp_t)X
+2097(*thread\))X
+843 1096(stp_t)N
+1071(*stp_qget)X
+1451(\(stp_q_t)X
+1793(*q\))X
+10 s 1 f F
+755 1276(The)N
+900(routine)X
+7 f F
+1147(stp_qget)X
+1 f F
+1551(returns)X
+1794(a)X
+1850(null)X
+1994(pointer)X
+2241(if)X
+2310(the)X
+2428(queue)X
+2640(is)X
+2713(empty.)X
+3 f F
+555 1484(4.2.)N
+715(SimpleThreads)X
+1254(Package)X
+1559(Initialization)X
+1 f F
+555 1616(SimpleThreads)N
+1062(must)X
+1239(be)X
+1337(initialized)X
+1679(before)X
+1907(any)X
+2045(other)X
+2232(operations)X
+2588(are)X
+2708(performed.)X
+3104(The)X
+3250(runable)X
+3512(queue)X
+3725(is)X
+3799(initialized)X
+4140(to)X
+4223(be)X
+555 1720(empty.)N
+8 s 7 f F
+843 1856(static)N
+1109(stp_q_t)X
+1413(stp_global_runq;)X
+919 2032(void)N
+843 2120(stp_init\(\))N
+843 2208({)N
+919 2296(stp_qinit)N
+1299(\(&stp_global_runq)X
+1945(\);)X
+843 2384(})N
+10 s 3 f F
+555 2640(4.3.)N
+715(SimpleThreads)X
+1254(Startup)X
+1 f F
+555 2772(One)N
+719(or)X
+816(more)X
+1011(runable)X
+1282(threads)X
+1543(are)X
+1671(created)X
+1933(\(discussed)X
+2296(below\))X
+2548(and)X
+2693(put)X
+2824(on)X
+2933(the)X
+3060(runable)X
+3330(queue.)X
+3591(Then)X
+7 f F
+3785(stp_start)X
+1 f F
+4246(is)X
+555 2876(called)N
+768(to)X
+851(start)X
+1010(the)X
+1129(SimpleThreads)X
+1635(package.)X
+1959(It)X
+2028(removes)X
+2320(a)X
+2376(thread)X
+2597(from)X
+2773(the)X
+2891(runable)X
+3152(queue,)X
+3384(blocks)X
+3613(the)X
+3731(main)X
+3911(thread,)X
+4152(calls)X
+555 2980(a)N
+611(helper)X
+832(to)X
+914(enqueue)X
+1202(the)X
+1320(blocked)X
+1594(main)X
+1774(thread,)X
+2015(and)X
+2151(runs)X
+2309(the)X
+2427(next)X
+2585(thread.)X
+8 s 7 f F
+843 3116(static)N
+1109(stp_t)X
+1337(*stp_global_curr;)X
+919 3292(void)N
+843 3380(stp_start\(\))N
+843 3468({)N
+919 3556(static)N
+1185(stp_t)X
+1413(stpmain;)X
+1945(/*)X
+2059(Thread)X
+2325(for)X
+2477(the)X
+2629(process.)X
+2971(*/)X
+919 3644(stp_t)N
+1147(*next;)X
+919 3820(while)N
+1147(\(\(next)X
+1413(=)X
+1489(stp_qget)X
+1831(\(&stp_global_runq)X
+2477(\)\))X
+2591(!=)X
+2705(NULL\))X
+2933({)X
+995 3908(stp_global_curr)N
+1603(=)X
+1679(next;)X
+995 3996(QT_BLOCK)N
+1337(\(stp_yieldhelp,)X
+1945(&stpmain,)X
+2325(&stp_global_runq,)X
+3009(next->sp\);)X
+919 4084(})N
+843 4172(})N
+10 s 1 f F
+755 4352(The)N
+909(main)X
+1098(thread)X
+1328(sets)X
+1477(the)X
+1604(notion)X
+1837(of)X
+1933(the)X
+2059(current)X
+2315(thread)X
+2544(\()X
+7 f F
+2571(stp_global_curr)X
+1 f F
+(\))S
+3346(to)X
+3436(be)X
+7 f F
+3540(next)X
+1 f F
+(,)S
+3780(then)X
+3946(blocks)X
+4183(and)X
+555 4456(calls)N
+7 f F
+731(stp_yieldhelp)X
+1 f F
+1384(on)X
+1493(the)X
+1620(next)X
+1787(thread's)X
+2075(stack.)X
+2309(After)X
+2507(the)X
+2633(context)X
+2897(switch,)X
+7 f F
+3154(stp_yieldhelp)X
+1 f F
+3806(saves)X
+4008(the)X
+4134(stack)X
+555 4560(pointer)N
+813(of)X
+911(the)X
+1040(blocked)X
+1325(main)X
+1516(thread,)X
+7 f F
+1768(sp)X
+1 f F
+(,)S
+1915(by)X
+2026(storing)X
+2279(it)X
+2354(in)X
+7 f F
+2447(stpmain)X
+1 f F
+2814(\(pointed)X
+3111(to)X
+3203(by)X
+7 f F
+3313(old)X
+1 f F
+(\),)S
+3534(and)X
+3680(then)X
+3848(puts)X
+4011(the)X
+4139(main)X
+555 4664(thread)N
+785(in)X
+876(the)X
+1003(runable)X
+1273(queue)X
+7 f F
+1494(stp_global_runq)X
+1 f F
+2243(\(pointed)X
+2539(to)X
+2630(by)X
+7 f F
+2739(blockq)X
+1 f F
+(\).)S
+3123(Note)X
+3308(that)X
+7 f F
+3457(QT_BLOCK)X
+1 f F
+3870(calls)X
+4045(it's)X
+4175(\256rst)X
+555 4768(parameter,)N
+7 f F
+923(stp_yieldhelp)X
+1 f F
+(;)S
+1595(and)X
+1736(that)X
+1881(the)X
+2004(second)X
+2252(and)X
+2393(third)X
+2569(arguments)X
+2928(to)X
+7 f F
+3015(QT_BLOCK)X
+1 f F
+3424(are)X
+3548(used)X
+3720(as)X
+3812(the)X
+3935(second)X
+4183(and)X
+555 4872(third)N
+726(arguments)X
+1080(to)X
+7 f F
+1162(stp_yieldhelp)X
+1 f F
+(.)S
+8 s 7 f F
+919 5008(static)N
+1185(void)X
+1375(*)X
+843 5096(stp_yieldhelp)N
+1375(\(qt_t)X
+1603(*sp,)X
+1793(void)X
+1983(*old,)X
+2211(void)X
+2401(*blockq\))X
+843 5184({)N
+919 5272(\(\(stp_t)N
+1223(*\)old\)->sp)X
+1641(=)X
+1717(sp;)X
+919 5360(stp_qput)N
+1261(\(\(stp_q_t)X
+1641(*\)blockq,)X
+2021(\(stp_t)X
+2287(*\)old\);)X
+843 5448(})N
+10 s 1 f F
+755 5628(The)N
+904(main)X
+1088(thread)X
+1313(runs)X
+1475(periodically)X
+1882(because)X
+2161(it)X
+2229(is)X
+2306(stored)X
+2526(in)X
+2612(the)X
+2733(runable)X
+2997(queue.)X
+3252(When)X
+3467(the)X
+3588(main)X
+3771(thread)X
+3995(is)X
+4071(restart-)X
+555 5732(ed,)N
+691(control)X
+958(returns)X
+1221(to)X
+7 f F
+1323(stp_start)X
+1 f F
+(,)S
+1815(which)X
+2051(checks)X
+2309(for)X
+2442(other)X
+2646(runable)X
+2926(threads,)X
+3217(If)X
+3310(there)X
+3510(are)X
+3648(no)X
+3767(runable)X
+4047(threads,)X
+7 f F
+555 5836(stp_start)N
+1 f F
+1007(returns,)X
+1270(exiting)X
+1512(the)X
+1630(SimpleThreads)X
+2135(package.)X
+
+%%Page: 11 11
+11 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(11)X
+2487(-)X
+755 680(When)N
+968(the)X
+1087(main)X
+1268(thread)X
+1490(is)X
+1564(in)X
+1647(the)X
+1766(run)X
+1894(queue,)X
+7 f F
+2127(stp_qget)X
+1 f F
+2532(can)X
+2665(never)X
+2865(return)X
+7 f F
+3078(NULL)X
+1 f F
+(.)S
+3331(Thus,)X
+3532(the)X
+3651(threads)X
+3903(package)X
+4187(ter-)X
+555 784(mination)N
+868(check)X
+1085(appears)X
+1360(only)X
+1531(in)X
+7 f F
+1622(stp_start)X
+1 f F
+2082(instead)X
+2337(of)X
+2432(appearing)X
+2777(in)X
+2867(each)X
+3043(context)X
+3307(switch.)X
+3584(That)X
+3759(saves)X
+3961(a)X
+4025(check)X
+4241(at)X
+555 888(every)N
+760(context)X
+1022(switch,)X
+1277(but)X
+1405(if)X
+1480(the)X
+1604(run)X
+1737(queue)X
+1955(is)X
+2034(typically)X
+2340(short,)X
+2546(checking)X
+2862(in)X
+7 f F
+2950(stp_start)X
+1 f F
+3408(causes)X
+3643(extra)X
+3829(context)X
+4090(switch)X
+555 992(overhead)N
+870(because)X
+1145(the)X
+1263(main)X
+1443(thread)X
+1664(is)X
+1737(invoked)X
+2015(frequently)X
+2365(to)X
+2447(check)X
+2655(for)X
+2769(termination.)X
+3 f F
+555 1200(4.4.)N
+715(Thread)X
+988(Creation)X
+8 s 7 f F
+843 1364(typedef)N
+1147(void)X
+1337(\(stp_userf_t\)\(voi)X
+1983(d)X
+2059(*u\))X
+843 1540(void)N
+1033(stp_create)X
+1451(\(stp_userf_t)X
+1945(*f,)X
+2097(void)X
+2287(*u\))X
+10 s 1 f F
+555 1692(Threads)N
+835(are)X
+955(created)X
+1209(with)X
+7 f F
+1372(stp_create)X
+1 f F
+(,)S
+1893(where)X
+7 f F
+2111(f)X
+1 f F
+2180(is)X
+2254(an)X
+2351(end-user)X
+2648(function)X
+2935(that)X
+3075(takes)X
+3260(one)X
+7 f F
+3396(void)X
+3636(*)X
+1 f F
+3704(parameter,)X
+7 f F
+4066(u)X
+1 f F
+(.)S
+4174(The)X
+555 1796(newly-created)N
+1031(thread)X
+1252(is)X
+1325(put)X
+1447(in)X
+1529(the)X
+1647(run)X
+1774(queue.)X
+755 1928(Creation)N
+1061(proceeds)X
+1377(as)X
+1474(follows:)X
+1766(First,)X
+1962(a)X
+2028(SimpleThreads)X
+2543(thread)X
+2774(body)X
+2964(\()X
+7 f F
+2991(stp_t)X
+1 f F
+(\))S
+3288(and)X
+3433(stack)X
+3627(region)X
+3861(are)X
+3989(allocated.)X
+555 2032(The)N
+708(stack)X
+901(region)X
+1134(is)X
+1214(rounded.)X
+1544(Since)X
+1749(the)X
+1874(stack)X
+2066(may)X
+2231(shrink)X
+2458(during)X
+2694(rounding,)X
+7 f F
+3030(QT_SP)X
+1 f F
+3297(is)X
+3377(passed)X
+3618(a)X
+3681(size)X
+3833(that)X
+3980(is)X
+4060(slightly)X
+555 2136(smaller)N
+815(than)X
+977(the)X
+1099(actual)X
+1315(allocation.)X
+1695(Then,)X
+1904(the)X
+2026(thread)X
+2251(is)X
+2327(initialized)X
+2670(with)X
+7 f F
+2835(QT_ARGS)X
+1 f F
+3194(so)X
+3288(that)X
+3431(when)X
+3628(the)X
+3749(thread)X
+3973(starts)X
+4165(run-)X
+555 2240(ning,)N
+744(it)X
+815(will)X
+966(call)X
+1109(the)X
+1234(routine)X
+7 f F
+1488(stp_only)X
+1 f F
+1899(with)X
+7 f F
+2068(f)X
+1 f F
+(,)S
+2163(a)X
+2225(pointer)X
+2478(to)X
+2566(the)X
+2690(user)X
+2850(function,)X
+3163(the)X
+3287(user)X
+3447(function)X
+3740(argument,)X
+7 f F
+4089(u)X
+1 f F
+(,)S
+4183(and)X
+555 2344(and)N
+691(a)X
+747(pointer)X
+994(to)X
+1076(the)X
+1194(SimpleThreads)X
+1699(thread,)X
+7 f F
+1940(t)X
+1 f F
+(.)S
+2048(The)X
+2193(routine)X
+7 f F
+2440(stp_only)X
+1 f F
+2844(is)X
+2917(discussed)X
+3244(in)X
+3326(more)X
+3511(detail)X
+3709(below.)X
+755 2476(The)N
+902(stack)X
+1089(size,)X
+7 f F
+1256(STP_STKSIZE,)X
+1 f F
+1854(is)X
+1929(a)X
+1987(multiple)X
+2274(of)X
+7 f F
+2362(QT_STKALIGN)X
+1 f F
+2911(and)X
+3048(is)X
+3122(chosen)X
+3366(arbitrarily.)X
+7 f F
+3748(xmalloc)X
+1 f F
+4105(is)X
+4179(like)X
+555 2580(the)N
+673(C)X
+746(library)X
+7 f F
+980(malloc)X
+1 f F
+(,)S
+1308(but)X
+1430(it)X
+1494(never)X
+1693(fails.)X
+8 s 7 f F
+919 2716(void)N
+843 2804(stp_create)N
+1261(\(stp_userf_t)X
+1755(*f,)X
+1907(void)X
+2097(*u\))X
+843 2892({)N
+919 2980(stp_t)N
+1147(*t;)X
+919 3068(void)N
+1109(*sto;)X
+919 3244(t)N
+995(=)X
+1071(xmalloc)X
+1375(\(sizeof\(stp_t\)\);)X
+919 3332(t->sto)N
+1185(=)X
+1261(xmalloc)X
+1565(\(STP_STKSIZE\);)X
+919 3420(sto)N
+1071(=)X
+1147(STP_STKALIGN)X
+1641(\(t->sto,)X
+1983(QT_STKALIGN\);)X
+919 3508(t->sp)N
+1147(=)X
+1223(QT_SP)X
+1451(\(sto,)X
+1679(STP_STKSIZE)X
+2135(-)X
+2211(QT_STKALIGN\);)X
+919 3596(t->sp)N
+1147(=)X
+1223(QT_ARGS)X
+1527(\(t->sp,)X
+1831(u,)X
+1945(t,)X
+2059(\(qt_userf_t)X
+2515(*\)f,)X
+2705(stp_only\);)X
+919 3684(stp_qput)N
+1261(\(&stp_global_runq)X
+1907(,)X
+1983(t\);)X
+843 3772(})N
+10 s 1 f F
+755 3952(The)N
+904(end)X
+1044(user)X
+1202(can)X
+1338(call)X
+7 f F
+1478(stp_create)X
+1 f F
+1982(any)X
+2122(time)X
+2288(after)X
+2460(calling)X
+7 f F
+2702(stp_init)X
+1 f F
+(.)S
+3150(The)X
+3298(application)X
+3677(must)X
+3855(create)X
+4071(at)X
+4152(least)X
+555 4056(one)N
+691(thread)X
+912(before)X
+1138(calling)X
+7 f F
+1376(stp_start)X
+1 f F
+(,)S
+1848(or)X
+7 f F
+1935(stp_start)X
+1 f F
+2387(will)X
+2531(\256nd)X
+2675(the)X
+2793(run)X
+2920(queue)X
+3132(empty)X
+3352(and)X
+3488(will)X
+3632(simply)X
+3869(return.)X
+755 4188(When)N
+970(the)X
+1091(thread)X
+1315(\256rst)X
+1461(runs,)X
+1641(it)X
+1707(calls)X
+7 f F
+1876(stp_only)X
+1 f F
+(.)S
+2322(The)X
+2469(running)X
+2740(thread)X
+2963(is)X
+3038(initialized)X
+3380(by)X
+3482(saving)X
+7 f F
+3713(t)X
+1 f F
+3783(to)X
+3867(a)X
+3925(global)X
+4147(vari-)X
+555 4292(able.)N
+7 f F
+753(t)X
+1 f F
+825(is)X
+902(a)X
+962(pointer)X
+1213(to)X
+1299(the)X
+7 f F
+1421(stp_t)X
+1 f F
+1685(of)X
+1776(the)X
+1898(new)X
+2056(thread,)X
+2301(and)X
+2440(it)X
+2507(is)X
+2583(used)X
+2753(later)X
+2919(by)X
+3022(blocking)X
+3325(operations)X
+3682(to)X
+3767(put)X
+3892(the)X
+4013(thread)X
+4237(in)X
+555 4396(blocked)N
+832(and)X
+971(runable)X
+1235(queues.)X
+1521(Next,)X
+7 f F
+1720(stp_only)X
+1 f F
+2127(calls)X
+2297(the)X
+2418(user)X
+2575(function,)X
+7 f F
+2885(f)X
+1 f F
+(.)S
+2996(If)X
+3073(the)X
+3193(user)X
+3349(function)X
+3638(returns,)X
+3903(the)X
+4023(thread)X
+4246(is)X
+555 4500(aborted,)N
+836(since)X
+1021(it)X
+1085(is)X
+1158(an)X
+1254(error)X
+1431(for)X
+7 f F
+1545(stp_only)X
+1 f F
+1949(to)X
+2031(return.)X
+8 s 7 f F
+843 4636(static)N
+1109(stp_t)X
+1337(*stp_global_curr;)X
+919 4812(static)N
+1185(void)X
+843 4900(stp_only)N
+1185(\(void)X
+1413(*u,)X
+1565(void)X
+1755(*t,)X
+1907(qt_userf_t)X
+2325(*f\))X
+843 4988({)N
+919 5076(stp_global_curr)N
+1527(=)X
+1603(\(stp_t)X
+1869(*\)t;)X
+919 5164(\(*\(stp_userf_t)N
+1489(*\)f\)\(u\);)X
+919 5252(stp_abort\(\);)N
+919 5340(/*)N
+1033(NOTREACHED)X
+1451(*/)X
+843 5428(})N
+
+%%Page: 12 12
+12 p
+8 s 0 xH 0 xS 7 f F
+10 s 1 f F
+2340 392(-)N
+2387(12)X
+2487(-)X
+3 f F
+555 680(4.5.)N
+715(Context)X
+1007(Switching)X
+8 s 7 f F
+843 844(void)N
+1033(stp_abort)X
+1413(\(void\))X
+843 932(void)N
+1033(stp_yield)X
+1413(\(void\))X
+10 s 1 f F
+555 1084(A)N
+639(context)X
+901(switch)X
+1136(halts)X
+1313(the)X
+1437(current)X
+1691(\(old\))X
+1872(thread)X
+2098(and)X
+2239(runs)X
+2402(a)X
+2463(next)X
+2626(\(new\))X
+2839(thread.)X
+3105(There)X
+3318(are)X
+3442(two)X
+3587(forms:)X
+3821(one)X
+3962(aborts)X
+4183(and)X
+555 1188(destroys)N
+842(the)X
+960(current)X
+1208(thread.)X
+1469(The)X
+1614(other)X
+1799(merely)X
+2042(yields)X
+2253(the)X
+2371(current)X
+2619(thread)X
+2840(so)X
+2931(that)X
+3071(other)X
+3256(threads)X
+3508(can)X
+3640(run.)X
+755 1320(The)N
+7 f F
+901(stp_abort)X
+1 f F
+1354(routine)X
+1602(selects)X
+1837(a)X
+1894(new)X
+2049(thread)X
+2271(to)X
+2354(run,)X
+2502(changes)X
+2782(the)X
+2901(notion)X
+3126(of)X
+3214(the)X
+3333(currently-running)X
+3920(thread,)X
+4161(then)X
+555 1424(aborts)N
+775(the)X
+897(old)X
+1023(thread,)X
+1268(calling)X
+7 f F
+1510(stp_aborthelp)X
+1 f F
+2157(to)X
+2242(clean)X
+2435(up.)X
+2578(Since)X
+2779(the)X
+2900(main)X
+3083(thread)X
+3307(is)X
+3383(in)X
+3468(the)X
+3589(run)X
+3719(queue,)X
+3954(there)X
+4138(is)X
+4214(al-)X
+555 1528(ways)N
+740(a)X
+796(next)X
+954(thread)X
+1175(and)X
+1311(never)X
+1510(a)X
+1566(need)X
+1738(to)X
+1820(check)X
+2028(if)X
+7 f F
+2097(stp_qget)X
+1 f F
+2501(returned)X
+7 f F
+2789(NULL)X
+1 f F
+(.)S
+8 s 7 f F
+919 1664(void)N
+843 1752(stp_abort)N
+1223(\(void\))X
+843 1840({)N
+919 1928(stp_t)N
+1147(*old,)X
+1375(*new;)X
+919 2104(new)N
+1071(=)X
+1147(stp_qget)X
+1489(\(&stp_global_runq)X
+2135(\);)X
+919 2192(old)N
+1071(=)X
+1147(stp_global_curr;)X
+919 2280(stp_global_curr)N
+1527(=)X
+1603(new;)X
+919 2368(QT_ABORT)N
+1261(\(stp_aborthelp,)X
+1869(old,)X
+2059(NULL,)X
+2287(new->sp\);)X
+843 2456(})N
+10 s 1 f F
+755 2636(The)N
+912(helper)X
+7 f F
+1145(stp_aborthelp)X
+1 f F
+1801(runs)X
+1971(after)X
+2150(the)X
+2279(old)X
+2412(thread)X
+2644(has)X
+2782(been)X
+2965(halted)X
+3192(completely.)X
+3619(It)X
+3699(simply)X
+3947(deletes)X
+4201(the)X
+555 2740(storage)N
+813(associated)X
+1169(with)X
+1337(the)X
+1461(old)X
+1589(thread.)X
+1855(The)X
+2005(helper)X
+7 f F
+2231(stp_aborthelp)X
+1 f F
+2880(runs)X
+3043(on)X
+3148(the)X
+3271(stack)X
+3461(of)X
+3553(the)X
+3676(new)X
+3835(thread,)X
+4081(so)X
+4177(it)X
+4246(is)X
+555 2844(safe)N
+705(to)X
+787(delete)X
+999(the)X
+1117(stack)X
+1302(of)X
+1389(the)X
+1507(old)X
+1629(thread.)X
+1890(When)X
+7 f F
+2102(stp_aborthelp)X
+1 f F
+2746(returns,)X
+3009(the)X
+3127(new)X
+3281(thread)X
+3502(is)X
+3575(resumed.)X
+8 s 7 f F
+919 2980(static)N
+1185(void)X
+1375(*)X
+843 3068(stp_aborthelp)N
+1375(\(qt_t)X
+1603(*sp,)X
+1793(void)X
+1983(*old,)X
+2211(void)X
+2401(*unused\))X
+843 3156({)N
+919 3244(free)N
+1109(\(\(\(stp_t)X
+1451(*\)old\)->stk\);)X
+919 3332(free)N
+1109(\(old\);)X
+843 3420(})N
+10 s 1 f F
+755 3600(Yielding)N
+1065(is)X
+1148(similar,)X
+1420(but)X
+1551(the)X
+1678(helper)X
+1908(function)X
+2204(is)X
+2286(called)X
+2507(with)X
+2678(a)X
+2743(pointer)X
+2999(to)X
+3090(the)X
+3217(queue)X
+3438(on)X
+3547(which)X
+3772(to)X
+3863(block)X
+4070(the)X
+4197(old)X
+555 3704(thread.)N
+822(The)X
+973(helper)X
+1200(function)X
+1493(is)X
+7 f F
+1572(stp_yieldhelp)X
+1 f F
+(,)S
+2241(described)X
+2574(above.)X
+2831(For)X
+2967(yielding,)X
+3274(the)X
+3397(queue)X
+3614(is)X
+3692(just)X
+3832(the)X
+3955(run)X
+4087(queue.)X
+555 3808(Semaphores)N
+967(and)X
+1103(monitors)X
+1407(\(if)X
+1503(implemented\))X
+1968(would)X
+2188(use)X
+2315(different)X
+2612(queues.)X
+8 s 7 f F
+919 3944(void)N
+843 4032(stp_yield\(\))N
+843 4120({)N
+919 4208(stp_t)N
+1147(*old,)X
+1375(*new;)X
+919 4384(new)N
+1071(=)X
+1147(stp_qget)X
+1489(\(&stp_global_runq)X
+2135(\);)X
+919 4472(old)N
+1071(=)X
+1147(stp_global_curr;)X
+919 4560(stp_global_curr)N
+1527(=)X
+1603(new;)X
+919 4648(QT_BLOCK)N
+1261(\(stp_yieldhelp,)X
+1869(old,)X
+2059(&stp_global_runq,)X
+2743(new->sp\);)X
+843 4736(})N
+10 s 1 f F
+755 4916(QuickThreads)N
+1235(does)X
+1407(not)X
+1534(allow)X
+1737(a)X
+1798(thread)X
+2024(to)X
+2111(context)X
+2372(switch)X
+2606(to)X
+2693(itself.)X
+2918(Thus,)X
+3122(whenever)X
+3459(a)X
+3519(thread)X
+3744(yields)X
+3959(there)X
+4144(must)X
+555 5020(be)N
+657(another)X
+924(runable)X
+1191(thread.)X
+1458(In)X
+1551(SimpleThreads,)X
+2082(the)X
+2205(main)X
+2390(thread)X
+2616(is)X
+2694(always)X
+2942(in)X
+3029(the)X
+3152(runable)X
+3418(queue,)X
+3655(so)X
+3751(there)X
+3937(is)X
+4015(always)X
+4263(a)X
+555 5124(new)N
+717(thread)X
+946(to)X
+1036(run.)X
+1211(A)X
+1297(different)X
+1602(implementation)X
+2132(might)X
+2345(store)X
+2528(the)X
+2653(main)X
+2840(thread)X
+3068(elsewhere,)X
+3437(in)X
+3526(which)X
+3749(case)X
+7 f F
+3915(stp_qget)X
+1 f F
+555 5228(could)N
+764(return)X
+7 f F
+987(NULL)X
+1 f F
+(.)S
+1250(All)X
+1383(routines)X
+1672(that)X
+1823(call)X
+7 f F
+1969(stp_qget)X
+1 f F
+2383(would)X
+2613(then)X
+2781(need)X
+2963(to)X
+3055(check)X
+3273(the)X
+3401(return)X
+3623(value.)X
+7 f F
+3867(stp_abort)X
+1 f F
+555 5332(would)N
+786(interpret)X
+7 f F
+1088(NULL)X
+1 f F
+1310(to)X
+1402(mean)X
+1606(that)X
+1756(SimpleThreads)X
+2271(should)X
+2514(halt.)X
+7 f F
+2704(stp_yield)X
+1 f F
+3166(would)X
+3396(use)X
+7 f F
+3533(NULL)X
+1 f F
+3755(to)X
+3847(mean)X
+4051(that)X
+4201(the)X
+555 5436(current)N
+806(thread)X
+1030(is)X
+1106(the)X
+1227(only)X
+1392(runable)X
+1656(thread,)X
+1900(so)X
+7 f F
+1994(stp_yield)X
+1 f F
+2449(should)X
+2685(return,)X
+2920(continuing)X
+3285(the)X
+3406(thread,)X
+3649(rather)X
+3859(than)X
+4019(blocking)X
+555 5540(and)N
+691(letting)X
+915(another)X
+1176(thread)X
+1397(run.)X
+755 5672(Note)N
+935(that)X
+1079(in)X
+1165(the)X
+1287(current)X
+1539(implementation,)X
+2085(the)X
+2207(main)X
+2391(thread)X
+2616(cannot)X
+2854(call)X
+7 f F
+2993(stp_abort)X
+1 f F
+3448(or)X
+7 f F
+3538(stp_yield)X
+1 f F
+(.)S
+4033(If)X
+4110(it)X
+4177(did,)X
+555 5776(there)N
+736(might)X
+942(not)X
+1064(be)X
+1160(another)X
+1421(runable)X
+1682(thread)X
+1903(\(also,)X
+7 f F
+2099(stp_global_curr)X
+1 f F
+2839(might)X
+3045(not)X
+3167(be)X
+3263(set)X
+3372(correctly\).)X
+
+%%Page: 13 13
+13 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(13)X
+2487(-)X
+3 f F
+555 680(5.)N
+655(Considerations)X
+1190(and)X
+1338(Idioms)X
+1 f F
+555 812(This)N
+727(section)X
+984(discusses)X
+1312(some)X
+1510(issues)X
+1730(to)X
+1821(be)X
+1926(considered)X
+2303(when)X
+2506(using)X
+2708(QuickThreads,)X
+3212(some)X
+3410(common)X
+3719(idioms,)X
+3985(and)X
+4130(some)X
+555 916(uses)N
+713(of)X
+800(\257exible)X
+1060(scheduling.)X
+3 f F
+555 1124(5.1.)N
+715(Context)X
+1007(Switching)X
+1364(Models)X
+1 f F
+555 1256(QuickThreads)N
+1035(can)X
+1172(be)X
+1273(used)X
+1445(to)X
+1532(emulate)X
+1811(several)X
+2064(other)X
+2254(context)X
+2515(switching)X
+2851(models:)X
+3129(locking)X
+3394(across)X
+3620(context)X
+3881(switches,)X
+4201(us-)X
+555 1360(ing)N
+677(scheduler)X
+1005(threads,)X
+1277(etc.)X
+755 1492(One)N
+912(model)X
+1135(holds)X
+1331(the)X
+1452(lock)X
+1613(across)X
+1837(a)X
+1896(context)X
+2155(switch)X
+2387(by)X
+2490(performing)X
+2874(the)X
+2 f F
+2994(lock)X
+1 f F
+3150(operation)X
+3475(before)X
+3703(calling)X
+3943(the)X
+4063(context)X
+555 1596(switch)N
+794(primitive)X
+1117(and)X
+1263(performing)X
+2 f F
+1654(unlock)X
+1 f F
+1898(in)X
+1990(the)X
+2117(helper)X
+2347(function.)X
+2683(However,)X
+3027(lock)X
+3194(holding)X
+3467(times)X
+3669(will)X
+3822(be)X
+3927(longer)X
+4161(than)X
+555 1700(with)N
+717(hand-coded)X
+1112(packages.)X
+755 1832(Another)N
+1039(model)X
+1260(returns)X
+1504(control)X
+1752(to)X
+1835(a)X
+1892(central)X
+2132(scheduler)X
+2461(thread.)X
+2723(Since)X
+2922(QuickThreads)X
+3398(returns)X
+3642(only)X
+3805(a)X
+3861(single)X
+4072(pointer)X
+555 1936(value,)N
+769(multiple)X
+1055(values)X
+1280(are)X
+1399(passed)X
+1633(in)X
+1715(memory,)X
+2022(pointed)X
+2282(to)X
+2364(by)X
+2464(the)X
+2582(single)X
+2793(return)X
+3005(pointer.)X
+755 2068(A)N
+836(third)X
+1010(model)X
+1233(uses)X
+1394(\252lightweight\272)X
+1853(scheduler)X
+2184(threads)X
+2439(that)X
+2582(are)X
+2703(simply)X
+2942(stacks)X
+3160(for)X
+3276(helper)X
+3499(functions)X
+3819(to)X
+3903(run)X
+4032(on.)X
+4174(The)X
+555 2172(stacks)N
+779(have)X
+959(no)X
+1067(underlying)X
+1442(thread,)X
+1691(so)X
+1790(the)X
+1916(helper)X
+2145(function)X
+2440(must)X
+2623(never)X
+2830(return.)X
+3090(The)X
+3243(helper)X
+3472(function)X
+3767(instead)X
+4022(selects)X
+4263(a)X
+555 2276(new)N
+709(thread,)X
+950(then)X
+1108(runs)X
+1266(the)X
+1384(new)X
+1538(thread)X
+1759(by)X
+1859(aborting)X
+2146(itself.)X
+3 f F
+555 2484(5.2.)N
+715(Multiprocessors)X
+1 f F
+555 2616(QuickThreads)N
+1035(uses)X
+1198(no)X
+1303(global)X
+1528(state.)X
+1740(However,)X
+2080(the)X
+2203(client)X
+2406(threads)X
+2663(package)X
+2951(must)X
+3130(be)X
+3230(concerned)X
+3585(about)X
+3787(synchronization)X
+555 2720(and)N
+699(sharing)X
+963(for)X
+1085(the)X
+1210(queues)X
+1460(that)X
+1607(maintain)X
+1914(threads)X
+2173(between)X
+2468(context)X
+2731(switches,)X
+3054(and)X
+3197(the)X
+3322(client)X
+3527(must)X
+3709(also)X
+3865(be)X
+3968(concerned)X
+555 2824(with)N
+723(maintaining)X
+1131(the)X
+1255(notion)X
+1485(of)X
+1578(the)X
+1702(current)X
+1956(thread.)X
+2223(Thus,)X
+2429(the)X
+2553(client)X
+2757(must)X
+2938(ensure)X
+3173(threads)X
+3430(are)X
+3554(properly)X
+3851(synchronized.)X
+555 2928(The)N
+700(following)X
+1031(describes)X
+1350(some)X
+1539(synchronization)X
+2071(issues)X
+2282(that)X
+2422(must)X
+2597(be)X
+2693(managed)X
+3003(by)X
+3103(the)X
+3221(client)X
+3419(threads)X
+3671(package.)X
+755 3060(The)N
+900(queue)X
+1112(access)X
+1338(functions)X
+1656(must)X
+1831(be)X
+1927(coded)X
+2139(for)X
+2253(multiprocessor)X
+2749(synchronization.)X
+755 3192(If)N
+832(the)X
+953(machine)X
+1248(has)X
+1378(per-processor)X
+1839(private)X
+2085(memory,)X
+2395(the)X
+2516(notion)X
+2743(of)X
+2833(the)X
+2954(current)X
+3205(thread)X
+3429(can)X
+3564(be)X
+3663(private)X
+3909(to)X
+3994(each)X
+4165(pro-)X
+555 3296(cessor.)N
+824(If)X
+906(not,)X
+1056(the)X
+1181(current)X
+1436(thread)X
+1664(must)X
+1846(be)X
+1949(derived)X
+2217(from)X
+2400(the)X
+2525(stack)X
+2717(pointer,)X
+2991(as)X
+3085(in)X
+3174(Amber)X
+3424([Cha90])X
+3714(and)X
+3857(threads)X
+4116(under)X
+555 3400(scheduler)N
+883(activations)X
+1250([BMVL92],)X
+1655(or)X
+1742(a)X
+1798(machine)X
+2090(register)X
+2351(must)X
+2526(be)X
+2622(set)X
+2731(aside)X
+2916(to)X
+2998(point)X
+3182(to)X
+3264(the)X
+3382(thread.)X
+755 3532(Multithreaded)N
+1233(applications)X
+1644(often)X
+1833(use)X
+1964(one)X
+2104(process)X
+2369(per)X
+2495(processor)X
+2826(and)X
+2965(multiplex)X
+3294(threads)X
+3549(on)X
+3652(top)X
+3777(of)X
+3867(each)X
+4038(process.)X
+555 3636(The)N
+706(stacks)X
+928(associated)X
+1284(with)X
+1452(the)X
+1576(initial)X
+1788(processes)X
+2122(are)X
+2247(called)X
+2 f F
+2465(main)X
+2651(threads)X
+1 f F
+2891(.)X
+2957(With)X
+3143(several)X
+3397(processors)X
+3761(there)X
+3947(are)X
+4071(several)X
+555 3740(main)N
+748(threads.)X
+1053(Typically,)X
+1413(main)X
+1606(threads)X
+1871(cannot)X
+2118(be)X
+2227(stored)X
+2456(in)X
+2551(the)X
+2682(runable)X
+2956(queue.)X
+3221(On)X
+3352(machines)X
+3687(with)X
+3861(per-processor)X
+555 3844(private)N
+809(memory,)X
+1127(some)X
+1327(virtual)X
+1566(addresses)X
+9 f F
+1904(-)X
+1 f F
+1978(notably,)X
+2268(those)X
+2467(used)X
+2644(for)X
+2768(main)X
+2958(thread)X
+3189(stacks)X
+9 f F
+3415(-)X
+1 f F
+3489(access)X
+3725(different)X
+4032(memory)X
+555 3948(depending)N
+918(on)X
+1027(which)X
+1252(processor)X
+1588(issues)X
+1807(the)X
+1933(reference.)X
+2302(Thus,)X
+2510(main)X
+2698(threads)X
+2958(must)X
+3141(be)X
+3245(per-processor)X
+3711(and)X
+3855(stored)X
+4079(in)X
+4169(per-)X
+555 4052(processor)N
+884(memory.)X
+1212(On)X
+1331(machines)X
+1655(without)X
+1920(private)X
+2164(memory,)X
+2472(care)X
+2628(is)X
+2702(needed)X
+2951(storing)X
+3194(main)X
+3374(threads)X
+3626(in)X
+3708(the)X
+3826(runable)X
+4087(queue,)X
+555 4156(since)N
+748(when)X
+950(one)X
+1094(processor)X
+1430(is)X
+1511(context)X
+1775(switching,)X
+2134(neither)X
+2385(the)X
+2511(old)X
+2641(thread)X
+2870(nor)X
+3005(the)X
+3131(new)X
+3293(thread)X
+3522(is)X
+3603(in)X
+3693(the)X
+3819(runable)X
+4087(queue.)X
+555 4260(Thus,)N
+758(if)X
+830(a)X
+889(processor)X
+1220(switches)X
+1519(between)X
+1810(two)X
+1953(main)X
+2136(threads,)X
+2411(there)X
+2595(are)X
+2717(brie\257y)X
+2948(fewer)X
+3154(available)X
+3466(main)X
+3648(threads)X
+3902(than)X
+4062(proces-)X
+555 4364(sors.)N
+755 4496(On)N
+875(a)X
+933(uniprocessor,)X
+1385(an)X
+1483(empty)X
+1705(runable)X
+1968(queue)X
+2182(indicates)X
+2489(that)X
+2631(there)X
+2814(is)X
+2889(no)X
+2991(more)X
+3178(available)X
+3490(work.)X
+3717(On)X
+3837(a)X
+3894(multiproces-)X
+555 4600(sor,)N
+703(the)X
+831(runable)X
+1102(queue)X
+1324(can)X
+1466(be)X
+1572(empty,)X
+1822(but)X
+1954(running)X
+2233(threads)X
+2495(on)X
+2605(other)X
+2800(processors)X
+3169(can)X
+3311(create)X
+3533(new)X
+3696(work.)X
+3930(Thus,)X
+4139(main)X
+555 4704(threads)N
+807(must)X
+982(terminate)X
+1305(only)X
+1467(when)X
+1661(all)X
+1761(processors)X
+2120(are)X
+2239(idle.)X
+3 f F
+555 4912(5.3.)N
+715(Multiple)X
+1028(Run)X
+1194(Queues)X
+1 f F
+555 5044(Since)N
+765(QuickThreads)X
+1251(does)X
+1429(not)X
+1562(de\256ne)X
+1789(run)X
+1927(queues,)X
+2201(applications)X
+2619(can)X
+2762(use)X
+2900(multiple)X
+3197(queues)X
+3451(and)X
+3598(scheduling)X
+3976(strategies.)X
+555 5148(Multiple)N
+851(queues)X
+1095(can)X
+1228(be)X
+1324(used)X
+1491(various)X
+1747(ways.)X
+1972(For)X
+2103(example,)X
+2415(libraries)X
+2698(can)X
+2830(be)X
+2926(implemented)X
+3364(using)X
+3557(threads)X
+3809(and)X
+3945(coroutines,)X
+555 5252(without)N
+823(regard)X
+1053(for)X
+1171(whether)X
+1454(the)X
+1576(rest)X
+1716(of)X
+1807(the)X
+1929(application)X
+2309(uses)X
+2471(threads.)X
+2767(Also,)X
+2961(threads)X
+3216(used)X
+3386(to)X
+3471(implement)X
+3836(simple)X
+4072(control)X
+555 5356(transfer)N
+827(\(e.g.,)X
+1015(coroutines\))X
+1401(can)X
+1538(be)X
+1639(implemented)X
+2082(cheaply,)X
+2377(even)X
+2554(though)X
+2801(other)X
+2991(threads)X
+3248(in)X
+3335(the)X
+3458(same)X
+3648(application)X
+4029(may)X
+4192(use)X
+555 5460(more)N
+741(complicated)X
+1154(and)X
+1291(expensive)X
+1633(control)X
+1881(transfer)X
+2148(rules)X
+2325(\(e.g.,)X
+2509(priority)X
+2770(scheduling\).)X
+3205(Further,)X
+3482(simple)X
+3716(queue)X
+3929(status,)X
+4152(such)X
+555 5564(as)N
+647(\252queue)X
+900(empty\272,)X
+1181(can)X
+1318(be)X
+1419(used)X
+1591(to)X
+1678(mark)X
+1868(particular)X
+2201(conditions,)X
+2579(e.g.,)X
+2740(\252all)X
+2881(threads)X
+3138(have)X
+3315(reached)X
+3591(the)X
+3713(barrier\272;)X
+4010(in)X
+4096(a)X
+4156(con-)X
+555 5668(ventional)N
+885(threads)X
+1149(package,)X
+1465(the)X
+1595(queue)X
+1819(may)X
+1989(be)X
+2097(inaccessible)X
+2517(\(buried)X
+2781(in)X
+2875(the)X
+3005(implementation\))X
+3566(or)X
+3665(there)X
+3858(may)X
+4027(be)X
+4134(other)X
+555 5772(\(non-barrier\))N
+997(threads)X
+1255(in)X
+1343(the)X
+1467(run)X
+1600(queue.)X
+1858(Finally,)X
+2130(When)X
+2348(the)X
+2472(number)X
+2743(of)X
+2836(threads)X
+3094(is)X
+3173(known,)X
+3436(it)X
+3505(is)X
+3583(possible)X
+3870(to)X
+3957(implement)X
+
+%%Page: 14 14
+14 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(14)X
+2487(-)X
+555 680(run)N
+682(queues)X
+925(using)X
+1118(faster)X
+1317(\256xed-size)X
+1649(data)X
+1803(structures)X
+2135(such)X
+2302(as)X
+2389(arrays)X
+2606(instead)X
+2853(of)X
+2940(linked)X
+3160(lists.)X
+3 f F
+555 888(5.4.)N
+715(Blocking)X
+1036(Critical)X
+1319(Sections)X
+2 f F
+555 1020(Blocking)N
+865(critical)X
+1121(sections)X
+1 f F
+1404(test)X
+1540(a)X
+1601(condition)X
+1928(and,)X
+2089(if)X
+2163(true,)X
+2333(block)X
+2536(the)X
+2659(current)X
+2912(thread)X
+3138(on)X
+3243(a)X
+3304(queue.)X
+3561(If)X
+3640(testing)X
+3878(and)X
+4019(blocking)X
+555 1124(are)N
+681(not)X
+810(a)X
+873(single)X
+1091(atomic)X
+1336(operation,)X
+1686(a)X
+1749(race)X
+1911(can)X
+2050(arise)X
+2229(when)X
+2430(the)X
+2555(condition)X
+2884(goes)X
+3058(false)X
+3237(between)X
+3532(the)X
+3657(test)X
+3795(and)X
+3938(the)X
+4063(context)X
+555 1228(switch.)N
+833(QuickThreads)X
+1317(does)X
+1493(not)X
+1624(provide)X
+1897(atomic)X
+2143(testing)X
+2384(and)X
+2528(enqueing;)X
+2872(clients)X
+3109(can)X
+3249(supply)X
+3490(several)X
+3746(implementations,)X
+555 1332(with)N
+717(tradeoffs.)X
+755 1464(On)N
+879(non-preemptive)X
+1413(uniprocessors,)X
+1900(no)X
+2006(other)X
+2197(threads)X
+2455(run)X
+2588(between)X
+2882(the)X
+3006(test)X
+3142(and)X
+3283(the)X
+3406(block,)X
+3629(so)X
+3725(no)X
+3830(race)X
+3990(can)X
+4127(arise.)X
+555 1568(On)N
+676(preemptive)X
+1060(uniprocessors,)X
+1544(preemption)X
+1932(can)X
+2067(be)X
+2166(disabled,)X
+2475(deferred,)X
+2786(or)X
+2875(squashed)X
+3191(so)X
+3284(that)X
+3426(no)X
+3528(threads)X
+3782(run)X
+3911(between)X
+4201(the)X
+555 1672(test)N
+691(and)X
+832(enqueue;)X
+1147(alternatively,)X
+1593(the)X
+1716(enqueue)X
+2009(can)X
+2146(check)X
+2359(if)X
+2433(there)X
+2619(was)X
+2769(a)X
+2830(preemption)X
+3220(and)X
+3361(retry,)X
+3558(as)X
+3650(with)X
+3817(optimistic)X
+4161(syn-)X
+555 1776(chronization)N
+976([Her88].)X
+755 1908(On)N
+877(multiprocessors,)X
+1428(the)X
+1550(current)X
+1802(thread)X
+2027(can)X
+2162(acquire)X
+2422(a)X
+2481(lock)X
+2642(while)X
+2843(testing)X
+3079(the)X
+3200(condition,)X
+3545(then)X
+3706(hold)X
+3871(the)X
+3992(lock)X
+4153(until)X
+555 2012(the)N
+676(thread)X
+900(has)X
+1030(been)X
+1205(blocked)X
+1482(and)X
+1621(put)X
+1746(on)X
+1849(the)X
+1970(blocked)X
+2247(queue.)X
+2502(This)X
+2667(technique)X
+3002(is)X
+3078(used)X
+3248(by)X
+3351(many)X
+3552(threads)X
+3807(packages.)X
+4165(One)X
+555 2116(disadvantage)N
+994(is)X
+1067(that)X
+1207(locks)X
+1396(are)X
+1515(held)X
+1673(across)X
+1894(context)X
+2150(save)X
+2313(and)X
+2449(restore,)X
+2708(increasing)X
+3058(lock)X
+3216(holding)X
+3480(times)X
+3673(and)X
+3809(contention.)X
+755 2248(Another)N
+1040(choice)X
+1272(is)X
+1347(to)X
+1431(have)X
+1605(the)X
+1725(current)X
+1975(thread)X
+2198(test)X
+2331(the)X
+2451(condition)X
+2774(and)X
+2911(block)X
+2 f F
+3110(tentatively)X
+1 f F
+3444(.)X
+3505(The)X
+3651(helper)X
+3873(function)X
+4161(then)X
+555 2352(atomically)N
+915(retests)X
+1142(the)X
+1262(condition)X
+1586(and)X
+1724(enqueues)X
+2045(the)X
+2165(thread)X
+2388(if)X
+2459(the)X
+2579(condition)X
+2902(is)X
+2976(still)X
+3116(true.)X
+3302(If)X
+3377(the)X
+3496(condition)X
+3819(has)X
+3947(meanwhile)X
+555 2456(gone)N
+737(false,)X
+935(the)X
+1059(blocking)X
+1365(thread)X
+1592(is)X
+1671(put)X
+1799(in)X
+1887(the)X
+2010(runable)X
+2276(queue.)X
+2533(When)X
+2750(the)X
+2873(thread)X
+3099(restarts,)X
+3376(it)X
+3445(retests)X
+3675(the)X
+3798(condition.)X
+4165(One)X
+555 2560(disadvantage)N
+1001(is)X
+1081(the)X
+1206(cost)X
+1362(of)X
+1456(excess)X
+1692(context)X
+1954(switches.)X
+2296(Another)X
+2585(is)X
+2664(that)X
+2810(a)X
+2872(thread)X
+3099(which)X
+3321(was)X
+3472(ready)X
+3677(to)X
+3765(enter)X
+3952(the)X
+4076(critical)X
+555 2664(section)N
+802(is)X
+875(now)X
+1033(delayed,)X
+1323(which)X
+1539(may)X
+1697(cause)X
+1896(latency)X
+2148(problems)X
+2466([ELZ86])X
+2767(or)X
+2854(starvation.)X
+755 2796(Some)N
+961(of)X
+1052(the)X
+1174(latency)X
+1430(and)X
+1570(starvation)X
+1910(problems)X
+2232(can)X
+2368(be)X
+2468(solved)X
+2701(by)X
+2805(blocking)X
+3109(tentatively,)X
+3490(then)X
+3651(restarting)X
+3977(the)X
+4098(thread)X
+555 2900(if)N
+628(the)X
+750(condition)X
+1076(has)X
+1207(gone)X
+1387(false)X
+1563(during)X
+1796(the)X
+1918(context)X
+2178(switch.)X
+2451(In)X
+2542(order)X
+2736(to)X
+2822(perform)X
+3105(the)X
+3227(tentative)X
+3527(context)X
+3787(switch,)X
+4039(a)X
+4098(thread)X
+555 3004(was)N
+703(removed)X
+1007(from)X
+1186(the)X
+1307(runable)X
+1571(queue.)X
+1826(When)X
+2041(the)X
+2162(blocking)X
+2465(thread)X
+2689(is)X
+2765(restarted,)X
+3085(the)X
+3206(new)X
+3363(thread)X
+3587(is)X
+3663(put)X
+3787(back)X
+3961(in)X
+4045(the)X
+4165(run-)X
+555 3108(able)N
+714(queue.)X
+971(Since)X
+1174(the)X
+1297(new)X
+1456(thread)X
+1682(was)X
+1832(never)X
+2036(actually)X
+2315(run,)X
+2467(the)X
+2590(stack)X
+2779(pointer)X
+3030(remains)X
+3308(unchanged,)X
+3700(and)X
+3840(the)X
+3962(thread)X
+4187(can)X
+555 3212(simply)N
+792(be)X
+888(reinserted)X
+1225(in)X
+1307(the)X
+1425(runable)X
+1686(queue.)X
+3 f F
+555 3420(5.5.)N
+715(Barriers)X
+1 f F
+555 3552(A)N
+2 f F
+639(barrier)X
+1 f F
+896(is)X
+975(a)X
+1037(control)X
+1290(construct,)X
+1630(where)X
+1853(no)X
+1959(thread)X
+2186(can)X
+2324(pass)X
+2488(the)X
+2612(barrier)X
+2853(until)X
+3025(all)X
+3131(of)X
+3224(a)X
+3285(set)X
+3399(of)X
+3491(threads)X
+3748(have)X
+3925(reached)X
+4201(the)X
+555 3656(barrier.)N
+835(A)X
+918(typical)X
+1161(implementation)X
+1688(initializes)X
+2024(the)X
+2147(barrier)X
+2387(with)X
+2554(a)X
+2615(count)X
+2818(of)X
+2910(the)X
+3033(number)X
+3303(of)X
+3395(threads,)X
+3671(and)X
+3811(decrements)X
+4201(the)X
+555 3760(count)N
+764(as)X
+862(each)X
+1041(thread)X
+1273(reaches)X
+1546(the)X
+1675(barrier.)X
+1961(Each)X
+2153(decrement)X
+2519(requires)X
+2809(synchronization,)X
+3372(so)X
+3474(the)X
+3603(barrier)X
+3849(cost)X
+4009(scales)X
+4232(as)X
+2 f F
+555 3864(O\(Nthreads\).)N
+1 f F
+755 3996(An)N
+878(alternative)X
+1242(is)X
+1320(to)X
+1407(keep)X
+1584(a)X
+1645(per-processor)X
+2108(count)X
+2311(of)X
+2403(the)X
+2525(number)X
+2794(of)X
+2885(threads)X
+3141(that)X
+3285(have)X
+3461(reached)X
+3736(the)X
+3858(barrier)X
+4097(and)X
+4237(to)X
+555 4100(ensure)N
+790(that)X
+935(only)X
+1102(barrier)X
+1342(threads)X
+1599(are)X
+1723(in)X
+1810(the)X
+1933(\(current\))X
+2240(run)X
+2372(queue.)X
+2629(When)X
+2846(the)X
+2969(run)X
+3101(queue)X
+3318(goes)X
+3489(empty,)X
+3733(the)X
+3855(processor)X
+4187(can)X
+555 4204(decrement)N
+916(the)X
+1040(shared)X
+1276(count)X
+1480(by)X
+1586(the)X
+1710(number)X
+1981(of)X
+2074(threads)X
+2332(that)X
+2478(have)X
+2656(been)X
+2834(run)X
+2967(by)X
+3073(that)X
+3219(processor.)X
+3593(Thus,)X
+3798(the)X
+3921(barrier)X
+4161(syn-)X
+555 4308(chronization)N
+976(cost)X
+1125(scales)X
+1337(as)X
+2 f F
+1424(O\(Nprocessors\))X
+1 f F
+1956(instead)X
+2203(of)X
+2 f F
+2290(O\(Nthreads\))X
+1 f F
+2695(.)X
+755 4440(Another)N
+1041(alternative)X
+1403(is)X
+1479(to)X
+1564(use)X
+1693(a)X
+1751(tree)X
+1894(that)X
+2036(synchronizes)X
+2477(pairs)X
+2655(of)X
+2744(threads,)X
+3018(then)X
+3178(pairs)X
+3356(of)X
+3445(pair-synchronized)X
+4047(threads,)X
+555 4544(and)N
+705(so)X
+810(on.)X
+964(Although)X
+1300(the)X
+1432(total)X
+1608(number)X
+1887(of)X
+1988(synchronization)X
+2534(operations)X
+2902(increases)X
+3230(to)X
+2 f F
+3325(O\(N)X
+1 f F
+3463(lg)X
+8 s F
+3525 4576(2)N
+10 s 2 f F
+4544(N\))Y
+1 f F
+3637(,)X
+3690(the)X
+3821(parallelism)X
+4210(in-)X
+555 4648(creases)N
+823(and)X
+974(the)X
+1107(worst-case)X
+1486(synchronization)X
+2033(time)X
+2210(is)X
+2 f F
+2298(O\()X
+1 f F
+2383(lg)X
+8 s F
+2445 4680(2)N
+10 s 2 f F
+4648(N\))Y
+1 f F
+2557(.)X
+2632(Traditional)X
+3023(threads)X
+3290(packages)X
+3620(synchronize)X
+4042(pairs)X
+4232(of)X
+555 4752(threads)N
+812(so)X
+908(the)X
+1031(barrier)X
+1271(cost)X
+1425(scales)X
+1642(as)X
+2 f F
+1734(O\()X
+1 f F
+1819(lg)X
+8 s F
+1881 4784(2)N
+10 s 2 f F
+4752(Nthreads\))Y
+1 f F
+2233(.)X
+2298(The)X
+2448(same)X
+2638(technique)X
+2975(can)X
+3112(be)X
+3213(used)X
+3385(with)X
+3552(per-barrier)X
+3922(run)X
+4054(queues:)X
+555 4856(instead)N
+812(of)X
+909(synchronizing)X
+1393(threads,)X
+1674(the)X
+1801(tree)X
+1951(synchronizes)X
+2399(pairs)X
+2584(of)X
+2680(processors.)X
+3088(Thus,)X
+3297(barrier)X
+3541(synchronization)X
+4082(can)X
+4223(be)X
+555 4960(performed)N
+910(in)X
+2 f F
+992(O\()X
+1 f F
+1077(lg)X
+8 s F
+1139 4992(2)N
+10 s 2 f F
+4960(Nprocessors\))Y
+1 f F
+1618(synchronization)X
+2150(times.)X
+755 5092(With)N
+941(a)X
+1003(straightforward)X
+1524(run)X
+1657(queue)X
+1875(implementation,)X
+2423(there)X
+2610(are)X
+2 f F
+2735(O\(Nthreads\))X
+1 f F
+3166(synchronization)X
+3704(operations)X
+4064(that)X
+4209(re-)X
+555 5196(move)N
+755(threads)X
+1009(from)X
+1187(the)X
+1307(run)X
+1436(queue.)X
+1690(Distributed)X
+2072(run)X
+2201(queues)X
+2445(can)X
+2578(be)X
+2675(used)X
+2843(to)X
+2926(increase)X
+3211(parallelism)X
+3588(and)X
+3725(reduce)X
+3961(contention)X
+555 5300([ALL89],)N
+904(but)X
+1044(care)X
+1217(is)X
+1308(needed)X
+1574(because)X
+1867(straightforward)X
+2400(implementations)X
+2971(require)X
+2 f F
+3237(O\(Nprocessors\))X
+1 f F
+3787(synchronization)X
+555 5404(times)N
+748(to)X
+830(check)X
+1038(for)X
+1152(an)X
+1248(empty)X
+1468(run)X
+1595(queue.)X
+755 5564(Standard)N
+1068(barriers)X
+1341(can)X
+1480(have)X
+1659(arbitrary)X
+1963(threads)X
+2222(in)X
+2311(the)X
+2436(run)X
+2570(queue.)X
+2829(Barrier)X
+3084(implementations)X
+3644(using)X
+3844(QuickThreads)X
+555 5668(can)N
+697(use)X
+834(per-barrier)X
+1209(run)X
+1346(queues.)X
+1639(Threads)X
+1928(are)X
+2056(inserted)X
+2339(in)X
+2430(the)X
+2557(run)X
+2693(queue)X
+2914(only)X
+3085(when)X
+3288(the)X
+3415(barrier)X
+3659(is)X
+3741(being)X
+3948(\(re\)started.)X
+555 5772(Thus,)N
+758(a)X
+817(processor)X
+1148(queue)X
+1363(that)X
+1506(becomes)X
+1810(empty)X
+2032(never)X
+2233(needs)X
+2438(to)X
+2522(be)X
+2620(rechecked)X
+2969(during)X
+3200(a)X
+3258(barrier)X
+3495(operation.)X
+3860(It)X
+3931(is)X
+4006(thus)X
+4161(pos-)X
+
+%%Page: 15 15
+15 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(15)X
+2487(-)X
+555 680(sible)N
+727(to)X
+810(build)X
+995(a)X
+1052(run)X
+1180(queue)X
+1393(that)X
+1534(can)X
+1667(check)X
+1876(for)X
+1991(queue)X
+2204(empty)X
+2425(without)X
+2690(any)X
+2827(synchronization.)X
+8 s F
+3359 640(4)N
+10 s F
+3432 680(However,)N
+3767(thread)X
+3988(migration)X
+555 784(\(moving)N
+846(threads)X
+1098(from)X
+1274(busy)X
+1445(processors)X
+1804(to)X
+1886(idle)X
+2026(ones\))X
+2220(still)X
+2359(requires)X
+2638(synchronization)X
+3170(operations.)X
+3 f F
+555 992(5.6.)N
+715(Marker)X
+1003(Threads)X
+1 f F
+555 1124(A)N
+2 f F
+638(marker)X
+895(thread)X
+1 f F
+1129(or)X
+1221(just)X
+2 f F
+1361(marker)X
+1 f F
+1618(is)X
+1696(one)X
+1837(placed)X
+2072(strategically)X
+2489(in)X
+2576(the)X
+2699(run)X
+2831(queue)X
+3048(so)X
+3143(that)X
+3287(simply)X
+3528(running)X
+3801(the)X
+3923(thread)X
+4148(indi-)X
+555 1228(cates)N
+738(a)X
+796(special)X
+1041(queue)X
+1254(condition)X
+1577(that)X
+1718(the)X
+1837(marker)X
+2086(then)X
+2245(handles.)X
+8 s F
+2510 1188(5)N
+10 s F
+2583 1228(For)N
+2715(example,)X
+3028(a)X
+3085(marker)X
+3334(can)X
+3467(be)X
+3564(inserted)X
+3839(as)X
+3927(the)X
+4046(last)X
+4178(ele-)X
+555 1332(ment)N
+736(in)X
+819(a)X
+876(LIFO)X
+1075(\(stack\))X
+1315(run)X
+1443(queue.)X
+1696(The)X
+1842(marker)X
+2091(is)X
+2165(run)X
+2293(only)X
+2456(when)X
+2651(there)X
+2833(are)X
+2953(no)X
+3054(other)X
+3240(runable)X
+3502(threads.)X
+3794(The)X
+3939(marker)X
+4187(can)X
+555 1436(then)N
+713(allocate)X
+983(stacks)X
+1199(to)X
+1281(startable)X
+1573(threads,)X
+1845(check)X
+2053(for)X
+2167(deadlock,)X
+2497(start)X
+2655(the)X
+2773(next)X
+2931(phase)X
+3134(of)X
+3221(the)X
+3339(program,)X
+3651(etc.)X
+755 1568(Marker)N
+1022(threads)X
+1284(are)X
+1413(useful)X
+1638(because)X
+1922(they)X
+2089(put)X
+2220(control)X
+2476(in)X
+2567(a)X
+2632(single)X
+2852(place)X
+3051(rather)X
+3268(than)X
+3435(e.g.,)X
+3600(requiring)X
+3923(a)X
+3988(check)X
+4205(for)X
+555 1672(empty)N
+781(queue)X
+999(on)X
+1105(each)X
+1279(access.)X
+1551(However,)X
+1892(an)X
+1994(extra)X
+2181(context)X
+2443(switch)X
+2678(is)X
+2757(required)X
+3051(each)X
+3225(time)X
+3393(the)X
+3517(marker)X
+3771(is)X
+3850(invoked.)X
+4174(The)X
+555 1776(\252main\272)N
+810(thread)X
+1034(in)X
+1119(SimpleThreads)X
+1627(is)X
+1702(a)X
+1760(marker:)X
+2032(when)X
+2228(the)X
+2348(\252main\272)X
+2602(thread)X
+2825(runs,)X
+3005(it)X
+3071(checks)X
+3312(for)X
+3428(queue)X
+3642(empty)X
+3864(and,)X
+4022(if)X
+4093(neces-)X
+555 1880(sary,)N
+732(halts)X
+906(the)X
+1027(threads)X
+1282(package.)X
+1609(Because)X
+1900(the)X
+2021(\252main\272)X
+2275(thread)X
+2498(is)X
+2573(always)X
+2818(in)X
+2902(the)X
+3022(run)X
+3151(queue,)X
+3385(no)X
+3487(other)X
+3674(queue)X
+3888(access)X
+4116(needs)X
+555 1984(to)N
+637(check)X
+845(if)X
+914(the)X
+1032(queue)X
+1244(is)X
+1317(empty.)X
+755 2116(It)N
+824(is)X
+897(possible)X
+1179(to)X
+1261(have)X
+1433(multiple)X
+1719(marker)X
+1967(threads)X
+2219(in)X
+2301(a)X
+2357(queue.)X
+3 f F
+555 2324(5.7.)N
+715(Stackless)X
+1046(Threads)X
+1 f F
+555 2456(A)N
+635(stackless)X
+942(thread)X
+1165(is)X
+1240(also)X
+1390(called)X
+1603(a)X
+2 f F
+1660(thread)X
+1890(template)X
+1 f F
+2187([BLL88].)X
+2533(Since)X
+2732(threads)X
+2985(are)X
+3105(typically)X
+3406(small)X
+3600(except)X
+3831(for)X
+3946(their)X
+4114(stack,)X
+555 2560(deferring)N
+880(stack)X
+1075(allocation)X
+1421(can)X
+1563(reduce)X
+1808(memory)X
+2105(consumption)X
+2548(because)X
+2833(only)X
+3004(running)X
+3282(threads)X
+3543(have)X
+3724(stacks.)X
+3989(A)X
+4076(Quick-)X
+555 2664(Threads)N
+841(thread)X
+1068(is)X
+1147(represented)X
+1544(by)X
+1650(a)X
+1712(stack)X
+1903(pointer,)X
+2176(so)X
+2273(it)X
+2343(must)X
+2524(implicitly)X
+2860(have)X
+3038(a)X
+3100(stack.)X
+3331(The)X
+3482(client)X
+3686(can)X
+3824(build)X
+4014(stackless)X
+555 2768(threads)N
+807(several)X
+1055(ways:)X
+595 2900(\267)N
+675(The)X
+829(client)X
+1036(thread)X
+1266(is)X
+1348(allocated)X
+1667(without)X
+1940(a)X
+2005(stack.)X
+2239(All)X
+2370(threads)X
+2631(\(both)X
+2829(complete)X
+3152(and)X
+3297(stackless\))X
+3638(are)X
+3765(on)X
+3873(the)X
+3999(same)X
+4192(run)X
+675 3004(queue)N
+887(and)X
+1023(the)X
+1141(context)X
+1397(switch)X
+1626(code)X
+1798(checks)X
+2037(each)X
+2205(thread)X
+2426(and)X
+2562(assigns)X
+2813(a)X
+2869(stack)X
+3054(if)X
+3123(necessary.)X
+595 3136(\267)N
+675(Stackless)X
+1004(threads)X
+1267(are)X
+1397(put)X
+1530(on)X
+1641(a)X
+2 f F
+1708(startable)X
+1 f F
+2023(queue.)X
+2286(When)X
+2509(the)X
+2638(run)X
+2775(queue)X
+2997(goes)X
+3174(empty,)X
+3424(thread)X
+3655(templates)X
+3992(are)X
+4121(given)X
+675 3240(stacks)N
+897(and)X
+1039(made)X
+1239(runable.)X
+1546(Since)X
+1750(stack)X
+1941(allocation)X
+2283(takes)X
+2474(place)X
+2670(as)X
+2763(a)X
+2825(part)X
+2976(of)X
+3069(handling)X
+3375(an)X
+3477(empty)X
+3703(run)X
+3835(queue,)X
+4072(normal)X
+675 3344(context)N
+931(switches)X
+1227(run)X
+1354(at)X
+1432(full)X
+1563(speed.)X
+595 3476(\267)N
+675(Each)X
+859(thread)X
+1083(is)X
+1159(initialized)X
+1502(with)X
+1667(a)X
+1726(small)X
+1921(stack.)X
+2148(When)X
+2362(the)X
+2482(thread)X
+2705(starts)X
+2896(running,)X
+3187(the)X
+3307(thread's)X
+2 f F
+3588(startup)X
+1 f F
+3836(function)X
+4125(reini-)X
+675 3580(tializes)N
+928(the)X
+1052(thread)X
+1279(with)X
+1447(a)X
+1509(large)X
+1696(stack)X
+1887(and)X
+2029(restarts)X
+2287(it.)X
+2397(If)X
+2477(stack)X
+2668(allocation)X
+3010(is)X
+3089(nontrivial,)X
+3446(it)X
+3516(must)X
+3697(be)X
+3798(performed)X
+4158(by)X
+4263(a)X
+675 3684(thread)N
+896(with)X
+1058(a)X
+1114(normal-sized)X
+1553(stack.)X
+755 3816(With)N
+935(all)X
+1035(of)X
+1122(these)X
+1307(schemes,)X
+1619(the)X
+1737(non-varargs)X
+2141(case)X
+2300(is)X
+2373(fairly)X
+2567(straightforward,)X
+3102(but)X
+3224(varargs)X
+3481(is)X
+3554(harder.)X
+8 s F
+3780 3776(6)N
+10 s 3 f F
+555 4024(5.8.)N
+715(Parameter)X
+1102(Limits)X
+1344(for)X
+1467(Blocking)X
+1788(Routines)X
+1 f F
+555 4156(Blocking)N
+869(routines)X
+1148(pass)X
+1307(only)X
+1470(a)X
+1527(few)X
+1669(parameters)X
+2043(to)X
+2126(the)X
+2245(helper)X
+2467(function.)X
+2795(More)X
+2990(parameters)X
+3364(can)X
+3496(be)X
+3592(\252faked\272)X
+3863(by)X
+3963(having)X
+4201(the)X
+555 4260(caller)N
+757(push)X
+931(some)X
+1123(values)X
+1351(on)X
+1454(the)X
+1575(old)X
+1700(thread's)X
+1982(stack,)X
+2190(then)X
+2351(pass)X
+2512(a)X
+2571(pointer)X
+2821(to)X
+2906(that)X
+3049(storage)X
+3304(to)X
+3389(the)X
+3510(helper)X
+3733(function.)X
+4062(The)X
+4209(ra-)X
+555 4364(tionalle)N
+818(for)X
+935(passing)X
+1197(only)X
+1361(a)X
+1419(few)X
+1562(parameters)X
+1937(is)X
+2012(that)X
+2154(the)X
+2274(case)X
+2435(of)X
+2524(a)X
+2582(few)X
+2725(parameters)X
+3100(is)X
+3175(common,)X
+3497(passing)X
+3759(more)X
+3946(parameters)X
+555 4468(is)N
+628(expensive,)X
+989(and)X
+1125(that)X
+1265(having)X
+1503(the)X
+1621(\257exibility)X
+1951(to)X
+2033(pass)X
+2191(more)X
+2376(parameters)X
+2749(shouldn't)X
+3071(penalize)X
+3359(the)X
+3477(common)X
+3777(case.)X
+3 f F
+555 4676(5.9.)N
+715(Minimizing)X
+1130(Thread)X
+1403(State)X
+1 f F
+555 4808(In)N
+644(the)X
+763(SimpleThreads)X
+1269(example,)X
+1582(the)X
+1701(notion)X
+1926(of)X
+2014(the)X
+2133(current)X
+2382(thread)X
+2604(was)X
+2750(encoded)X
+3039(in)X
+3122(a)X
+3179(structure)X
+7 f F
+3481(stp_t)X
+1 f F
+(.)S
+3782(It)X
+3852(would)X
+4073(be)X
+4170(best)X
+555 4912(if)N
+633(client)X
+840(threads)X
+1101(packages)X
+1425(could)X
+1632(manipulate)X
+2017(a)X
+2082(thread)X
+2311(by)X
+2419(simply)X
+2664(manipulating)X
+3114(its)X
+3217(stack)X
+3410(pointer)X
+3665(and)X
+3809(without)X
+4081(adding)X
+555 5016(any)N
+696(state)X
+868(\(such)X
+1067(as)X
+1159(an)X
+7 f F
+1260(stp_t)X
+1 f F
+(\))S
+1552(to)X
+1639(that)X
+1784(required)X
+2077(by)X
+2182(QuickThreads.)X
+2702(Usually,)X
+2996(however,)X
+3318(when)X
+3516(a)X
+3576(thread)X
+3801(exits)X
+3976(it)X
+4044(must)X
+4223(be)X
+555 5120(possible)N
+838(to)X
+921(discover)X
+1214(the)X
+1333(base)X
+1497(of)X
+1585(the)X
+1704(stack,)X
+1909(given)X
+2107(just)X
+2242(the)X
+2360(stack)X
+2545(pointer.)X
+8 s F
+2792 5080(7)N
+10 s F
+2864 5120(One)N
+3018(common)X
+3318(way)X
+3472(to)X
+3554(\256nd)X
+3698(the)X
+3816(stack)X
+4001(base)X
+4164(is)X
+4237(to)X
+8 s 9 f F
+555 5200 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5300(4.)N
+651(It)X
+706(is)X
+765(also)X
+884(possible)X
+1110(to)X
+1176(build)X
+1324(tree-structured)X
+1711(run)X
+1812(queues)X
+2005(so)X
+2078(that)X
+2190(one)X
+2298(data)X
+2420(structure)X
+2659(implements)X
+2974(both)X
+3104(the)X
+3198(run)X
+3299(queue)X
+3467(and)X
+3575(the)X
+3669(barrier.)X
+555 5400(5.)N
+651(Marker)X
+854(threads)X
+1054(are)X
+1147(similar)X
+1341(to)X
+1407(control)X
+1604(constructs)X
+1879(in)X
+1945(threaded)X
+2180(interpreters)X
+2486(and)X
+2594(to)X
+2660(the)X
+2754(\256nal)X
+2884(states)X
+3042(in)X
+3108(\256nite)X
+3256(automata)X
+3506([Tho68].)X
+555 5500(6.)N
+651(It)X
+713(is)X
+779(tempting)X
+1030(to)X
+1103(try)X
+1197(to)X
+1270(set)X
+1364(aside)X
+7 f F
+1518(nbytes)X
+1 f F
+1769(of)X
+1844(storage)X
+2050(pointed)X
+2264(to)X
+2336(by)X
+7 f F
+2422(vargs)X
+1 f F
+2612(.)X
+2666(However,)X
+2937(the)X
+3037(argument)X
+3300(list)X
+3401(described)X
+3667(by)X
+7 f F
+3753(vargs)X
+1 f F
+3965(may)X
+4097(actually)X
+651 5572(represent)N
+902(more)X
+1051(than)X
+7 f F
+1179(nbytes)X
+1 f F
+1425(of)X
+1496(storage,)X
+1714(may)X
+1842(not)X
+1942(point)X
+2092(to)X
+2160(the)X
+2256(beginning)X
+2530(or)X
+2601(end)X
+2711(of)X
+2782(that)X
+2896(storage,)X
+3114(might)X
+3282(not)X
+3381(even)X
+3518(be)X
+3595(a)X
+3640(pointer,)X
+3854(and)X
+3963(the)X
+4058(argument)X
+651 5644(list)N
+746(may)X
+872(have)X
+1008(constrained)X
+1318(alignment.)X
+1622(See)X
+1730(Appendix)X
+1998(A.)X
+555 5744(7.)N
+651(It)X
+706(would)X
+882(be)X
+958(useful)X
+1130(to)X
+1196(have)X
+1332(the)X
+1426(capacity)X
+1654(to)X
+1720(unwind)X
+1928(the)X
+2022(stack)X
+2169(and)X
+2277(call)X
+2385(the)X
+2479(cleanup)X
+2693(function,)X
+2938(but)X
+3036(no)X
+3116(such)X
+3249(facility)X
+3446(is)X
+3505(provided.)X
+
+%%Page: 16 16
+16 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2340 392(-)N
+2387(16)X
+2487(-)X
+555 680(keep)N
+737(a)X
+803(global)X
+1033(pointer)X
+1290(\(e.g.,)X
+1483(SimpleThreads's)X
+7 f F
+2056(stp_global_curr)X
+1 f F
+(\).)S
+2873(Another)X
+3166(is)X
+3249(to)X
+3341(allocate)X
+3620(all)X
+3729(stacks)X
+3954(on)X
+4063(aligned)X
+555 784(boundaries;)N
+965(the)X
+1098(stack)X
+1298(base)X
+1476(is)X
+1564(found)X
+1786(by)X
+1901(rounding)X
+2225(the)X
+2358(stack)X
+2558(pointer.)X
+2860(The)X
+3020(aligned/rounding)X
+3602(technique)X
+3949(is)X
+4037(used)X
+4219(by)X
+555 888(Amber)N
+798([Cha90])X
+1081(and)X
+1217(threads)X
+1469(under)X
+1672(scheduler)X
+2000(activations)X
+2367([BMVL92].)X
+755 1020(Some)N
+965(queues,)X
+1236(such)X
+1411(as)X
+1505(the)X
+1630(SimpleThreads)X
+2142(queues,)X
+2412(expect)X
+2649(each)X
+2824(thread)X
+3052(to)X
+3141(provide)X
+3413(storage)X
+3672(for)X
+3793(the)X
+7 f F
+3918(next)X
+1 f F
+4137(\256eld.)X
+555 1124(Such)N
+735(storage)X
+987(can)X
+1119(be)X
+1215(allocated)X
+1525(on)X
+1625(top)X
+1747(of)X
+1834(the)X
+1952(thread)X
+2173(stack)X
+2358(using)X
+7 f F
+2551(QT_SALLOC)X
+1 f F
+(.)S
+3 f F
+555 1332(5.10.)N
+755(Auto-Grow)X
+1167(Stacks)X
+1 f F
+555 1464(In)N
+645(some)X
+837(circumstances)X
+1315(it)X
+1382(is)X
+1458(useful)X
+1677(to)X
+1762(grow)X
+1950(the)X
+2071(stack)X
+2259(on)X
+2362(demand,)X
+2659(saving)X
+2891(backing)X
+3168(store)X
+3347(allocation)X
+3686(for)X
+3803(threads)X
+4058(that)X
+4200(ac-)X
+555 1568(tually)N
+765(use)X
+900(large)X
+1089(stacks.)X
+1353(To)X
+1470(implement)X
+1840(this,)X
+2003(each)X
+2179(stack)X
+2372(allocation)X
+2716(is)X
+2797(followed)X
+3110(by)X
+3218(a)X
+3282(large)X
+3470(unallocated)X
+3867(region)X
+4099(that)X
+4246(is)X
+555 1672(mapped)N
+832(to)X
+917(cause)X
+1119(a)X
+1178(fault)X
+1348(on)X
+1451(access.)X
+1720(When)X
+1935(the)X
+2056(stack)X
+2243(over\257ows,)X
+2601(stack)X
+2788(references)X
+3142(go)X
+3244(to)X
+3328(the)X
+3448(unallocated)X
+3840(region.)X
+4107(These)X
+555 1776(references)N
+919(invoke)X
+1169(a)X
+1237(fault)X
+1416(handler)X
+1689(that)X
+1841(maps)X
+2042(additional)X
+2394(storage)X
+2658(in)X
+2752(to)X
+2846(the)X
+2976(region,)X
+3233(thus)X
+3397(growing)X
+3695(the)X
+3824(stack)X
+4020([Gru91].)X
+555 1880(Stacks)N
+788(space)X
+991(can)X
+1127(also)X
+1280(be)X
+1380(\252scavenged\272,)X
+1831(unmapping)X
+2215(storage)X
+2471(between)X
+2763(the)X
+2885(thread's)X
+3168(current)X
+3420(top-of-stack)X
+3832(and)X
+3972(the)X
+4093(end)X
+4232(of)X
+555 1984(the)N
+673(thread's)X
+952(stack)X
+1137(region.)X
+3 f F
+555 2192(5.11.)N
+755(Shared)X
+1019(Stacks)X
+1 f F
+555 2324(The)N
+704(preceding)X
+1044(discussion)X
+1400(of)X
+1490(thread)X
+1714(stacks)X
+1933(assumed)X
+2232(that)X
+2375(distinct)X
+2633(storage)X
+2888(is)X
+2964(used)X
+3134(for)X
+3251(each)X
+3422(thread's)X
+3704(stack.)X
+3932(An)X
+4053(alterna-)X
+555 2428(tive)N
+698(is)X
+774(to)X
+859(have)X
+1034(a)X
+1093(shared)X
+1326(stack.)X
+1554(When)X
+1769(a)X
+1828(thread)X
+2052(is)X
+2128(restarted,)X
+2448(its)X
+2546(stack)X
+2734(data)X
+2891(is)X
+2967(copied)X
+3204(from)X
+3383(the)X
+3504(heap)X
+3678(to)X
+3762(the)X
+3882(shared)X
+4114(stack.)X
+555 2532(When)N
+771(a)X
+831(thread)X
+1056(is)X
+1132(halted,)X
+1371(the)X
+1492(thread's)X
+1774(stack)X
+1962(data)X
+2119(is)X
+2195(copied)X
+2432(back)X
+2607(to)X
+2692(the)X
+2813(heap.)X
+3028(Although)X
+3353(copying)X
+3634(takes)X
+3822(a)X
+3881(lot)X
+3988(of)X
+4078(time,)X
+4263(a)X
+555 2636(shared)N
+794(stack)X
+988(reduces)X
+1263(the)X
+1390(space)X
+1598(used)X
+1774(by)X
+1883(halted)X
+2107(threads.)X
+2407(The)X
+2560(intuition)X
+2858(is)X
+2939(that)X
+3087(private)X
+3338(stacks)X
+3562(are)X
+3689(large)X
+3878(because)X
+4161(they)X
+555 2740(give)N
+716(each)X
+887(thread)X
+1111(as)X
+1201(much)X
+1402(space)X
+1604(as)X
+1694(it)X
+1761(might)X
+1970(ever)X
+2132(need.)X
+2347(The)X
+2495(shared)X
+2728(stack)X
+2916(is)X
+2992(large)X
+3176(so)X
+3270(it)X
+3337(can)X
+3472(run)X
+3602(threads,)X
+3876(but)X
+4000(the)X
+4120(space)X
+555 2844(used)N
+729(by)X
+836(each)X
+1011(blocked)X
+1292(thread)X
+1520(needs)X
+1730(to)X
+1819(be)X
+1922(only)X
+2091(as)X
+2184(big)X
+2312(as)X
+2405(the)X
+2529(thread's)X
+2814(state)X
+2987(at)X
+3071(the)X
+3195(time)X
+3363(it)X
+3433(blocks.)X
+3708(For)X
+3845(some)X
+4040(applica-)X
+555 2948(tions,)N
+762(allocating)X
+1110(a)X
+1178(few)X
+1331(hundred)X
+1626(bytes)X
+1827(per)X
+1962(thread)X
+2195(is)X
+2280(acceptable,)X
+2672(but)X
+2806(allocating)X
+3154(e.g.,)X
+3322(a)X
+3389(4Kb)X
+3558(stack)X
+3754(for)X
+3879(each)X
+4058(runable)X
+555 3052(thread)N
+776(will)X
+920(consume)X
+1225(all)X
+1325(available)X
+1635(memory)X
+1922([Ros92,)X
+2193(EAL93,)X
+2469(Pin93].)X
+755 3184(Shared)N
+1001(stacks)X
+1220(can)X
+1355(be)X
+1454(implemented)X
+1895(using)X
+2091(QuickThreads.)X
+2609(The)X
+2757(thread's)X
+2 f F
+3039(current)X
+3298(stack)X
+1 f F
+3486(is)X
+3562(the)X
+3683(region)X
+3911(between)X
+4201(the)X
+555 3288(uninitialized)N
+982(stack)X
+1174(pointer)X
+1428(and)X
+1571(the)X
+1696(thread's)X
+1982(current)X
+2237(\(blocked\))X
+2572(stack)X
+2764(pointer.)X
+3058(Here,)X
+3262(\252between\272)X
+3629(includes)X
+3922(the)X
+4046(bytes)X
+4241(at)X
+555 3392(the)N
+684(lowest)X
+923(address)X
+1194(but)X
+1326(not)X
+1458(those)X
+1657(at)X
+1745(the)X
+1873(highest)X
+2134(address.)X
+2445(Since)X
+2653(the)X
+2781(stack)X
+2976(can)X
+3118(grow)X
+3313(up)X
+3423(or)X
+3520(down,)X
+3748(the)X
+3876(current)X
+4134(stack)X
+555 3496(pointer)N
+851(may)X
+1058(be)X
+1203(larger)X
+1460(or)X
+1596(smaller)X
+1900(than)X
+2106(the)X
+2272(uninitialized)X
+2740(stack)X
+2973(pointer.)X
+3308(Thus,)X
+3556(the)X
+3722(region)X
+3995(is)X
+4116(either)X
+2 f F
+555 3600([initialized..uninitialized\))N
+1 f F
+1391(or)X
+2 f F
+1478([uninitialized..initialized\))X
+1 f F
+2294(.)X
+755 3732(Each)N
+941(time)X
+1108(a)X
+1168(thread)X
+1393(blocks)X
+1626(it)X
+1694(switches)X
+1994(to)X
+2080(a)X
+2140(scheduler)X
+2472(thread.)X
+2737(The)X
+2886(scheduler)X
+3218(thread)X
+3443(must)X
+3622(use)X
+3753(a)X
+3813(different)X
+4114(stack,)X
+555 3836(but)N
+692(since)X
+892(there)X
+1088(is)X
+1176(only)X
+1353(one)X
+1504(scheduler)X
+1847(per)X
+1985(processor,)X
+2348(the)X
+2480(space)X
+2693(overhead)X
+3022(is)X
+3109(small.)X
+3356(The)X
+3515(scheduler)X
+3857(saves)X
+4065(the)X
+4197(old)X
+555 3940(thread's)N
+834(stack)X
+1019(data,)X
+1193(\256nds)X
+1368(a)X
+1424(new)X
+1578(thread,)X
+1819(restores)X
+2089(its)X
+2184(stack)X
+2369(data)X
+2523(to)X
+2605(the)X
+2723(shared)X
+2953(stack,)X
+3158(then)X
+3316(resumes)X
+3599(the)X
+3717(new)X
+3871(thread.)X
+755 4072(Another)N
+1050(alternative)X
+1421(is)X
+1506(to)X
+1600(have)X
+1783(a)X
+1850(small)X
+2054(number)X
+2330(of)X
+2428(shared)X
+2669(stacks.)X
+2936(Each)X
+3128(thread)X
+3360(can)X
+3503(be)X
+3610(in)X
+3703(one)X
+3850(of)X
+3948(two)X
+4099(states:)X
+2 f F
+555 4176(cached)N
+1 f F
+803(or)X
+2 f F
+890(noncached)X
+1 f F
+1238(.)X
+1298(A)X
+1376(cached)X
+1620(thread)X
+1841(has)X
+1968(its)X
+2063(stack)X
+2248(data)X
+2402(on)X
+2502(a)X
+2558(shared)X
+2788(stack.)X
+3013(An)X
+3131(uncached)X
+3455(thread)X
+3676(must)X
+3851(be)X
+3947(copied)X
+4181(to)X
+4263(a)X
+555 4280(shared)N
+788(stack)X
+976(before)X
+1205(it)X
+1272(can)X
+1407(run.)X
+1577(When)X
+1792(a)X
+1851(thread)X
+2075(is)X
+2151(\256rst)X
+2297(started)X
+2533(it)X
+2599(is)X
+2674(assigned)X
+2972(to)X
+3056(one)X
+3194(of)X
+3283(the)X
+3403(stacks,)X
+3641(called)X
+3855(its)X
+2 f F
+3952(designated)X
+1 f F
+555 4384(stack;)N
+764(a)X
+822(thread)X
+1045(always)X
+1290(runs)X
+1450(on)X
+1552(its)X
+1649(designated)X
+2014(stack.)X
+2241(A)X
+2321(context)X
+2579(switch)X
+2810(can)X
+2944(go)X
+3046(directly)X
+3313(from)X
+3491(an)X
+3589(old)X
+3713(thread)X
+3935(to)X
+4018(a)X
+4075(cached)X
+555 4488(new)N
+715(thread.)X
+982(An)X
+1106(uncached)X
+1436(new)X
+1596(thread)X
+1823(needs)X
+2032(a)X
+2094(context)X
+2356(switch)X
+2591(to)X
+2679(the)X
+2803(scheduler,)X
+3157(where)X
+3379(the)X
+3502(thread)X
+3728(on)X
+3833(the)X
+3956(designated)X
+555 4592(stack)N
+746(is)X
+825(copied)X
+1065(back)X
+1243(to)X
+1331(heap)X
+1509(storage,)X
+1787(and)X
+1929(the)X
+2053(new)X
+2213(thread)X
+2440(is)X
+2519(copied)X
+2759(in)X
+2847(and)X
+2989(run.)X
+3162(The)X
+3312(context)X
+3573(switch)X
+3807(to)X
+3894(an)X
+3995(uncached)X
+555 4696(thread)N
+785(must)X
+969(go)X
+1078(via)X
+1205(the)X
+1332(scheduler)X
+1669(because)X
+1952(the)X
+2078(old)X
+2208(and)X
+2352(new)X
+2514(threads)X
+2774(might)X
+2988(use)X
+3123(the)X
+3249(same)X
+3442(designated)X
+3813(stack.)X
+4046(Context)X
+555 4800(switches)N
+851(are)X
+970(fastest)X
+1195(between)X
+1483(cached)X
+1727(threads,)X
+1999(so)X
+2090(the)X
+2208(scheduling)X
+2575(policies)X
+2844(should)X
+3077(try)X
+3186(to)X
+3268(run)X
+3395(threads)X
+3647(that)X
+3787(are)X
+3906(cached.)X
+3 f F
+555 5008(5.12.)N
+755(Preemption)X
+1 f F
+555 5140(QuickThreads)N
+1034(is)X
+1111(designed)X
+1420(for)X
+1538(nonpreemptive)X
+2043(threads)X
+2299(packages.)X
+2658(Preemptive)X
+3047(threads)X
+3303(can)X
+3438(be)X
+3537(implemented)X
+3978(by)X
+4081(having)X
+555 5244(timer)N
+751(signal)X
+969(handlers)X
+1268(pushed)X
+1522(on)X
+1629(the)X
+1754(thread's)X
+2040(stack)X
+2232(rather)X
+2447(than)X
+2612(going)X
+2821(on)X
+2928(a)X
+2991(special)X
+3241(signal)X
+3459(stack.)X
+3690(The)X
+3841(signal)X
+4058(handler)X
+555 5348(can)N
+692(block)X
+895(the)X
+1018(current)X
+1271(thread)X
+1497(using)X
+1695(nonpreemptive)X
+2201(primitives.)X
+2590(Timer)X
+2811(signals)X
+3058(are)X
+3182(reenabled)X
+3520(when)X
+3719(the)X
+3842(signal)X
+4058(handler)X
+555 5452(returns.)N
+846(The)X
+999(signal)X
+1218(handler)X
+1487(doesn't)X
+1751(return)X
+1971(until)X
+2145(the)X
+2271(thread)X
+2499(resumes,)X
+2809(so)X
+2907(timer)X
+3103(signals)X
+3352(must)X
+3534(be)X
+3637(reenabled)X
+3977(explicitly.)X
+555 5556(Prototypical)N
+966(code)X
+1138(is)X
+1211(shown)X
+1440(in)X
+1522(Figure)X
+1751(4.)X
+755 5688(Often,)N
+981(involuntary)X
+1373(context)X
+1632(switches)X
+1931(should)X
+2167(be)X
+2266(disabled)X
+2556(during)X
+2788(e.g.,)X
+2947(critical)X
+3193(sections.)X
+3514(Context)X
+3790(switches)X
+4089(can)X
+4223(be)X
+555 5792(disabled)N
+847(easily)X
+1059(by)X
+1163(setting)X
+1400(a)X
+1460(global.)X
+1724(The)X
+7 f F
+1873(sig_timer)X
+1 f F
+2329(routine)X
+2580(checks)X
+2823(the)X
+2945(global,)X
+3189(and,)X
+3349(if)X
+3422(set,)X
+3555(the)X
+3677(signal)X
+3892(handler)X
+4157(sim-)X
+
+%%Page: 17 17
+17 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(17)X
+2487(-)X
+8 s 7 f F
+843 712(sig_timer\(\))N
+843 800({)N
+919 888(QT_BLOCK)N
+1261(\(...,)X
+1489(sig_timer_helper,)X
+2173(...\);)X
+843 976(})N
+843 1152(sig_timer_helper)N
+1489(\(...\))X
+843 1240({)N
+919 1328(...)N
+1071(clean)X
+1299(up)X
+1413(old)X
+1565(thread)X
+1831(...)X
+919 1416(...)N
+1071(reenable)X
+1413(timer)X
+1641(signals)X
+1945(...)X
+919 1504(...)N
+1071(set)X
+1223(the)X
+1375(timer)X
+1603(...)X
+843 1592(})N
+9 s 3 f F
+1674 1744(Figure)N
+1896(4.)X
+1 f F
+1986(Prototypical)X
+2356(code)X
+2510(for)X
+2612(preemptive)X
+2954(threads.)X
+10 s F
+555 1952(ply)N
+684(resets)X
+894(the)X
+1019(timer)X
+1215(and)X
+1358(returns.)X
+1648(With)X
+1835(this)X
+1977(technique,)X
+2336(threads)X
+2594(in)X
+2682(locked)X
+2922(sections)X
+3206(can)X
+3344(get)X
+3468(excess)X
+3704(quanta.)X
+3984(However,)X
+555 2056(the)N
+673(threads)X
+925(are)X
+1044(doing)X
+1246(critical)X
+1489(section)X
+1736(work,)X
+1941(so)X
+2032(the)X
+2150(effective)X
+2452(priority)X
+2712(increase)X
+2996(is)X
+3069(usually)X
+3320(acceptable.)X
+2 f F
+755 2188(Note:)N
+1 f F
+961(A)X
+1047(preemption)X
+1440(during)X
+1677(a)X
+1741(context)X
+2005(switch)X
+2242(effectively)X
+2614(preempts)X
+2935(two)X
+3082(threads:)X
+3363(when)X
+3564(the)X
+3689(old)X
+3818(thread)X
+4046(is)X
+755 2292(running)N
+1036(it)X
+1112(has)X
+1251(a)X
+1319(pointer)X
+1578(to)X
+1672(the)X
+1801(next)X
+1970(thread;)X
+2224(when)X
+2429(the)X
+2558(helper)X
+2790(runs)X
+2959(on)X
+3070(the)X
+3199(new)X
+3364(thread's)X
+3654(stack)X
+3850(it)X
+3925(has)X
+4063(a)X
+755 2396(pointer)N
+1002(to)X
+1084(the)X
+1202(old)X
+1324(\(blocking\))X
+1678(thread.)X
+755 2528(This)N
+919(preemption)X
+1306(mechanism)X
+1693(leaves)X
+1916(signal)X
+2129(handler)X
+2392(frames)X
+2633(on)X
+2734(the)X
+2853(stack)X
+3039(and)X
+3176(may)X
+3335(lead)X
+3490(to)X
+3573(stack)X
+3759(growth)X
+4007(if)X
+4077(signals)X
+555 2632(arrive)N
+777(while)X
+7 f F
+989(sig_timer)X
+1 f F
+1455(or)X
+7 f F
+1556(sig_timer_helper)X
+1 f F
+2358(is)X
+2445(executing.)X
+2831(Workarounds)X
+3302(exist,)X
+3507(but)X
+3643(lead)X
+3811(to)X
+3907(complicated)X
+555 2736(code.)N
+767(Note)X
+943(also)X
+1092(that)X
+1232(the)X
+1350(timer)X
+1539(must)X
+1714(be)X
+1810(reenabled)X
+2143(late)X
+2279(to)X
+2361(avoid)X
+2559(race)X
+2714(conditions.)X
+3 f F
+555 2944(5.13.)N
+755(Persistent)X
+1114(Threads)X
+1 f F
+555 3076(A)N
+2 f F
+635(persistent)X
+968(thread)X
+1 f F
+1199(is)X
+1274(one)X
+1412(that)X
+1554(can)X
+1688(be)X
+1786(\252frozen\272)X
+2086(and)X
+2224(e.g.,)X
+2382(put)X
+2506(in)X
+2589(a)X
+2646(disk)X
+2800(\256le.)X
+2963(The)X
+3109(thread)X
+3331(is)X
+3405(later)X
+3569(read)X
+3729(in)X
+3812(to)X
+3895(memory)X
+4183(and)X
+555 3180(resumed.)N
+891(A)X
+973(persistent)X
+1304(thread)X
+1528(may)X
+1689(be)X
+1788(frozen)X
+2017(and)X
+2156(resumed)X
+2451(many)X
+2652(times;)X
+2870(likely,)X
+3095(it)X
+3162(will)X
+3309(be)X
+3408(resumed)X
+3703(each)X
+3874(time)X
+4039(in)X
+4124(a)X
+4183(dif-)X
+555 3284(ferent)N
+765(program,)X
+1079(or)X
+1168(at)X
+1247(least)X
+1415(a)X
+1472(different)X
+1770(run)X
+1898(of)X
+1986(the)X
+2105(program.)X
+2438(There)X
+2647(are)X
+2767(a)X
+2824(variety)X
+3068(of)X
+3156(issue)X
+3337(that)X
+3478(must)X
+3654(be)X
+3751(resolved,)X
+4064(such)X
+4232(as)X
+555 3388(ensuring)N
+865(the)X
+997(thread)X
+1231(occupies)X
+1545(the)X
+1676(same)X
+1874(portion)X
+2138(of)X
+2238(the)X
+2369(address)X
+2643(space)X
+2855(from)X
+3044(run)X
+3184(to)X
+3279(run,)X
+3439(how)X
+3610(the)X
+3741(thread)X
+3975(is)X
+4061(to)X
+4156(treat)X
+555 3492(pointers)N
+833(outside)X
+1084(of)X
+1171(the)X
+1289(thread's)X
+1568(stack)X
+1753(region,)X
+1998(and)X
+2134(how)X
+2292(to)X
+2374(synchronize)X
+2782(with)X
+2944(other)X
+3129(users)X
+3314(of)X
+3401(the)X
+3519(persistent)X
+3846(thread.)X
+755 3624(QuickThreads)N
+1233(does)X
+1403(not)X
+1528(resolve)X
+1783(those)X
+1974(issues)X
+2187(but)X
+2311(does)X
+2480(help)X
+2640(in)X
+2724(one)X
+2862(way:)X
+3040(it)X
+3106(separates)X
+3423(the)X
+3543(scheduling)X
+3912(decisions)X
+4232(of)X
+555 3728(the)N
+677(application)X
+1057(from)X
+1237(the)X
+1359(operation)X
+1686(of)X
+1777(the)X
+1899(thread.)X
+2164(When)X
+2380(an)X
+2480(application)X
+2860(restarts)X
+3116(a)X
+3176(persistent)X
+3507(thread)X
+3731(it)X
+3798(can)X
+3933(provide)X
+4201(the)X
+555 3832(code)N
+735(and)X
+879(data)X
+1041(that)X
+1189(the)X
+1315(thread)X
+1544(uses)X
+1710(to)X
+1800(block)X
+2006(itself.)X
+2234(Each)X
+2423(application)X
+2807(can)X
+2947(use)X
+3082(the)X
+3208(same)X
+3401(thread)X
+3630(with)X
+3800(completely)X
+4183(dif-)X
+555 3936(ferent)N
+763(scheduling)X
+1130(protocols.)X
+8 s F
+1448 3896(8)N
+10 s 3 f F
+555 4144(6.)N
+655(Measurements)X
+1179(and)X
+1327(Implementation)X
+1 f F
+555 4276(This)N
+742(section)X
+994(reports)X
+1241(on)X
+1345(the)X
+1467(performance)X
+1898(of)X
+1989(QuickThreads)X
+2468(primitives)X
+2816(on)X
+2920(a)X
+2980(number)X
+3249(of)X
+3340(machines)X
+3667(and)X
+3807(describes)X
+4130(some)X
+555 4380(practical)N
+852(details)X
+1081(of)X
+1168(the)X
+1286(implementations.)X
+3 f F
+555 4588(6.1.)N
+715(Performance)X
+1 f F
+555 4720(QuickThreads)N
+1032(is)X
+1107(designed)X
+1414(to)X
+1498(give)X
+1658(modest)X
+1911(performance.)X
+2380(QuickThreads)X
+2857(alone)X
+3053(is)X
+3128(minimalist)X
+3491(and)X
+3629(thus)X
+3784(fairly)X
+3980(fast.)X
+4157(This)X
+555 4824(section)N
+810(gives)X
+1007(performance)X
+1442(of)X
+1537(the)X
+1663(primitives)X
+2015(on)X
+2122(several)X
+2377(platforms:)X
+2733(an)X
+2836(AXP)X
+3023([Sit93])X
+3272(processor,)X
+3627(with)X
+3796(reported)X
+4091(timing)X
+555 4928(\256gures)N
+805(estimated;)X
+1166(one)X
+1314(16MHz)X
+1591(Intel)X
+1770(i386)X
+1944(processor)X
+2284(on)X
+2395(a)X
+2462(Sequent)X
+2751(Symmetry)X
+3115([Seq88];)X
+3422(a)X
+3489(20MHz)X
+3765(KSR1)X
+3991(processor)X
+555 5032([KSR91];)N
+906(two)X
+1066(SPARC-based)X
+1568([SPA92])X
+1887(Suns)X
+2081(with)X
+2262(kernel)X
+2502(support)X
+2781(for)X
+2914(register)X
+3194(windows)X
+3522([Kep91];)X
+3851(a)X
+3926(DECstation)X
+555 5136(5000/200)N
+885(using)X
+1086(a)X
+1150(MIPS)X
+1364(R3000)X
+1605(processor)X
+1941([Kan87];)X
+2259(and)X
+2403(a)X
+2467(VAX-based)X
+2879([DEC81])X
+3201(VAXstation)X
+3616(3500.)X
+3844(QuickThreads)X
+555 5240(also)N
+704(runs)X
+862(on)X
+962(a)X
+1018(platform)X
+1314(using)X
+1507(Motorola)X
+1825(88100)X
+2045(processors)X
+2404([Mot89],)X
+2711(but)X
+2833(no)X
+2933(timing)X
+3161(\256gures)X
+3399(are)X
+3518(available.)X
+8 s 9 f F
+555 5340 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5440(8.)N
+651(Applications)X
+998(will)X
+1118(sometimes)X
+1412(assume)X
+1620(that)X
+1736(thread)X
+1915(stacks)X
+2091(contain)X
+2299(certain)X
+2492(\256elds,)X
+2667(e.g.,)X
+2795(a)X
+7 f F
+2843(next)X
+1 f F
+3015(\256eld)X
+3149(that)X
+3264(is)X
+3326(used)X
+3462(to)X
+3531(link)X
+3650(together)X
+3878(blocked)X
+4099(threads.)X
+651 5512(In)N
+724(this)X
+837(case,)X
+982(an)X
+1062(application)X
+1366(can)X
+1474(create)X
+1645(a)X
+2 f F
+1693(surrogate)X
+1 f F
+1962(thread)X
+2140(that)X
+2255(is)X
+2317(scheduled)X
+2591(normally.)X
+2873(When)X
+3044(the)X
+3141(surrogate)X
+3397(is)X
+3459(invoked)X
+3684(it)X
+3739(invokes)X
+3957(the)X
+4054(persistent)X
+651 5584(thread.)N
+860(When)X
+1029(the)X
+1124(persistent)X
+1386(thread)X
+1562(blocks)X
+1746(it)X
+1799(returns)X
+1993(control)X
+2191(to)X
+2258(the)X
+2353(surrogate,)X
+2623(which)X
+2796(then)X
+2923(blocks)X
+3107(in)X
+3174(an)X
+3251(application-de\256ned)X
+3761(way.)X
+3916(Scheduling)X
+4221(the)X
+651 5656(surrogate)N
+904(thus)X
+1027(implicitly)X
+1293(schedules)X
+1557(the)X
+1651(persistent)X
+1912(thread.)X
+
+%%Page: 18 18
+18 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2340 392(-)N
+2387(18)X
+2487(-)X
+755 680(All)N
+880(measurements)X
+1362(in)X
+1447(this)X
+1585(section)X
+1835(are)X
+1956(for)X
+2072(microbenchmarks.)X
+2709(Experiments)X
+3136(were)X
+3315(performed)X
+3672(by)X
+3774(running)X
+4045(the)X
+4165(pro-)X
+555 784(gram)N
+753(once)X
+938(to)X
+1033(get)X
+1164(it)X
+1241(in)X
+1336(to)X
+1431(memory,)X
+1751(then)X
+1922(timing)X
+2163(each)X
+2344(of)X
+2444(the)X
+2575(microbenchmark)X
+3152(runs)X
+3323(when)X
+3530(run)X
+3670(on)X
+3782(a)X
+3850(lightly-loaded)X
+555 888(machine.)N
+892(Each)X
+1078(microbenchmark)X
+1647(executes)X
+1949(the)X
+2071(given)X
+2273(operation\(s\))X
+2685(a)X
+2745(\252large\272)X
+3002(number)X
+3271(of)X
+3362(times.)X
+3599(Time)X
+3792(per)X
+3919(operation)X
+4246(is)X
+555 992(computed)N
+892(by)X
+993(dividing)X
+1280(the)X
+1399(elapsed)X
+1661(\(wallclock\))X
+2047(time)X
+2209(by)X
+2309(the)X
+2427(number)X
+2692(of)X
+2779(times)X
+2972(the)X
+3090(operation)X
+3413(was)X
+3558(performed.)X
+3953(Since)X
+4151(each)X
+555 1096(operation)N
+885(was)X
+1037(performed)X
+1399(a)X
+1462(large)X
+1650(number)X
+1922(of)X
+2015(times)X
+2214(and)X
+2356(since)X
+2547(each)X
+2721(microbenchmark)X
+3291(performs)X
+3607(no)X
+3713(other)X
+3904(work,)X
+4115(cache)X
+555 1200(hit)N
+663(rates)X
+839(are)X
+962(probably)X
+1271(close)X
+1460(to)X
+1546(100%)X
+1757(and)X
+1897(register)X
+2161(allocation)X
+2500(is)X
+2576(good)X
+2759(because)X
+3037(all)X
+3140(registers)X
+3435(are)X
+3557(available)X
+3870(for)X
+3987(loops)X
+4183(and)X
+555 1304(context)N
+811(switches.)X
+1147(Thus,)X
+1347(the)X
+1465(reported)X
+1753(times)X
+1946(are)X
+2065(probably)X
+2370(better)X
+2573(than)X
+2731(will)X
+2875(be)X
+2971(seen)X
+3134(in)X
+3216(practice.)X
+755 1436(As)N
+868(a)X
+928(rough)X
+1139(benchmark,)X
+1539(Figure)X
+1771(5)X
+1834(shows)X
+2057(the)X
+2178(raw)X
+2322(times)X
+2518(for)X
+2635(many)X
+2836(repetitions)X
+3197(of)X
+3287(a)X
+3346(few)X
+3490(simple)X
+3726(operations.)X
+4123(Note,)X
+555 1540(however,)N
+873(that)X
+1014(benchmark)X
+1392(times)X
+1586(are)X
+1706(approximate)X
+2128(since)X
+2314(the)X
+2433(benchmark)X
+2811(code)X
+2984(may)X
+3143(have)X
+3316(been)X
+3489(optimized)X
+3830(by)X
+3931(e.g.,)X
+4087(the)X
+4205(as-)X
+555 1644(sembler.)N
+869(No)X
+987(microbenchmarks)X
+1582(were)X
+1759(run)X
+1886(on)X
+1986(the)X
+2104(KSR1.)X
+1716 1751(_)N
+1737(___________________________________)X
+9 f F
+2335 1855(m)N
+1 f F
+2381(Sec)X
+9 f F
+2626(m)X
+1 f F
+2672(Sec)X
+9 f F
+2926(m)X
+1 f F
+2972(Sec)X
+1845 1959(Machine)N
+2345(Null)X
+2632(Reg.)X
+2924(Load)X
+2349 2063(Call)N
+2638(Add)X
+2932(Reg.)X
+1716 2079(_)N
+1737(___________________________________)X
+1716 2095(_)N
+1737(___________________________________)X
+1905 2191(AXP)N
+2346(0.90)X
+2617(0.090)X
+2917(0.090)X
+1914 2295(i386)N
+2346(1.89)X
+2617(0.14)X
+9 f F
+2985(-)X
+1 f F
+1888 2399(KSR1)N
+9 f F
+2394(-)X
+2685(-)X
+2985(-)X
+1 f F
+1850 2503(M88100)N
+9 f F
+2394(-)X
+2685(-)X
+2985(-)X
+1 f F
+1776 2607(MIPS)N
+1982(R3000)X
+2346(0.19)X
+2617(0.011)X
+2917(0.091)X
+1776 2711(SPARC)N
+2048(4-65)X
+2346(1.36)X
+2617(0.049)X
+2917(0.089)X
+1756 2815(SPARC)N
+2028(4-490)X
+2346(0.99)X
+2617(0.036)X
+2917(0.067)X
+1808 2919(VAX)N
+2002(3500)X
+2346(5.4)X
+2617(0.23)X
+2917(3.5)X
+1716 2943(_)N
+1737(___________________________________)X
+9 f F
+1716 MX
+(br)135 200 oc
+1716 2871 MXY
+(br)135 200 oc
+1716 2791 MXY
+(br)135 200 oc
+1716 2711 MXY
+(br)135 200 oc
+1716 2631 MXY
+(br)135 200 oc
+1716 2551 MXY
+(br)135 200 oc
+1716 2471 MXY
+(br)135 200 oc
+1716 2391 MXY
+(br)135 200 oc
+1716 2311 MXY
+(br)135 200 oc
+1716 2231 MXY
+(br)135 200 oc
+1716 2151 MXY
+(br)135 200 oc
+1716 2071 MXY
+(br)135 200 oc
+1716 1991 MXY
+(br)135 200 oc
+1716 1911 MXY
+(br)135 200 oc
+1716 1831 MXY
+(br)135 200 oc
+3137 2943 MXY
+(br)135 200 oc
+3137 2871 MXY
+(br)135 200 oc
+3137 2791 MXY
+(br)135 200 oc
+3137 2711 MXY
+(br)135 200 oc
+3137 2631 MXY
+(br)135 200 oc
+3137 2551 MXY
+(br)135 200 oc
+3137 2471 MXY
+(br)135 200 oc
+3137 2391 MXY
+(br)135 200 oc
+3137 2311 MXY
+(br)135 200 oc
+3137 2231 MXY
+(br)135 200 oc
+3137 2151 MXY
+(br)135 200 oc
+3137 2071 MXY
+(br)135 200 oc
+3137 1991 MXY
+(br)135 200 oc
+3137 1911 MXY
+(br)135 200 oc
+3137 1831 MXY
+(br)135 200 oc
+3 f F
+1881 3126(Figure)N
+2128(5.)X
+1 f F
+2228(Basic)X
+2426(timing)X
+2654(estimates.)X
+755 3362(Figure)N
+985(6)X
+1046(shows)X
+1267(the)X
+1386(times)X
+1580(required)X
+1868(to)X
+1950(perform)X
+2229(thread)X
+2450(initialization)X
+2874(for)X
+2988(both)X
+3150(the)X
+3268(single-argument)X
+3809(version)X
+4065(and)X
+4201(the)X
+555 3466(version)N
+822(that)X
+973(supports)X
+1275(varargs,)X
+1562(the)X
+1690(latter)X
+1885(measured)X
+2223(passing)X
+2493(several)X
+2751(different)X
+3058(numbers)X
+3364(of)X
+3461(arguments.)X
+3865(Note)X
+4051(that)X
+4201(the)X
+555 3570(KSR1)N
+770(version)X
+1026(does)X
+1193(not)X
+1315(currently)X
+1625(support)X
+1885(varargs.)X
+1043 3677(_)N
+1051(_____________________________________________________________________)X
+1162 3781(Machine)N
+1662(Single)X
+1886(Arg)X
+2151(Varargs)X
+2426(0)X
+2586(Varargs)X
+2861(2)X
+3021(Varargs)X
+3296(4)X
+3456(Varargs)X
+3731(8)X
+1043 3797(_)N
+1051(_____________________________________________________________________)X
+1043 3813(_)N
+1051(_____________________________________________________________________)X
+1152 3909(AXP)N
+1774(<0.1)X
+2278(1.4)X
+2713(1.5)X
+3148(1.6)X
+3583(1.7)X
+1171 4013(i386)N
+1819(2.5)X
+2238(15.7)X
+2673(18.1)X
+3108(22.0)X
+9 f F
+3611(-)X
+1 f F
+1145 4117(KSR1)N
+1819(0.6)X
+9 f F
+2306(-)X
+2741(-)X
+3176(-)X
+3611(-)X
+1 f F
+1127 4221(M88100)N
+9 f F
+1834(-)X
+2306(-)X
+2741(-)X
+3176(-)X
+3611(-)X
+1 f F
+1093 4325(MIPS)N
+1299(R3000)X
+1819(1.7)X
+2278(3.4)X
+2713(4.5)X
+3148(5.3)X
+3583(7.0)X
+1093 4429(SPARC)N
+1365(4-65)X
+1819(1.8)X
+2278(5.1)X
+2713(6.2)X
+3148(7.4)X
+3543(10.7)X
+1083 4533(SPARC)N
+1355(4-490)X
+1819(0.7)X
+2278(2.5)X
+2713(3.1)X
+3148(4.0)X
+3583(5.4)X
+1105 4637(VAX)N
+1299(3500)X
+1819(4.1)X
+2238(29.0)X
+2673(31.0)X
+3108(36.0)X
+3543(42.0)X
+1043 4661(_)N
+1051(_____________________________________________________________________)X
+9 f F
+1043 MX
+(br)135 200 oc
+1043 4637 MXY
+(br)135 200 oc
+1043 4557 MXY
+(br)135 200 oc
+1043 4477 MXY
+(br)135 200 oc
+1043 4397 MXY
+(br)135 200 oc
+1043 4317 MXY
+(br)135 200 oc
+1043 4237 MXY
+(br)135 200 oc
+1043 4157 MXY
+(br)135 200 oc
+1043 4077 MXY
+(br)135 200 oc
+1043 3997 MXY
+(br)135 200 oc
+1043 3917 MXY
+(br)135 200 oc
+1043 3837 MXY
+(br)135 200 oc
+1043 3757 MXY
+(br)135 200 oc
+3811 4661 MXY
+(br)135 200 oc
+3811 4637 MXY
+(br)135 200 oc
+3811 4557 MXY
+(br)135 200 oc
+3811 4477 MXY
+(br)135 200 oc
+3811 4397 MXY
+(br)135 200 oc
+3811 4317 MXY
+(br)135 200 oc
+3811 4237 MXY
+(br)135 200 oc
+3811 4157 MXY
+(br)135 200 oc
+3811 4077 MXY
+(br)135 200 oc
+3811 3997 MXY
+(br)135 200 oc
+3811 3917 MXY
+(br)135 200 oc
+3811 3837 MXY
+(br)135 200 oc
+3811 3757 MXY
+(br)135 200 oc
+3 f F
+1827 4844(Figure)N
+2074(6.)X
+1 f F
+2174(Microseconds)X
+2644(to)X
+2726(initialize.)X
+755 5080(Figure)N
+986(7)X
+1048(shows)X
+1270(the)X
+1390(times)X
+1585(for)X
+1701(integer-only)X
+2115(and)X
+2253(generic)X
+2512(context)X
+2770(switches.)X
+3108(On)X
+3228(some)X
+3419(machines,)X
+3763(all)X
+3864(\257oating-point)X
+555 5184(registers)N
+847(are)X
+966(caller-save,)X
+1355(so)X
+1466(integer-only)X
+1878(and)X
+2014(generic)X
+2271(context)X
+2527(switches)X
+2823(are)X
+2942(identical.)X
+755 5316(Figure)N
+987(8)X
+1050(shows)X
+1273(the)X
+1394(time)X
+1559(required)X
+1850(to)X
+1935(initialize,)X
+2258(start)X
+2419(and)X
+2558(stop)X
+2714(a)X
+2773(thread.)X
+3037(The)X
+3185(reported)X
+3476(time)X
+3640(is)X
+3715(that)X
+3857(required)X
+4147(for)X
+4263(a)X
+555 5420(\252generator\272)N
+963(thread)X
+1196(to)X
+1290(initialize)X
+1601(an)X
+1708(allocated)X
+2029(thread)X
+2261(plus)X
+2425(two)X
+2576(context)X
+2843(switches:)X
+3172(one)X
+3319(to)X
+3412(perform)X
+3702(an)X
+3809(integer)X
+4063(context)X
+555 5524(switch)N
+790(to)X
+878(block)X
+1082(the)X
+1206(generator)X
+1536(and)X
+1678(a)X
+1740(second)X
+1989(to)X
+2077(abort)X
+2267(the)X
+2390(new)X
+2549(thread)X
+2775(and)X
+2916(restart)X
+3142(the)X
+3265(generator.)X
+3634(Varargs)X
+3914(routines)X
+4197(did)X
+555 5628(not)N
+677(use)X
+804(any)X
+940(of)X
+1027(their)X
+1194(arguments.)X
+
+%%Page: 19 19
+19 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(19)X
+2487(-)X
+1797 683(_)N
+1816(_______________________________)X
+2431 787(Integer)N
+2794(Int+FP)X
+1916 839(Machine)N
+2416 891(Cswap)N
+2796(Cswap)X
+1797 907(_)N
+1816(_______________________________)X
+1797 923(_)N
+1816(_______________________________)X
+1906 1019(AXP)N
+2515(1.0)X
+2875(2.0)X
+1925 1123(i386)N
+2475(10.4)X
+2835(10.4)X
+1899 1227(KSR1)N
+2515(6.2)X
+2835(14.6)X
+1881 1331(M88100)N
+9 f F
+2543(-)X
+2903(-)X
+1 f F
+1847 1435(MIPS)N
+2053(R3000)X
+2515(1.9)X
+2875(4.6)X
+1847 1539(SPARC)N
+2119(4-65)X
+2475(32.3)X
+2835(32.7)X
+1837 1643(SPARC)N
+2109(4-490)X
+2475(16.7)X
+2835(16.5)X
+1859 1747(VAX)N
+2053(3500)X
+2475(21.0)X
+2835(22.0)X
+1797 1771(_)N
+1816(_______________________________)X
+9 f F
+1797 MX
+(br)135 200 oc
+1797 1723 MXY
+(br)135 200 oc
+1797 1643 MXY
+(br)135 200 oc
+1797 1563 MXY
+(br)135 200 oc
+1797 1483 MXY
+(br)135 200 oc
+1797 1403 MXY
+(br)135 200 oc
+1797 1323 MXY
+(br)135 200 oc
+1797 1243 MXY
+(br)135 200 oc
+1797 1163 MXY
+(br)135 200 oc
+1797 1083 MXY
+(br)135 200 oc
+1797 1003 MXY
+(br)135 200 oc
+1797 923 MXY
+(br)135 200 oc
+1797 843 MXY
+(br)135 200 oc
+1797 763 MXY
+(br)135 200 oc
+3056 1771 MXY
+(br)135 200 oc
+3056 1723 MXY
+(br)135 200 oc
+3056 1643 MXY
+(br)135 200 oc
+3056 1563 MXY
+(br)135 200 oc
+3056 1483 MXY
+(br)135 200 oc
+3056 1403 MXY
+(br)135 200 oc
+3056 1323 MXY
+(br)135 200 oc
+3056 1243 MXY
+(br)135 200 oc
+3056 1163 MXY
+(br)135 200 oc
+3056 1083 MXY
+(br)135 200 oc
+3056 1003 MXY
+(br)135 200 oc
+3056 923 MXY
+(br)135 200 oc
+3056 843 MXY
+(br)135 200 oc
+3056 763 MXY
+(br)135 200 oc
+3 f F
+1735 1954(Figure)N
+1982(7.)X
+1 f F
+2082(Microseconds)X
+2552(to)X
+2634(context)X
+2890(switch.)X
+1043 2165(_)N
+1051(_____________________________________________________________________)X
+1162 2269(Machine)N
+1662(Single)X
+1886(Arg)X
+2151(Varargs)X
+2426(0)X
+2586(Varargs)X
+2861(2)X
+3021(Varargs)X
+3296(4)X
+3456(Varargs)X
+3731(8)X
+1043 2285(_)N
+1051(_____________________________________________________________________)X
+1043 2301(_)N
+1051(_____________________________________________________________________)X
+1152 2397(AXP)N
+1816(1.1)X
+2278(2.7)X
+2713(2.7)X
+3148(2.8)X
+3583(2.9)X
+1171 2501(i386)N
+1776(22.5)X
+2238(39.9)X
+2673(42.4)X
+3108(46.2)X
+9 f F
+3611(-)X
+1 f F
+1145 2605(KSR1)N
+1776(12.0)X
+9 f F
+2306(-)X
+2741(-)X
+3176(-)X
+3611(-)X
+1 f F
+1127 2709(M88100)N
+9 f F
+1844(-)X
+2306(-)X
+2741(-)X
+3176(-)X
+3611(-)X
+1 f F
+1093 2813(MIPS)N
+1299(R3000)X
+1816(4.6)X
+2278(7.2)X
+2713(8.3)X
+3148(9.2)X
+3543(10.7)X
+1093 2917(SPARC)N
+1365(4-65)X
+1776(75.6)X
+2238(80.8)X
+2673(82.2)X
+3108(82.8)X
+3543(85.2)X
+1083 3021(SPARC)N
+1355(4-490)X
+1776(38.6)X
+2238(39.7)X
+2673(41.5)X
+3108(41.2)X
+3543(43.9)X
+1105 3125(VAX)N
+1299(3500)X
+1776(45.0)X
+2238(81.0)X
+2673(87.0)X
+3108(90.0)X
+3543(97.0)X
+1043 3149(_)N
+1051(_____________________________________________________________________)X
+9 f F
+1043 MX
+(br)135 200 oc
+1043 3125 MXY
+(br)135 200 oc
+1043 3045 MXY
+(br)135 200 oc
+1043 2965 MXY
+(br)135 200 oc
+1043 2885 MXY
+(br)135 200 oc
+1043 2805 MXY
+(br)135 200 oc
+1043 2725 MXY
+(br)135 200 oc
+1043 2645 MXY
+(br)135 200 oc
+1043 2565 MXY
+(br)135 200 oc
+1043 2485 MXY
+(br)135 200 oc
+1043 2405 MXY
+(br)135 200 oc
+1043 2325 MXY
+(br)135 200 oc
+1043 2245 MXY
+(br)135 200 oc
+3811 3149 MXY
+(br)135 200 oc
+3811 3125 MXY
+(br)135 200 oc
+3811 3045 MXY
+(br)135 200 oc
+3811 2965 MXY
+(br)135 200 oc
+3811 2885 MXY
+(br)135 200 oc
+3811 2805 MXY
+(br)135 200 oc
+3811 2725 MXY
+(br)135 200 oc
+3811 2645 MXY
+(br)135 200 oc
+3811 2565 MXY
+(br)135 200 oc
+3811 2485 MXY
+(br)135 200 oc
+3811 2405 MXY
+(br)135 200 oc
+3811 2325 MXY
+(br)135 200 oc
+3811 2245 MXY
+(br)135 200 oc
+3 f F
+1738 3332(Figure)N
+1985(8.)X
+1 f F
+2085(Microseconds)X
+2555(to)X
+2637(start)X
+2795(and)X
+2931(abort.)X
+3 f F
+555 3540(6.2.)N
+715(Implementation)X
+1 f F
+555 3672(The)N
+710(QuickThreads)X
+1195(implementation)X
+1727(for)X
+1851(all)X
+1961(platforms)X
+2297(except)X
+2536(for)X
+2659(the)X
+2786(KSR)X
+2970(is)X
+3052(about)X
+3259(400)X
+3408(lines)X
+3588(of)X
+3684(assembler)X
+4034(and)X
+4179(400)X
+555 3776(lines)N
+728(of)X
+817(C)X
+892(and)X
+1030(includes)X
+1319(support)X
+1581(for)X
+1697(user)X
+1853(functions)X
+2173(that)X
+2315(take)X
+2471(variant)X
+2716(argument)X
+3041(lists.)X
+3230(KSR)X
+3406(support)X
+3667(is)X
+3741(an)X
+3838(additional)X
+4179(400)X
+555 3880(lines)N
+733(and)X
+876(lacks)X
+1067(variant)X
+1316(argument)X
+1645(list)X
+1768(support.)X
+2074(In)X
+2167(Figure)X
+2402(9,)X
+2488(the)X
+2612(column)X
+2878(\252Assembler\272)X
+3319(is)X
+3398(the)X
+3522(number)X
+3793(of)X
+3886(assembly)X
+4210(in-)X
+555 3984(structions,)N
+909(the)X
+1030(column)X
+1293(\252C\272)X
+1441(is)X
+1517(approximately)X
+2003(the)X
+2124(number)X
+2391(of)X
+2480(useful)X
+2698(lines)X
+2871(of)X
+2960(C,)X
+3055(and)X
+3193(the)X
+3313(column)X
+3575(\252Comments\272)X
+4015(is)X
+4090(the)X
+4210(to-)X
+555 4088(tal)N
+655(lines)X
+826(minus)X
+1041(the)X
+1159(other)X
+1344(lines)X
+1515(reported)X
+1803(and)X
+1939(consists)X
+2212(of)X
+2299(lines)X
+2470(that)X
+2610(are)X
+2729(either)X
+2932(blank)X
+3130(or)X
+3217(that)X
+3357(contain)X
+3613(only)X
+3775(comments.)X
+1634 4195(_)N
+1660(_______________________________________)X
+1702 4299(Machine)N
+2131(Assembler)X
+2627(C)X
+2834(Comments)X
+1634 4315(_)N
+1660(_______________________________________)X
+1634 4331(_)N
+1660(_______________________________________)X
+1674 4427(Common)N
+2322(0)X
+2594(120)X
+3007(80)X
+1634 4451(_)N
+1660(_______________________________________)X
+1712 4555(AXP)N
+2242(100)X
+2634(70)X
+2967(230)X
+1731 4659(i386)N
+2282(35)X
+2634(30)X
+2967(120)X
+1705 4763(KSR1)N
+2242(380)X
+2634(30)X
+2967(190)X
+1687 4867(M88100)N
+2282(60)X
+2634(75)X
+2967(230)X
+1709 4971(MIPS)N
+2282(75)X
+2634(30)X
+2967(150)X
+1686 5075(SPARC)N
+2282(55)X
+2634(30)X
+2967(165)X
+1705 5179(VAX)N
+2282(35)X
+2634(25)X
+2967(110)X
+1634 5195(_)N
+1660(_______________________________________)X
+1634 5211(_)N
+1660(_______________________________________)X
+1738 5307(Total)N
+2242(740)X
+2594(410)X
+2927(1285)X
+1634 5331(_)N
+1660(_______________________________________)X
+9 f F
+1634 MX
+(br)135 200 oc
+1634 5315 MXY
+(br)135 200 oc
+1634 5235 MXY
+(br)135 200 oc
+1634 5155 MXY
+(br)135 200 oc
+1634 5075 MXY
+(br)135 200 oc
+1634 4995 MXY
+(br)135 200 oc
+1634 4915 MXY
+(br)135 200 oc
+1634 4835 MXY
+(br)135 200 oc
+1634 4755 MXY
+(br)135 200 oc
+1634 4675 MXY
+(br)135 200 oc
+1634 4595 MXY
+(br)135 200 oc
+1634 4515 MXY
+(br)135 200 oc
+1634 4435 MXY
+(br)135 200 oc
+1634 4355 MXY
+(br)135 200 oc
+1634 4275 MXY
+(br)135 200 oc
+3220 5331 MXY
+(br)135 200 oc
+3220 5315 MXY
+(br)135 200 oc
+3220 5235 MXY
+(br)135 200 oc
+3220 5155 MXY
+(br)135 200 oc
+3220 5075 MXY
+(br)135 200 oc
+3220 4995 MXY
+(br)135 200 oc
+3220 4915 MXY
+(br)135 200 oc
+3220 4835 MXY
+(br)135 200 oc
+3220 4755 MXY
+(br)135 200 oc
+3220 4675 MXY
+(br)135 200 oc
+3220 4595 MXY
+(br)135 200 oc
+3220 4515 MXY
+(br)135 200 oc
+3220 4435 MXY
+(br)135 200 oc
+3220 4355 MXY
+(br)135 200 oc
+3220 4275 MXY
+(br)135 200 oc
+3 f F
+1651 5514(Figure)N
+1898(9.)X
+1 f F
+1998(Implementation)X
+2525(size,)X
+2690(in)X
+2772(lines)X
+2943(of)X
+3030(code.)X
+755 5750(The)N
+901(core)X
+1061(is)X
+1135(small)X
+1329(enough)X
+1586(that)X
+1727(it)X
+1791(should)X
+2024(be)X
+2120(straightforward)X
+2635(to)X
+2717(implement)X
+3079(for)X
+3193(a)X
+3249(new)X
+3403(machine.)X
+3735(In)X
+3822(the)X
+3940(current)X
+4188(im-)X
+555 5854(plementations)N
+1026(there)X
+1209(has)X
+1338(been)X
+1512(no)X
+1614(attempt)X
+1876(at)X
+1956(conciseness,)X
+2377(nor)X
+2505(have)X
+2678(the)X
+2797(implementations)X
+3351(been)X
+3524(tuned.)X
+3763(There)X
+3972(is)X
+4046(no)X
+4147(code)X
+
+%%Page: 20 20
+20 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(20)X
+2487(-)X
+555 680(to)N
+637(help)X
+795(with)X
+957(debugging.)X
+755 812(The)N
+908(design)X
+1145(of)X
+1240(QuickThreads)X
+1722(is)X
+1802(optimized)X
+2149(around)X
+2399(several)X
+2654(assumptions.)X
+3116(It)X
+3192(is)X
+3272(expected)X
+3585(that)X
+3732(function)X
+4026(calls)X
+4200(are)X
+555 916(cheap)N
+767(and)X
+907(that)X
+1051(passing)X
+1315(a)X
+1375(few)X
+1520(unused)X
+1771(arguments)X
+2129(to)X
+2215(the)X
+2337(helper)X
+2562(routines)X
+2844(is)X
+2921(cheap.)X
+3173(Both)X
+3352(of)X
+3443(these)X
+3632(assumptions)X
+4051(are)X
+4174(true)X
+555 1020(on)N
+659(most)X
+838(RISC)X
+1039(architectures,)X
+1494(but)X
+1619(may)X
+1780(be)X
+1879(a)X
+1938(source)X
+2171(of)X
+2261(inef\256ciency)X
+2663(on)X
+2766(machines)X
+3092(that)X
+3235(pass)X
+3396(arguments)X
+3753(on)X
+3856(the)X
+3977(stack,)X
+4185(etc.)X
+555 1124(In)N
+646(particular,)X
+998(the)X
+1120(i386)X
+1286(and)X
+1426(VAX)X
+1624(ports)X
+1808(suffer)X
+2020(relative)X
+2284(to)X
+2369(the)X
+2490(RISC)X
+2690(processors)X
+3052(because)X
+3330(the)X
+3451(RISC)X
+3651(processors)X
+4013(can)X
+4148(typi-)X
+555 1228(cally)N
+732(call)X
+869(the)X
+988(helper)X
+1210(functions)X
+1529(by)X
+1630(simply)X
+1868(changing)X
+2183(the)X
+2302(stack)X
+2488(pointer)X
+2736(and)X
+2873(\256rst)X
+3018(argument)X
+3342(register,)X
+3624(while)X
+3823(the)X
+3942(CISC)X
+4139(ports)X
+555 1332(have)N
+727(calling)X
+965(conventions)X
+1372(that)X
+1512(require)X
+1760(arguments)X
+2114(to)X
+2196(be)X
+2292(copied)X
+2526(from)X
+2702(the)X
+2820(old)X
+2942(thread's)X
+3221(stack)X
+3406(to)X
+3488(the)X
+3606(new)X
+3760(thread's)X
+4039(stack.)X
+755 1464(Many)N
+971(implementations)X
+1532(use)X
+1667(essentially)X
+2033(the)X
+2159(same)X
+2352(code)X
+2532(for)X
+7 f F
+2654(QT_BLOCKI)X
+1 f F
+3114(and)X
+7 f F
+3258(QT_ABORT)X
+1 f F
+(,)S
+3690(and)X
+7 f F
+3834(QT_BLOCK)X
+1 f F
+4246(is)X
+555 1568(sometimes)N
+917(implemented)X
+1355(by)X
+1455(saving)X
+1684(\257oating-point)X
+2139(registers,)X
+2451(then)X
+2609(calling)X
+7 f F
+2847(QT_BLOCKI)X
+1 f F
+(.)S
+755 1700(Most)N
+947(implementations)X
+1508(use)X
+1643(the)X
+1769(same)X
+1962(routine)X
+2216(both)X
+2385(to)X
+2474(restore)X
+2720(state)X
+2894(on)X
+3001(context)X
+3264(switches)X
+3567(and)X
+3710(to)X
+3799(restore)X
+4045(state)X
+4219(on)X
+555 1804(thread)N
+778(startup.)X
+1058(Startup)X
+1311(generally)X
+1632(needs)X
+1836(to)X
+1919(restore)X
+2159(only)X
+2322(a)X
+2379(little)X
+2546(bit)X
+2651(of)X
+2739(state,)X
+2927(but)X
+3050(the)X
+3169(context)X
+3426(switch)X
+3656(routine)X
+3904(must)X
+4080(restore)X
+555 1908(many)N
+755(registers.)X
+1089(Thus,)X
+1291(thread)X
+1514(startup)X
+1754(time)X
+1918(might)X
+2126(be)X
+2224(substantially)X
+2650(better)X
+2855(if)X
+2926(the)X
+3046(saved)X
+3251(state)X
+3420(of)X
+3509(a)X
+3566(thread)X
+3788(indicated)X
+4103(which)X
+555 2012(routine)N
+816(to)X
+912(use)X
+1053(to)X
+1149(restore)X
+1402(state.)X
+1623(However,)X
+1972(the)X
+2104(implementation)X
+2640(would)X
+2873(be)X
+2982(more)X
+3180(complicated)X
+3605(and)X
+3754(context)X
+4023(switches)X
+555 2116(might)N
+761(be)X
+857(somewhat)X
+1202(slower.)X
+755 2248(More)N
+953(than)X
+1115 MX
+(12)130 833 oc
+1206(of)X
+1297(the)X
+1418(AXP)X
+1601(and)X
+1740(88100)X
+1963(implementations)X
+2519(are)X
+2641(for)X
+2758(handling)X
+3061(varargs.)X
+3361(Other)X
+3567(platforms)X
+3897(are)X
+4019(typically)X
+555 2352(one-third.)N
+755 2484(The)N
+900(SPARC)X
+1172(port)X
+1321(is)X
+1394(implemented)X
+1832(using)X
+2025(techniques)X
+2388(described)X
+2716(elsewhere)X
+3058([Kep91].)X
+3 f F
+555 2692(7.)N
+655(Related)X
+938(Work)X
+2 f F
+555 2824(Coroutines)N
+1 f F
+944(are)X
+1077(functions)X
+1409(that)X
+1562(can)X
+1707(both)X
+1882(return)X
+2107(a)X
+2176(value)X
+2383(and)X
+2532(save)X
+2708(their)X
+2888(current)X
+3149(state)X
+3329(for)X
+3456(later)X
+3632(invocations)X
+4034([Knu73,)X
+555 2928(Pra86].)N
+831(Coroutines)X
+1204(are)X
+1325(typically)X
+1627(invoked)X
+1907(by)X
+2009(name)X
+2204(\(e.g.,)X
+2388(the)X
+2507(predecessor)X
+2908(names)X
+3134(the)X
+3253(successor)X
+3582(explicitly\),)X
+3952(scheduling)X
+555 3032(is)N
+628(typically)X
+928(limited)X
+1174(to)X
+1256(\256xed)X
+1436(orderings,)X
+1779(and)X
+1915(coroutines)X
+2269(cannot)X
+2503(overlap)X
+2764(execution.)X
+2 f F
+755 3164(Threads,)N
+1059(tasks)X
+1 f F
+1219(,)X
+1261(and)X
+2 f F
+1399(lightweight)X
+1780(processes)X
+1 f F
+2114(are)X
+2235(generalized)X
+2628(coroutines)X
+2983(where)X
+3201(control)X
+3449(transfers)X
+3747(are)X
+3867(implicit)X
+4136(\(e.g.,)X
+555 3268(a)N
+615(thread)X
+840(suspends)X
+1153(itself)X
+1337(without)X
+1605(naming)X
+1869(its)X
+1968(successor\);)X
+2349(thread)X
+2574(scheduling)X
+2945(\(the)X
+3094(order)X
+3288(of)X
+3379(execution)X
+3715(of)X
+3806(threads\))X
+4088(can)X
+4223(be)X
+555 3372(general,)N
+836(with)X
+1002(successors)X
+1365(implied)X
+1633(instead)X
+1884(of)X
+1975(being)X
+2177(named)X
+2414(explicitly;)X
+2761(and)X
+2900(threads)X
+3155(can)X
+3290(run)X
+3420(concurrently,)X
+3869(where)X
+4089(corou-)X
+555 3476(tines)N
+727(use)X
+855(strict)X
+1036(interleaving.)X
+1479(A)X
+2 f F
+1557(preemptive)X
+1 f F
+1934(scheduling)X
+2301(policy)X
+2521(can)X
+2653(suspend)X
+2931(threads)X
+3183(at)X
+3261(arbitrary)X
+3558(times;)X
+3773(threads)X
+4025(need)X
+4197(not)X
+555 3580(not)N
+690(explicilty)X
+1025(invoke)X
+1276(blocking)X
+1589(constructs.)X
+1987(Most)X
+2184(threads)X
+2449(packages)X
+2777(provide)X
+3055(various)X
+3324(additional)X
+3677(constructs)X
+4035(for)X
+4161(syn-)X
+555 3684(chronization)N
+976([Bir89].)X
+2 f F
+755 3816(Continuations)N
+1 f F
+1239(are)X
+1370(closures)X
+1665(that)X
+1816(implement)X
+2189(general-purpose)X
+2738(control)X
+2996(constructs.)X
+3392(Although)X
+3725(continuations)X
+4187(can)X
+555 3920(implement)N
+923(threads,)X
+8 s F
+1175 3880(9)N
+10 s F
+1233 3920(threads)N
+1491(do)X
+1597(not)X
+1725(necessarily)X
+2108(rely)X
+2259(on)X
+2365(language)X
+2681(and)X
+2823(compiler)X
+3134(support.)X
+3440(Also,)X
+3637(threads)X
+3895(are)X
+4019(typically)X
+555 4024(optimized)N
+895(to)X
+977(the)X
+1095(special)X
+1338(case)X
+1497(of)X
+1584(context)X
+1840(switch,)X
+2089(where)X
+2306(continuations)X
+2757(are)X
+2876(more)X
+3061(general.)X
+755 4156(PRESTO)N
+1075([BLL88])X
+1383(is)X
+1458(an)X
+1556(extensible)X
+1903(user-space)X
+2265(threads)X
+2519(package.)X
+2845(It)X
+2916(allows)X
+3147(multiple)X
+3435(preemptable)X
+3854(threads)X
+4108(to)X
+4192(run)X
+555 4260(concurrently)N
+987(on)X
+1092(a)X
+1153(multiprocessor.)X
+1694(PRESTO)X
+2016(was)X
+2166(designed)X
+2476(with)X
+2643(the)X
+2766(philosophy)X
+3146(that)X
+3291(users)X
+3481(should)X
+3719(be)X
+3820(able)X
+3979(to)X
+4066(replace)X
+555 4364(components.)N
+1020(For)X
+1169(example,)X
+1499(the)X
+1635(default)X
+1896(scheduling)X
+2281(is)X
+2372(round-robin,)X
+2813(but)X
+2953(stack)X
+3156(and)X
+3309(other)X
+3511(disciplines)X
+3890(can)X
+4039(be)X
+4152(used)X
+555 4468([BLLW88].)N
+981(Originally,)X
+1354(basic)X
+1543(thread)X
+1768(creation)X
+2051(and)X
+2191(invocation)X
+2553(cost)X
+2706(several)X
+2958(hundred)X
+3245(microseconds.)X
+3750(More)X
+3948(recent)X
+4169(ver-)X
+555 4572(sions)N
+739(have)X
+911(been)X
+1083(sped)X
+1250(up)X
+1350(by)X
+1450(hard-coding)X
+1858(various)X
+2114(allocation)X
+2450(policies.)X
+755 4704(FastThreads)N
+1190([And90])X
+1505(is)X
+1601(a)X
+1680(non-preemptive)X
+2231(user-space)X
+2614(multiprocessor)X
+3133(threads)X
+3408(package)X
+3715(that)X
+3878(improves)X
+4219(on)X
+555 4808(PRESTO's)N
+932(performance)X
+1361(by)X
+1463(cleaning)X
+1757(up)X
+1859(the)X
+1979(code,)X
+2173(reimplementing)X
+2701(in)X
+2784(C)X
+2858(and)X
+2995(assembler,)X
+3357(distributing)X
+3746(the)X
+3865(run)X
+3993(queues)X
+4237(to)X
+555 4912(reduce)N
+800(contention,)X
+1188(by)X
+1298(using)X
+1501(a)X
+1567(cheap)X
+1785(scheduling)X
+2162(discipline)X
+2503(\(stack\))X
+2751(and)X
+2896(by)X
+3005(hard-coding)X
+3422(all)X
+3531(policies.)X
+3849(On)X
+3976(a)X
+4041(Sequent)X
+555 5016(Symmetry,)N
+932(the)X
+1054(basic)X
+1243(thread)X
+1468(context)X
+1728(swap)X
+1916(operation)X
+2242(takes)X
+2430(between)X
+2721(25)X
+2824(and)X
+2963(30)X
+3066(microseconds)X
+3530(and)X
+3669(includes)X
+3959(the)X
+4080(cost)X
+4232(of)X
+555 5120(scheduling)N
+931(and)X
+1076(also)X
+1234(grabbing)X
+1548(and)X
+1693(relinquishing)X
+2144(a)X
+2209(\(potentially\))X
+2634(shared)X
+2873(run)X
+3008(queue.)X
+3268(FastThreads)X
+3688(is)X
+3769(thus)X
+3930(an)X
+4034(order)X
+4232(of)X
+555 5224(magnitude)N
+916(faster)X
+1118(than)X
+1279(PRESTO,)X
+1619(but)X
+1744(is)X
+1820(also)X
+1972(less)X
+2115(\257exible.)X
+2418(Where)X
+2656(PRESTO)X
+2976(and)X
+3114(QuickThreads)X
+3591(both)X
+3755(provide)X
+4022(mechan-)X
+555 5328(isms)N
+731(for)X
+855(extending)X
+1201(their)X
+1378(basic)X
+1573(features,)X
+1878(FastThreads)X
+2300(is)X
+2383(designed)X
+2698(to)X
+2790(be)X
+2896(extended)X
+3215(by)X
+3324(rewriting)X
+3647(the)X
+3774(threads)X
+4035(package)X
+555 5432([And90].)N
+8 s 9 f F
+555 5556 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5656(9.)N
+651(Thread)X
+847(context)X
+1051(switching)X
+1316(is)X
+1375(essentially)X
+1661(control)X
+1858(transfer)X
+2068(via)X
+2162(continuation)X
+2498(passing.)X
+
+%%Page: 21 21
+21 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2340 392(-)N
+2387(21)X
+2487(-)X
+755 680(Mach)N
+963(Cthreads)X
+1273([CD88])X
+1543(is)X
+1621(widely-available)X
+2181(and)X
+2322(has)X
+2454(been)X
+2630(ported)X
+2859(to)X
+2945(many)X
+3147(machines.)X
+3514(Like)X
+3685(FastThreads,)X
+4121(many)X
+555 784(allocation)N
+893(and)X
+1031(scheduling)X
+1400(decisions)X
+1720(are)X
+1841(\252locked)X
+2113(in\272.)X
+2273(Cthreads)X
+2580(is)X
+2655(implemented)X
+3095(in)X
+3179(layers)X
+3393(and)X
+3531(one)X
+3669(of)X
+3757(the)X
+3876(undocument-)X
+555 888(ed)N
+651(inner)X
+836(layers)X
+1048(bears)X
+1238(resemblance)X
+1660(to)X
+1742(QuickThreads)X
+2217([Bar93].)X
+755 1020(POSIX)N
+1007(threads,)X
+1280(Pthreads,)X
+1597(have)X
+1770(a)X
+1827(set)X
+1937(of)X
+2025(behavior)X
+2327(defaults)X
+2602(and)X
+2738(a)X
+2794(set)X
+2903(of)X
+2990(attributes)X
+3308(that)X
+3448(may)X
+3606(be)X
+3702(set)X
+3811(by)X
+3911(user)X
+4065(code)X
+4237(to)X
+555 1124(con\256gure)N
+879(Pthreads)X
+1176(to)X
+1259(the)X
+1378(application.)X
+1795(However,)X
+2131(since)X
+2317(there)X
+2499(are)X
+2619(many)X
+2818(con\256guration)X
+3266(attributes,)X
+3605(each)X
+3774(thread)X
+3996(operation)X
+555 1228(potentially)N
+917(needs)X
+1120(to)X
+1202(make)X
+1396(many)X
+1594(runtime)X
+1863(decisions)X
+2181(in)X
+2263(order)X
+2453(to)X
+2535(evaluate)X
+2823(the)X
+2941(attributes.)X
+755 1360(RapidThreads)N
+1229(is)X
+1306(a)X
+1366(non-preempting)X
+1902(uniprocessor)X
+2336(user-space)X
+2700(threads)X
+2956(package)X
+3244(core)X
+3406(that)X
+3549(sacri\256ces)X
+3871(everything)X
+4237(to)X
+555 1464(get)N
+697(raw)X
+862(performance.)X
+1353(Like)X
+1544(QuickThreads,)X
+2063(it)X
+2151(omits)X
+2372(nearly)X
+2617(all)X
+2741(functionality.)X
+3234(The)X
+3402(thread)X
+3646(state)X
+3836(is)X
+3932(a)X
+4011(block)X
+4232(of)X
+555 1568(dynamically-compiled)N
+1300(self-modifying)X
+1799(code.)X
+2014(The)X
+2162(code)X
+2337(contains)X
+2627(embedded)X
+2980(constants)X
+3301(describing)X
+3658(how)X
+3819(to)X
+3904(save)X
+4070(and)X
+4209(re-)X
+555 1672(store)N
+739(the)X
+865(stack)X
+1058(pointer)X
+1313(and)X
+1457(how)X
+1623(to)X
+1713(jump)X
+1905(to)X
+1995(the)X
+2121(next)X
+2287(thread)X
+2516([MP89].)X
+2833(On)X
+2959(one)X
+3103(processor)X
+3439(of)X
+3534(a)X
+3598(Sequent)X
+3883(Symmetry,)X
+4263(a)X
+555 1776(thread)N
+776(context)X
+1032(switch)X
+1261(takes)X
+1446(about)X
+1644(5)X
+1704(microseconds.)X
+755 1908(NewThreads)N
+1199(is)X
+1285(a)X
+1353(non-preempting)X
+1897(user-space)X
+2269(threads)X
+2533(package)X
+2829(that)X
+2981(runs)X
+3151(one)X
+3299(thread)X
+3532(on)X
+3644(each)X
+3824(processor)X
+4164(of)X
+4263(a)X
+555 2012(message-passing)N
+1119(multiprocessor.)X
+1660(Since)X
+1863(run)X
+1995(queues)X
+2243(are)X
+2367(not)X
+2494(shared,)X
+2749(no)X
+2854(locking)X
+3119(is)X
+3197(needed.)X
+3490(NewThreads)X
+3926(implements)X
+555 2116(basic)N
+740(synchronization)X
+1272(and)X
+1408(message)X
+1700(passing)X
+1960(on)X
+2060(top)X
+2182(of)X
+2269(a)X
+2325(threads)X
+2577(library.)X
+755 2248(Psyche)N
+1003([MSLM91],)X
+1413(Scheduler)X
+1755(Activations)X
+2145([ABLL91],)X
+2529(and)X
+2666(Synthesis)X
+2992([MP89])X
+3261(are)X
+3380(all)X
+3480(kernel)X
+3701(approaches)X
+4083(to)X
+4165(pro-)X
+555 2352(viding)N
+787(\256rst-class)X
+1122(threads)X
+1382(with)X
+1552(costs)X
+1739(and)X
+1882(\257exibility)X
+2219(close)X
+2411(to)X
+2500(those)X
+2696(of)X
+2790(user-level)X
+3134(threads.)X
+3433(Psyche)X
+3687(and)X
+3830(Scheduler)X
+4178(Ac-)X
+555 2456(tivations)N
+851(use)X
+979(two-level)X
+1303(scheduling)X
+1671(so)X
+1763(that)X
+1904(most)X
+2080(context)X
+2337(switches)X
+2633(occur)X
+2832(without)X
+3096(kernel)X
+3317(intervention.)X
+3764(Synthesis)X
+4090(allows)X
+555 2560(user)N
+713(processes)X
+1045(to)X
+1131(customize)X
+1480(kernel)X
+1704(threads)X
+1959(in)X
+2044(safe)X
+2197(ways)X
+2385(and)X
+2524(uses)X
+2685(very)X
+2851(fast)X
+2990(communication)X
+3511(between)X
+3802(kernel)X
+4026(and)X
+4165(user)X
+555 2664(spaces)N
+790([MP88,)X
+1057(MP89].)X
+1344(These)X
+1561(systems)X
+1839(allow)X
+2041(each)X
+2213(application)X
+2593(to)X
+2679(choose)X
+2926(\(or)X
+3044(build\))X
+3259(a)X
+3319(thread)X
+3544(library)X
+3782(that)X
+3926(implements)X
+555 2768(just)N
+695(the)X
+818(minimum)X
+1153(needed)X
+1406(functionality)X
+1840(and,)X
+2001(thus,)X
+2179(runs)X
+2342(with)X
+2509(minimum)X
+2844(overhead.)X
+3204(Psyche)X
+3456(emphasizes)X
+3851(the)X
+3974(use)X
+4105(of)X
+4196(ap-)X
+555 2872(plications)N
+897(with)X
+1070(more)X
+1265(than)X
+1433(one)X
+1579(thread)X
+1810(model)X
+2040(within)X
+2274(a)X
+2340(single)X
+2561(application,)X
+2967(though)X
+3219(all)X
+3329(of)X
+3426(the)X
+3554(above)X
+3776(systems)X
+4059(support)X
+555 2976(multi-model)N
+983(programming)X
+1452(to)X
+1546(some)X
+1747(degree.)X
+2034(All)X
+2168(of)X
+2267(these)X
+2464(systems)X
+2749(focus)X
+2955(on)X
+3067(an)X
+3175(effective)X
+3489(kernel)X
+3722(interface.)X
+4076(Quick-)X
+555 3080(Threads)N
+837(instead)X
+1087(focuses)X
+1351(on)X
+1454(the)X
+1575(construction)X
+1994(and)X
+2133(tuning)X
+2360(of)X
+2450(the)X
+2571(user-level)X
+2910(threads)X
+3164(packages)X
+3481(within)X
+3707(an)X
+3805(application)X
+4183(and)X
+555 3184(could)N
+753(be)X
+849(used)X
+1016(for)X
+1130(that)X
+1270(purpose)X
+1544(under)X
+1747(Psyche)X
+1994(and)X
+2130(Scheduler)X
+2471(Activations.)X
+755 3316(Filaments)N
+1101([EAL93])X
+1422(is)X
+1506(a)X
+1572(nonpreemptive)X
+2083(user-space)X
+2453(threads)X
+2715(package)X
+3009(that)X
+3159(restricts)X
+3443(thread)X
+3674(operations)X
+4038(to)X
+4130(those)X
+555 3420(with)N
+722(particularly)X
+1117(cheap)X
+1330(implementations:)X
+1910(threads)X
+2167(do)X
+2272(not)X
+2399(have)X
+2575(individual)X
+2923(stacks;)X
+3165(thread)X
+3390(state)X
+3561(is)X
+3638(as)X
+3729(small)X
+3926(as)X
+4017(4)X
+4081(words;)X
+555 3524(full)N
+687(thread)X
+909(creation)X
+1189(costs)X
+1370(about)X
+1569(30)X
+1670(instructions)X
+2064(and)X
+2201(thread)X
+2423(start/exit)X
+2724(can)X
+2857(be)X
+2954(less)X
+3094(than)X
+3252(10.)X
+3392(Threads)X
+3671(that)X
+3811(run)X
+3938(in)X
+4020(a)X
+4076(special)X
+555 3628(order)N
+746(\(e.g.,)X
+930(LIFO\))X
+1156(can)X
+1289(be)X
+1386(run)X
+1514(using)X
+1708(a)X
+1765(single)X
+1977(stack.)X
+2203(Threads)X
+2483(that)X
+2624(block)X
+2823(in)X
+2906(certain)X
+3146(ways)X
+3332(can)X
+3464(be)X
+3560(rewritten)X
+3870(as)X
+3957(several)X
+4205(or-)X
+555 3732(dered)N
+756(threads)X
+1010(with)X
+1174(little)X
+1342(state)X
+1511(passed)X
+1747(between)X
+2037(them.)X
+2259(Threads)X
+2540(that)X
+2682(require)X
+2932(full)X
+3065(stack)X
+3252(generality)X
+3594(cannot)X
+3829(be)X
+3926(run)X
+4054(directly)X
+555 3836(with)N
+717(Filaments.)X
+755 3968(QuickThreads)N
+1232(attempts)X
+1525(to)X
+1609(get)X
+1729(most)X
+1906(of)X
+1995(the)X
+2115(\257exibility)X
+2446(of)X
+2534(PRESTO)X
+2852(and)X
+2989(Pthreads,)X
+3306(while)X
+3505(retaining)X
+3811(most)X
+3987(of)X
+4075(perfor-)X
+555 4072(mance)N
+786(of)X
+874(FastThreads,)X
+1307(Filaments)X
+1643(and)X
+1780(RapidThreads.)X
+2291(It)X
+2360(does)X
+2527(so)X
+2618(by)X
+2718(discarding)X
+3072(everything)X
+3435(but)X
+3557(the)X
+3675(core)X
+3834(context)X
+4090(switch)X
+555 4176(operations.)N
+962(It)X
+1043(is)X
+1128(up)X
+1240(to)X
+1334(the)X
+1464(client)X
+1674(to)X
+1768(provide)X
+2045(ef\256cient)X
+2340(operations)X
+2706(with)X
+2880(the)X
+3010(desired)X
+3274(semantics)X
+3622(\(e.g.,)X
+3817(FIFO)X
+4022(or)X
+4121(LIFO)X
+555 4280(scheduling\).)N
+997(A)X
+1083(previous)X
+1387(version)X
+1651(of)X
+1746(QuickThreads)X
+2229(used)X
+2403(special)X
+2653(compiler)X
+2965(support)X
+3232(to)X
+3321(get)X
+3446(FastThreads')X
+3892(performance)X
+555 4384(without)N
+819(hard-coding)X
+1227(any)X
+1363(policies.)X
+1672(The)X
+1817(current)X
+2065(version)X
+2321(is)X
+2394(slightly)X
+2653(slower)X
+2887(but)X
+3009(does)X
+3176(not)X
+3298(rely)X
+3443(on)X
+3543(compiler)X
+3848(support.)X
+3 f F
+555 4592(8.)N
+655(Experiences)X
+1089(Using)X
+1304(QuickThreads)X
+1 f F
+555 4724(QuickThreads)N
+1033(has)X
+1163(been)X
+1338(used)X
+1508(to)X
+1593(reimplement)X
+2021(two)X
+2164(threads)X
+2419(packages,)X
+2757(PRESTO)X
+3077(and)X
+3216(NewThreads.)X
+3689(The)X
+3836(following)X
+4169(sec-)X
+555 4828(tions)N
+730(describe)X
+1018(some)X
+1207(of)X
+1294(the)X
+1412(experiences)X
+1812(and)X
+1948(lessons)X
+2199(learned.)X
+3 f F
+555 5036(8.1.)N
+715(Porting)X
+993(PRESTO)X
+1 f F
+555 5168(PRESTO)N
+875(was)X
+1023(originally)X
+1357(written)X
+1607(for)X
+1724(the)X
+1845(Sequent)X
+2125(and)X
+2263(although)X
+2565(it)X
+2631(has)X
+2760(been)X
+2934(ported)X
+3161(to)X
+3245(other)X
+3432(machines,)X
+3777(the)X
+3897(\(tricky\))X
+4160(core)X
+555 5272(context)N
+813(switch)X
+1044(code)X
+1218(has)X
+1347(not)X
+1471(changed)X
+1761(since)X
+1948(the)X
+2068(early)X
+2251(prototype.)X
+2620(The)X
+2767(basic)X
+2954(PRESTO)X
+3273(context)X
+3531(switch)X
+3762(design)X
+3993(is)X
+4068(at)X
+4148(odds)X
+555 5376(with)N
+717(QuickThreads)X
+1192(and)X
+1328(showed)X
+1593(some)X
+1782(of)X
+1869(QuickThreads')X
+2371(strengths)X
+2680(and)X
+2816(weaknesses.)X
+755 5508(For)N
+893(this)X
+1035(rewrite,)X
+1310(PRESTO)X
+1634(was)X
+1786(compiled)X
+2111(with)X
+2280(uniprocessor)X
+2717(command)X
+3060(\257ags)X
+3237(since)X
+3428(initial)X
+3640(targets)X
+3880(were)X
+4063(unipro-)X
+555 5612(cessors)N
+810(and)X
+949(spinlocks)X
+1274(are)X
+1396(a)X
+1455(source)X
+1688(of)X
+1778(machine)X
+2073(dependencies.)X
+2569(Preemption)X
+2961(was)X
+3109(disabled)X
+3398(because)X
+3675(QuickThreads)X
+4152(does)X
+555 5716(not)N
+683(support)X
+949(it)X
+1019(\(although)X
+1352(the)X
+1476(PRESTO)X
+1799(preemption)X
+2190(mechanism)X
+2581(is)X
+2660(essentially)X
+3023(the)X
+3146(same)X
+3336(as)X
+3428(the)X
+3551(QuickThreads)X
+4031(preemp-)X
+555 5820(tion)N
+699(mechanism)X
+1084(described)X
+1412(above\).)X
+
+%%Page: 22 22
+22 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(22)X
+2487(-)X
+755 680(PRESTO)N
+1073(is)X
+1147(written)X
+1395(in)X
+1478(C++.)X
+1681(Function)X
+1985(calls)X
+2152(typically)X
+2452(use)X
+2579(a)X
+2635(hidden)X
+2 f F
+2873(self)X
+1 f F
+3004(argument.)X
+3367(This)X
+3529(makes)X
+3754(it)X
+3818(hard)X
+3981(to)X
+4063(discov-)X
+555 784(er)N
+641(the)X
+7 f F
+762(vargs)X
+1 f F
+1025(parameter)X
+1370(to)X
+7 f F
+1455(QT_VARGS)X
+1 f F
+1862(during)X
+2094(thread)X
+2318(creation.)X
+2640(Furthermore,)X
+3084(the)X
+3205(original)X
+3477(interface)X
+3782(used)X
+3952(the)X
+4072(routine)X
+7 f F
+555 888(nargs)N
+1 f F
+820(to)X
+907(determine)X
+1252(the)X
+1374(number)X
+1643(of)X
+1734(arguments,)X
+2112(and)X
+7 f F
+2252(nargs)X
+1 f F
+2516(is)X
+2593(even)X
+2769(less)X
+2913(portable)X
+3200(than)X
+3362(the)X
+3484(basic)X
+3673(varargs)X
+3934(mechanism)X
+555 992(\(See)N
+720(Appendix)X
+1058(A\).)X
+1205(PRESTO)X
+1524(also)X
+1675(stored)X
+1893(the)X
+2013(C++)X
+2 f F
+2178(self)X
+1 f F
+2311(argument)X
+2636(in)X
+2719(to)X
+2802(the)X
+2921(thread)X
+3143(structure)X
+3445(at)X
+3524(a)X
+3581(different)X
+3879(time)X
+4042(than)X
+4201(the)X
+555 1096(argument)N
+885(list,)X
+1029(splitting)X
+1317(the)X
+1442(argument)X
+1772(list.)X
+1936(Fortunately,)X
+2352(the)X
+2477(QuickThreads)X
+2959(rewrite)X
+3214(can)X
+3353(take)X
+3514(advantage)X
+3867(of)X
+3961(a)X
+4023(previous)X
+555 1200(rewrite)N
+809(of)X
+902(PRESTO)X
+1225(that)X
+1371(eliminated)X
+1735(the)X
+1859(use)X
+1992(of)X
+2085(varargs)X
+2348(for)X
+2468(some)X
+2663(platforms,)X
+3016(and)X
+3158(also)X
+3312(the)X
+3435(corresponding)X
+3919(dependence)X
+555 1304(on)N
+7 f F
+661(nargs)X
+1 f F
+(.)S
+966(The)X
+1116(QuickThreads)X
+1596(port)X
+1750(still)X
+1894(uses)X
+2057(the)X
+2180(code)X
+2357(that)X
+2502(splits)X
+2695(the)X
+2818(self)X
+2959(argument)X
+3287(away)X
+3482(from)X
+3663(the)X
+3786(other)X
+3976(argument,)X
+555 1408(but)N
+689(it)X
+764(then)X
+933(reassembles)X
+1352(the)X
+1481(argument)X
+1815(list)X
+1943(using)X
+7 f F
+2147(QT_VARGS)X
+1 f F
+(.)S
+2602(Thus,)X
+2813(although)X
+3124(the)X
+3253(current)X
+3512(PRESTO)X
+3840(always)X
+4094(uses)X
+4263(a)X
+555 1512(\256xed)N
+735(number)X
+1000(of)X
+1087(arguments)X
+1441(\(two\),)X
+1655(it)X
+1719(must)X
+1894(pay)X
+2030(the)X
+2148(penalty)X
+2404(of)X
+2491(using)X
+2684(varargs)X
+2941(generality.)X
+755 1644(PRESTO)N
+1075(initializes)X
+1409(a)X
+1468(new)X
+1625(thread)X
+1849(by)X
+1952(switching)X
+2286(to)X
+2371(it,)X
+2458(then)X
+2619(having)X
+2860(it)X
+2927(overwrite)X
+3258(its)X
+3356(own)X
+3516(stack)X
+3703(while)X
+3903(the)X
+4023(thread)X
+4246(is)X
+555 1748(running)N
+829(on)X
+934(the)X
+1057(stack.)X
+1287(In)X
+1379(the)X
+1502(QuickThreads)X
+1982(rewrite,)X
+2255(this)X
+2395(crock)X
+2599(was)X
+2749(removed)X
+3055(and)X
+3196(the)X
+3319(stack)X
+3509(is)X
+3587(instead)X
+3839(initialized)X
+4184(just)X
+555 1852(before)N
+783(the)X
+903(thread)X
+1126(runs.)X
+1326(The)X
+1473(PRESTO)X
+1792(context)X
+2050(switch)X
+2281(code)X
+2455(already)X
+2714(contained)X
+3048(a)X
+3106(test)X
+3239(to)X
+3323(see)X
+3448(if)X
+3519(the)X
+3639(new)X
+3795(thread)X
+4018(has)X
+4147(been)X
+555 1956(run)N
+682(before;)X
+930(stack)X
+1115(initialization)X
+1539(was)X
+1684(just)X
+1819(added)X
+2031(to)X
+2113(an)X
+2209(existing)X
+2482(list)X
+2599(of)X
+2686(initializations.)X
+755 2088(PRESTO)N
+1086(uses)X
+1258(scheduler)X
+1600(threads,)X
+1886(but)X
+2021(the)X
+2152(scheduler)X
+2493(and)X
+2642(the)X
+2773(thread)X
+3007(it)X
+3084(is)X
+3170(running)X
+3452(communicate)X
+3917(via)X
+4048(globals.)X
+555 2192(Thus,)N
+764(the)X
+891(QuickThreads)X
+1375(blocking)X
+1684(function)X
+1980(return)X
+2201(value)X
+2404(feature)X
+2656(is)X
+2737(not)X
+2867(needed)X
+3123(for)X
+3245(communication)X
+3771(between)X
+4067(threads)X
+555 2296(and)N
+695(scheduler.)X
+1067(In)X
+1158(the)X
+1280(current)X
+1532(implementation,)X
+2078(however,)X
+2399(the)X
+2521(return)X
+2737(value)X
+2935(is)X
+3012(used)X
+3183(when)X
+3381(threads)X
+3637(join.)X
+3824(When)X
+4039(a)X
+4098(thread)X
+555 2400(terminates,)N
+930(the)X
+1049(thread)X
+1271(function)X
+1559(can)X
+1692(return)X
+1905(a)X
+1962(value)X
+2157(that)X
+2298(is)X
+2372(passed)X
+2606(to)X
+2688(a)X
+2744(joining)X
+2990(thread.)X
+3251(The)X
+3396(ideal)X
+3572(place)X
+3762(to)X
+3844(save)X
+4007(the)X
+4125(value)X
+555 2504(is)N
+630(in)X
+714(the)X
+834(thread's)X
+7 f F
+1114(cleanup)X
+1 f F
+1471(function.)X
+1799(For)X
+1931(obscure)X
+2202(reasons,)X
+2484(it)X
+2549(was)X
+2695(hard)X
+2859(to)X
+2942(call)X
+3079(C++)X
+3243(code)X
+3416(from)X
+3593(C)X
+3667(code,)X
+3860(so)X
+3952(the)X
+4071(current)X
+555 2608(implementation)N
+1090(returns)X
+1345(a)X
+7 f F
+1413(void)X
+1653(*)X
+1 f F
+1733(to)X
+1827(the)X
+1957(scheduler.)X
+2337(The)X
+2494(scheduler)X
+2834(tests)X
+3008(the)X
+3138(value,)X
+3364(and)X
+3512(if)X
+3593(it)X
+3669(is)X
+3754(not)X
+3888(a)X
+3956(designated)X
+555 2712(pointer,)N
+824(calls)X
+993(the)X
+1113(appropriate)X
+1501(cleanup)X
+1773(routine.)X
+2062(The)X
+2209(current)X
+2459(code)X
+2633(is)X
+2708(expedient)X
+3042(but)X
+3165(strictly)X
+3408(wrong)X
+3634(since)X
+3820(several)X
+4069(bit)X
+4174(pat-)X
+555 2816(terns)N
+738(\(pointer,)X
+1039(integral,)X
+1331(etc.\))X
+1499(can)X
+1638(be)X
+1741(returned)X
+2036(and)X
+2178(the)X
+2302(designated)X
+2671(pointer)X
+2924(does)X
+3097(not)X
+3225(have)X
+3403(a)X
+3465(unique)X
+3709(bit)X
+3819(pattern.)X
+4108(Using)X
+555 2920(inter-language)N
+1039(calls)X
+1206(would)X
+1426(eliminate)X
+1744(this)X
+1879(problem.)X
+755 3052(Porting)N
+1017(PRESTO)X
+1341(took)X
+1510(substantial)X
+1879(time)X
+2048(for)X
+2169(understanding)X
+2650(the)X
+2774(context)X
+3036(switch)X
+3271(code.)X
+3489(The)X
+3640(actual)X
+3858(rewrite)X
+4112(was)X
+4263(a)X
+555 3156(few)N
+697(hours.)X
+936(Once)X
+1127(a)X
+1184(QuickThreads)X
+1660(version)X
+1917(was)X
+2063(available)X
+2374(on)X
+2475(the)X
+2594(DECstation,)X
+3008(PRESTO)X
+3326(was)X
+3471(ported)X
+3696(to)X
+3778(a)X
+3834(SPARCstation)X
+555 3260(with)N
+727(about)X
+935(half)X
+1090(an)X
+1196(hour)X
+1373(of)X
+1469(matching)X
+1796(system)X
+2047(and)X
+2192(PRESTO)X
+2518(header)X
+2762(\256les)X
+2924(to)X
+3015(get)X
+3142(library)X
+3385(calls)X
+3561(to)X
+3652(work)X
+3846(correctly.)X
+4201(No)X
+555 3364(thread)N
+776(initialization)X
+1200(or)X
+1287(context)X
+1543(switch)X
+1772(code)X
+1944(was)X
+2089(changed.)X
+3 f F
+555 3572(8.2.)N
+715(Porting)X
+993(NewThreads)X
+1 f F
+555 3704(NewThreads)N
+1006(initializes)X
+1356(threads)X
+1627(with)X
+1808(a)X
+1883(function)X
+2189(pointer)X
+2455(and)X
+2610(single)X
+2840(argument.)X
+3222(Threads)X
+3520(always)X
+3782(have)X
+3973(stacks,)X
+4228(so)X
+7 f F
+555 3808(QT_ARGS)N
+1 f F
+924(was)X
+1082(used)X
+1262(directly.)X
+1580(The)X
+7 f F
+1738(startup)X
+1 f F
+2107(function)X
+2407(simply)X
+2657(calls)X
+2837(the)X
+2968(user's)X
+3193(function)X
+3493(and)X
+3641(calls)X
+3820(a)X
+3888(NewThreads)X
+555 3912(cleanup)N
+825(routine)X
+1072(if)X
+1141(the)X
+1259(user's)X
+1471(function)X
+1758(returns.)X
+755 4044(Although)N
+1081(threads)X
+1337(can)X
+1473(block)X
+1675(in)X
+1761(various)X
+2021(parts)X
+2201(of)X
+2292(the)X
+2414(NewThreads)X
+2849(library,)X
+3107(NewThreads)X
+3542(calls)X
+3713(a)X
+3773(single)X
+3987(routine)X
+4237(to)X
+555 4148(perform)N
+837(all)X
+940(context)X
+1199(switches.)X
+1538(The)X
+1686(central)X
+1928(routine)X
+2178(calls)X
+7 f F
+2348(QT_BLOCK)X
+1 f F
+2755(or)X
+7 f F
+2845(QT_BLOCKI)X
+1 f F
+3300(depending)X
+3657(on)X
+3759(whether)X
+4040(a)X
+4098(thread)X
+555 4252(\257ag)N
+698(indicates)X
+1006(\257oating-point)X
+1464(is)X
+1540(in)X
+1625(use.)X
+1795(Each)X
+1979(node)X
+2158(of)X
+2248(the)X
+2369(machine)X
+2664(behaves)X
+2946(like)X
+3089(a)X
+3148(uniprocessor,)X
+3600(so)X
+3693(no)X
+3795(queue)X
+4009(locks)X
+4200(are)X
+555 4356(needed,)N
+825(and)X
+963(threads)X
+1217(can)X
+1351(e.g.,)X
+1509(be)X
+1607(put)X
+1731(in)X
+1814(the)X
+1933(runable)X
+2195(queue)X
+2408(when)X
+2603(they)X
+2762(are)X
+2882(still)X
+3022(being)X
+3221(used.)X
+3429(Therefore,)X
+3788(the)X
+3907(helper)X
+4129(func-)X
+555 4460(tion)N
+699(simply)X
+936(updates)X
+1201(the)X
+1319(thread)X
+1540(state.)X
+755 4592(The)N
+904(original)X
+1177(context)X
+1437(switch)X
+1670(code)X
+1846(restores)X
+2120(new)X
+2278(threads)X
+2534(differently)X
+2897(than)X
+3059(threads)X
+3315(that)X
+3459(are)X
+3581(being)X
+3782(restarted.)X
+4122(Simi-)X
+555 4696(larly,)N
+749(it)X
+820(tests)X
+989(explicitly)X
+1318(whether)X
+1604(\257oating-point)X
+2066(registers)X
+2365(need)X
+2544(to)X
+2633(be)X
+2736(restored.)X
+3061(QuickThreads)X
+3542(threads)X
+3800(are)X
+3925(treated)X
+4170(uni-)X
+555 4800(formly,)N
+827(removing)X
+1168(several)X
+1430(tests)X
+1606(from)X
+1796(the)X
+1928(central)X
+2181(routine.)X
+2482(However,)X
+2831(extra)X
+3026(procedure)X
+3382(calls)X
+3563(are)X
+3696(needed)X
+3957(to)X
+4052(call)X
+4201(the)X
+555 4904(QuickThreads)N
+1030(primitives,)X
+1394(so)X
+1485(overall)X
+1728(performance)X
+2155(is)X
+2228(the)X
+2346(same.)X
+755 5036(The)N
+900(port)X
+1049(took)X
+1211(about)X
+1409(2)X
+1469(hours)X
+1667(of)X
+1754(relaxed)X
+2011(coding.)X
+3 f F
+555 5244(9.)N
+655(Future)X
+911(Work)X
+555 5452(9.1.)N
+715(Compiler)X
+1060(Support)X
+1 f F
+555 5584(Simple)N
+801(compiler)X
+1106(support)X
+1366(could)X
+1564(improve)X
+1851(raw)X
+1992(QuickThreads)X
+2467(performance)X
+2894(substantially.)X
+755 5716(On)N
+884(most)X
+1070(machines,)X
+1424(much)X
+1633(of)X
+1730(the)X
+1858(context)X
+2124(switch)X
+2363(time)X
+2535(is)X
+2618(spent)X
+2817(saving)X
+3056(and)X
+3202(restoring)X
+3517(registers.)X
+3859(The)X
+4014(compiler)X
+555 5820(could)N
+758(be)X
+859(directed)X
+1143(that)X
+1287(calls)X
+1458(to)X
+1544(blocking)X
+1848(routines)X
+2130(should)X
+2367(use)X
+2498(a)X
+2558(different)X
+2859(calling)X
+3101(convention)X
+3481(with)X
+3647(more)X
+3836(caller-save)X
+4209(re-)X
+
+%%Page: 23 23
+23 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(23)X
+2487(-)X
+555 680(gisters.)N
+829(At)X
+934(a)X
+995(context)X
+1256(switch,)X
+1510(the)X
+1633(caller)X
+1837(would)X
+2062(save)X
+2230(only)X
+2397(live)X
+2542(registers)X
+2839(and)X
+2980(the)X
+3103(register)X
+3369(saves)X
+3567(could)X
+3769(also)X
+3922(take)X
+4080(advan-)X
+555 784(tage)N
+726(of)X
+830(instruction)X
+1209(scheduling.)X
+1633(Without)X
+1932(compiler)X
+2253(support,)X
+2549(the)X
+2683(core)X
+2858(of)X
+2961(the)X
+3095(context)X
+3367(switch)X
+3612(routine)X
+3875(is)X
+3964(a)X
+4036(burst)X
+4232(of)X
+555 888(memory)N
+842(writes)X
+1058(and)X
+1194(reads.)X
+755 1020(Calls)N
+944(to)X
+7 f F
+1031(QT_ABORT)X
+1 f F
+1440(need)X
+1617(not)X
+1744(save)X
+1911(registers.)X
+2247(With)X
+2431(compiler)X
+2740(support,)X
+3024(these)X
+3213(calls)X
+3384(could)X
+3586(use)X
+3717(a)X
+3777(convention)X
+4157(with)X
+555 1124(more)N
+740(callee-save)X
+1118(registers.)X
+755 1256(As)N
+871(discussed)X
+1205(above,)X
+1444(most)X
+1626(of)X
+1720(the)X
+1845(context)X
+2108(switch)X
+2344(code)X
+2523(is)X
+2603(loads)X
+2799(and)X
+2941(stores;)X
+3176(the)X
+3300(remainder)X
+3652(is)X
+3731(typically)X
+4037(5-10)X
+4210(in-)X
+555 1360(structions)N
+886(and)X
+1022(could)X
+1220(also)X
+1369(be)X
+1465(inlined)X
+1707(in)X
+1789(the)X
+1907(caller,)X
+2126(saving)X
+2355(one)X
+2491(procedure)X
+2833(call.)X
+755 1492(Helper)N
+997(functions)X
+1318(are)X
+1440(invoked)X
+1721(from)X
+1900(within)X
+2127(the)X
+2247(context)X
+2505(switch)X
+2736(code)X
+2910(at)X
+2990(a)X
+3048(time)X
+3212(when)X
+3408(all)X
+3510(general)X
+3769(registers)X
+4063(may)X
+4223(be)X
+555 1596(clobbered)N
+903(freely.)X
+1162(However,)X
+1508(helper)X
+1740(functions)X
+2069(are)X
+2199(compiled)X
+2528(to)X
+2621(obey)X
+2808(normal)X
+3066(function)X
+3364(calling)X
+3612(conventions)X
+4029(and)X
+4175(will)X
+555 1700(thus)N
+714(needlessly)X
+1074(save)X
+1243(callee-save)X
+1627(registers)X
+1925(before)X
+2157(using)X
+2356(them.)X
+2582(With)X
+2768(compiler)X
+3079(support,)X
+3365(they)X
+3529(could)X
+3733(instead)X
+3985(use)X
+4117(a)X
+4178(cal-)X
+555 1804(ling)N
+699(convention)X
+1075(with)X
+1237(more)X
+1422(caller-save)X
+1791(registers.)X
+755 1936(Although)N
+1082(blocking)X
+1386(routines)X
+1668(are)X
+1791(called)X
+2007(with)X
+2173(many)X
+2375(different)X
+2676(helper)X
+2901(functions,)X
+3243(most)X
+3422(individual)X
+3770(call)X
+3910(sites)X
+4076(always)X
+555 2040(pass)N
+713(the)X
+831(same)X
+1016(helper.)X
+1277(In)X
+1364(these)X
+1549(cases,)X
+1759(even)X
+1931(the)X
+2049(helper)X
+2270(could)X
+2468(be)X
+2564(inlined.)X
+755 2172(Thread)N
+1004(startup)X
+1243(can)X
+1376(sometimes)X
+1739(omit)X
+1906(parts)X
+2082(of)X
+2169(the)X
+2287(normal)X
+2534(thread)X
+2755(startup)X
+2993(protocol.)X
+3320(For)X
+3451(example,)X
+3763(a)X
+3819(client)X
+4017(interface)X
+555 2276(may)N
+718(avoid)X
+921(startup)X
+1164(and)X
+1305(cleanup)X
+1580(code)X
+1757(and)X
+1898(guarantee)X
+2236(that)X
+2381(user)X
+2540(functions)X
+2863(never)X
+3067(return.)X
+3324(In)X
+3415(theses)X
+3635(cases,)X
+3849(the)X
+3971(user)X
+4129(func-)X
+555 2380(tion)N
+699(could)X
+897(be)X
+993(called)X
+1205(directly,)X
+1490(saving)X
+1719(the)X
+1837(overhead)X
+2152(of)X
+2239(at)X
+2317(least)X
+2484(one)X
+2620(procedure)X
+2962(call.)X
+755 2512(Although)N
+1087(the)X
+1215(above)X
+1437(optimizations)X
+1902(could)X
+2110(improve)X
+2407(raw)X
+2558(context)X
+2823(switch)X
+3061(times,)X
+3283(they)X
+3450(all)X
+3559(tend)X
+3726(to)X
+3817(make)X
+4020(the)X
+4147(code)X
+555 2616(larger)N
+770(and)X
+913(reduce)X
+1155(locality.)X
+1462(Thus,)X
+1669(they)X
+1834(should)X
+2074(only)X
+2243(be)X
+2346(used)X
+2520(with)X
+2689(threads)X
+2948(that)X
+3095(are)X
+3221(extremely)X
+3568(\256ne-grained.)X
+4022(Coarser-)X
+555 2720(grained)N
+827(threads)X
+1090(will)X
+1245(already)X
+1512(be)X
+1618(spending)X
+1937(most)X
+2122(of)X
+2219(their)X
+2396(time)X
+2568(doing)X
+2780(other)X
+2975(work.)X
+3210(Further,)X
+3496(for)X
+3620(blocking)X
+3930(sites)X
+4102(where)X
+555 2824(most)N
+732(callee-save)X
+1112(registers)X
+1406(are)X
+1527(in)X
+1611(use,)X
+1760(inlining)X
+2029(the)X
+2148(blocking)X
+2449(operation)X
+2773(will)X
+2918(improve)X
+3206(scheduling)X
+3574(of)X
+3662(loads)X
+3852(and)X
+3989(stores)X
+4197(but)X
+555 2928(will)N
+702(be)X
+801(unable)X
+1038(to)X
+1123(remove)X
+1387(any)X
+1526(of)X
+1616(them.)X
+1839(Finally,)X
+2108(helper)X
+2332(functions)X
+2653(are)X
+2775(often)X
+2962(small)X
+3157(enough)X
+3415(that)X
+3557(they)X
+3717(\256t)X
+3805(in)X
+3889(the)X
+4009(available)X
+555 3032(caller-save)N
+924(registers)X
+1216(of)X
+1303(existing)X
+1576(protocols,)X
+1914(so)X
+2005(in)X
+2087(practice)X
+2362(they)X
+2520(save)X
+2683(and)X
+2819(restore)X
+3058(few)X
+3199(callee-save)X
+3577(registers.)X
+3 f F
+555 3240(9.2.)N
+715(Tuning)X
+1 f F
+555 3372(Although)N
+880(the)X
+1000(QuickThreads)X
+1477(interface)X
+1781(is)X
+1856(simple,)X
+2111(it)X
+2177(still)X
+2318(has)X
+2447(many)X
+2647(possible)X
+2931(implementations,)X
+3506(each)X
+3676(with)X
+3840(tradeoffs.)X
+4188(For)X
+555 3476(example:)N
+595 3608(\267)N
+7 f F
+675(QT_BLOCK)X
+1 f F
+1090(can)X
+1233(save)X
+1407(\257oating-point)X
+1873(registers)X
+2175(then)X
+2343(call)X
+7 f F
+2489(QT_BLOCKI)X
+1 f F
+(,)S
+2971(or)X
+3068(totally)X
+3302(separate)X
+3596(routines)X
+3884(can)X
+4026(be)X
+4132(used.)X
+675 3712(The)N
+820(\256rst)X
+964(is)X
+1037(compact,)X
+1349(but)X
+1471(the)X
+1589(second)X
+1832(saves)X
+2026(a)X
+2082(procedure)X
+2424(call)X
+2560(and,)X
+2716(potentially,)X
+3098(argument)X
+3421(copying.)X
+595 3844(\267)N
+7 f F
+675(QT_ARGS)X
+1 f F
+1036(can)X
+1173(ready)X
+1377(a)X
+1438(new)X
+1597(thread)X
+1823(to)X
+1910(be)X
+2011(resumed)X
+2308(from)X
+2489(the)X
+2612(\252middle\272)X
+2931(of)X
+7 f F
+3023(QT_BLOCKI)X
+1 f F
+(,)S
+3500(or)X
+3592(each)X
+3765(\(blocked\))X
+4098(thread)X
+675 3948(can)N
+811(store)X
+991(a)X
+1051(pointer)X
+1302(to)X
+1388(the)X
+1510(code)X
+1686(that)X
+1830(will)X
+1978(resume)X
+2234(it.)X
+2342(In)X
+2433(the)X
+2555(\256rst)X
+2703(case,)X
+2886(starting)X
+3150(a)X
+3210(new)X
+3368(thread)X
+3592(will)X
+3739(restore)X
+3981(all)X
+4084(callee-)X
+675 4052(save)N
+840(registers,)X
+1154(even)X
+1328(though)X
+1572(only)X
+1736(a)X
+1794(few)X
+1936(values)X
+2162(may)X
+2321(be)X
+2418(needed)X
+2667(to)X
+2750(start)X
+2909(a)X
+2966(thread.)X
+3228(In)X
+3316(the)X
+3435(second)X
+3679(case,)X
+3859(thread)X
+4081(startup)X
+675 4156(is)N
+757(fast)X
+902(because)X
+1186(only)X
+1357(the)X
+1484(key)X
+1629(values)X
+1863(need)X
+2044(to)X
+2134(be)X
+2238(read.)X
+2445(However,)X
+2788(context)X
+3052(switches)X
+3356(may)X
+3522(be)X
+3626(slower)X
+3868(because)X
+4151(each)X
+675 4260(context)N
+931(switch)X
+1160(requires)X
+1439(an)X
+1535(indirect)X
+1800(branch.)X
+755 4392(When)N
+977(performance)X
+1413(is)X
+1495(unacceptable,)X
+1964(a)X
+2029(different)X
+2335(implementation)X
+2866(may)X
+3033(solve)X
+3231(the)X
+3358(problem.)X
+3694(However,)X
+4038(the)X
+4165(pro-)X
+555 4496(grammer)N
+876(should)X
+1120(be)X
+1227(aware)X
+1451(that)X
+1602(optimizations)X
+2068(for)X
+2193(one)X
+2340(case)X
+2510(may)X
+2678(be)X
+2784(pessimizations)X
+3285(for)X
+3409(another.)X
+3720(Ideally,)X
+3993(the)X
+4121(client)X
+555 4600(should)N
+797(be)X
+902(able)X
+1065(to)X
+1156(specify)X
+1417(where)X
+1643(performance)X
+2079(is)X
+2161(most)X
+2345(critical)X
+2597(and)X
+2742(get)X
+2869(the)X
+2996(proper)X
+3235(implementation)X
+3766([Kic92,)X
+4038(Kep93].)X
+555 4704(Note,)N
+757(however,)X
+1080(that)X
+1225(some)X
+1419(conventions)X
+1831(are)X
+1955(incompatible)X
+2398(and)X
+2539(a)X
+2600(thread)X
+2826(cannot,)X
+3085(in)X
+3172(general,)X
+3454(be)X
+3555(started)X
+3794(with)X
+3961(a)X
+4022(different)X
+555 4808(convention)N
+931(than)X
+1089(the)X
+1207(one)X
+1343(that)X
+1483(stopped)X
+1752(it.)X
+3 f F
+555 5016(9.3.)N
+715(Preemption)X
+1 f F
+555 5148(It)N
+626(would)X
+848(be)X
+946(good)X
+1128(to)X
+1212(extend)X
+1448(the)X
+1568(QuickThreads)X
+2045(interface)X
+2349(to)X
+2433(handle)X
+2669(preemption.)X
+3096(However,)X
+3432(it)X
+3497(is)X
+3571(tricky)X
+3779(to)X
+3862(do)X
+3963(so)X
+4055(without)X
+555 5252(hard-coding)N
+965(allocation)X
+1303(policies.)X
+1614(The)X
+1761(basic)X
+1948(problem)X
+2237(is)X
+2312(that)X
+2454(preemption)X
+2841(must)X
+3018(always)X
+3263(have)X
+3436(a)X
+3493(place)X
+3684(to)X
+3767(store)X
+3944(the)X
+4063(context)X
+555 5356(of)N
+642(the)X
+760(preempted)X
+1119(thread.)X
+1380(There)X
+1588(are)X
+1707(various)X
+1963(alternatives,)X
+2373(none)X
+2549(perfect:)X
+595 5488(\267)N
+675(When)X
+891(preemption)X
+1280(occurs)X
+1514(a)X
+2 f F
+1573(preemption)X
+1961(function)X
+1 f F
+2246(is)X
+2322(called)X
+2537(on)X
+2640(the)X
+2761(stack)X
+2949(of)X
+3039(the)X
+3160(preempted)X
+3522(thread.)X
+3786(The)X
+3934(preemption)X
+675 5592(function)N
+971(starts)X
+1169(another)X
+1439(thread)X
+1669(or)X
+1765(resumes)X
+2057(the)X
+2184(preempted)X
+2552(one.)X
+2737(However,)X
+3081(nested)X
+3315(preemptions)X
+3740(can)X
+3881(lead)X
+4044(to)X
+4134(stack)X
+675 5696(over\257ow.)N
+
+%%Page: 24 24
+24 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(24)X
+2487(-)X
+595 680(\267)N
+675(Scheduler)X
+1024(activations)X
+1399([ABLL90])X
+1770(maintain)X
+2078(a)X
+2142(pool)X
+2312(of)X
+2407(empty)X
+2635(stacks.)X
+2899(A)X
+2985(new)X
+3147(thread)X
+3376(\(a)X
+3467(\252scheduler)X
+3839(activation\272\))X
+4246(is)X
+675 784(created)N
+935(on)X
+1042(each)X
+1217(preemption.)X
+1648(Nested)X
+1897(preemptions)X
+2319(can)X
+2457(be)X
+2559(organized)X
+2902(in)X
+2990(a)X
+3052(way)X
+3212(that)X
+3358(cannot)X
+3598(cause)X
+3803(stack)X
+3994(over\257ow,)X
+675 888(but)N
+797(nested)X
+1022(preemptions)X
+1438(can)X
+1570(exhaust)X
+1835(the)X
+1953(free)X
+2099(stack)X
+2284(pool.)X
+595 1020(\267)N
+675(The)X
+824(preemption)X
+1213(function,)X
+1524(and)X
+1664(all)X
+1768(code)X
+1944(that)X
+2088(it)X
+2156(calls,)X
+2347(can)X
+2483(be)X
+2583(recognized)X
+2960(by)X
+3064(e.g.,)X
+3224(the)X
+3346(interrupt)X
+3646(handler.)X
+3950(The)X
+4098(obser-)X
+675 1124(vation)N
+896(is)X
+970(that)X
+1111(preempting)X
+1496(a)X
+1552(preemption)X
+1937(handler)X
+2198(is)X
+2271(redundant,)X
+2632(so)X
+2723(one)X
+2859(of)X
+2946(the)X
+3064(preemptions)X
+3480(can)X
+3612(be)X
+3708(discarded.)X
+4076(Nested)X
+675 1228(preemptions)N
+1098(either)X
+1308(restart,)X
+1556(throwing)X
+1872(away)X
+2068(previously-saved)X
+2642(preemption)X
+3033(state,)X
+3226(or)X
+3319(continue,)X
+3641(throwing)X
+3956(away)X
+4152(state)X
+675 1332(saved)N
+880(by)X
+982(the)X
+1102(nested)X
+1329(preemption.)X
+1756(Since)X
+1956(redundant)X
+2299(preemption)X
+2686(state)X
+2855(is)X
+2930(discarded,)X
+3279(the)X
+3398(space)X
+3598(needs)X
+3802(are)X
+3922(bounded)X
+4219(by)X
+675 1436(the)N
+793(number)X
+1058(of)X
+1145(threads)X
+1397(rather)X
+1605(than)X
+1763(the)X
+1881(number)X
+2146(of)X
+2233(simultaneous)X
+2675(preemptions.)X
+595 1568(\267)N
+675(A)X
+754(\256nal)X
+917(option)X
+1142(is)X
+1216(that)X
+1357(the)X
+1476(preemption)X
+1862(mechanism)X
+2248(is)X
+2322(disabled)X
+2609(until)X
+2775(it)X
+2839(is)X
+2912(reenabled)X
+3245(by)X
+3345(the)X
+3463(user-level)X
+3800(code.)X
+4012(To)X
+4121(avoid)X
+675 1672(stack)N
+874(growth)X
+1135(problems,)X
+1487(preemption)X
+1886(must)X
+2075(be)X
+2185(reenabled)X
+2532(only)X
+2707(after)X
+2888(the)X
+3019(preemption)X
+3417(handler)X
+3691(has)X
+3831(\256nished.)X
+4157(This)X
+675 1776(mechanism)N
+1060(is)X
+1133(thus)X
+1286(unable)X
+1520(to)X
+1602(handle)X
+1836(certain)X
+2075(preemtions,)X
+2471(such)X
+2638(as)X
+2725(preemptions)X
+3141(arising)X
+3379(from)X
+3555(page)X
+3727(faults.)X
+755 1908(Another)N
+1056(problem)X
+1360(with)X
+1539(supporting)X
+1918(preemption)X
+2320(is)X
+2410(that)X
+2567(preemption)X
+2969(interfaces)X
+3319(typically)X
+3636(depend)X
+3905(on)X
+4022(both)X
+4201(the)X
+555 2012(machine)N
+854(architecture)X
+1261(and)X
+1404(the)X
+1529(operating)X
+1859(system.)X
+2148(Thus,)X
+2354(a)X
+2416(QuickThreads)X
+2897(mechanism)X
+3288(to)X
+3376(support)X
+3642(preemption)X
+4033(must)X
+4214(ei-)X
+555 2116(ther)N
+702(be)X
+800(de\256ned)X
+1057(in)X
+1140(terms)X
+1339(of)X
+1427(the)X
+1546(OS)X
+1669(preemption)X
+2055(mechanism,)X
+2461(or)X
+2549(QuickThreads)X
+3025(must)X
+3201(de\256ne)X
+3418(a)X
+3475(machine-dependent)X
+4125(inter-)X
+555 2220(face,)N
+730(with)X
+892(the)X
+1010(client)X
+1208(is)X
+1281(forced)X
+1507(to)X
+1589(perform)X
+1868(the)X
+1986(mapping.)X
+755 2352(A)N
+845(good)X
+1037(implementation)X
+1571(should)X
+1816(avoid)X
+2026(excess)X
+2268(copying.)X
+2598(Note)X
+2786(that)X
+2938(saved)X
+3153(state)X
+3332(\()X
+7 f F
+3359(struct)X
+3707(sigcontext)X
+1 f F
+(\))S
+4246(is)X
+555 2456(often)N
+740(pushed)X
+987(on)X
+1087(the)X
+1205(thread)X
+1426(stack)X
+1611(during)X
+1840(preemption.)X
+755 2588(A)N
+844(typical)X
+1093(preemption)X
+1489(interface)X
+1802(would)X
+2033(reconstruct)X
+2421(the)X
+2550(thread)X
+2782(from)X
+2969(its)X
+3075(state)X
+3253(at)X
+3342(the)X
+3470(time)X
+3642(of)X
+3739(preemption.)X
+4174(The)X
+555 2692(thread)N
+780(must)X
+959(be)X
+1059(halted)X
+1279(during)X
+1512(reconstruction.)X
+2035(If)X
+2113(preemptions)X
+2533(typically)X
+2837(arrive)X
+3049(on)X
+3153(the)X
+3275(stack)X
+3464(of)X
+3555(the)X
+3676(preempted)X
+4038(process,)X
+555 2796(the)N
+677(preemption)X
+1066(handler)X
+1331(must)X
+1510(transfer)X
+1780(control)X
+2031(to)X
+2117(another)X
+2382(thread)X
+2607(before)X
+2837(it)X
+2904(reconstructs)X
+3315(the)X
+3436(preempted)X
+3798(thread)X
+4022(from)X
+4201(the)X
+555 2900(helper.)N
+755 3032(An)N
+875(interface)X
+1179(to)X
+1263(a)X
+1321(preemption)X
+1708(routine)X
+1957(would)X
+2179(take)X
+2335(the)X
+2455(context)X
+2713(of)X
+2802(a)X
+2860(preempted)X
+3221(thread)X
+3444(and)X
+3582(use)X
+3711(that)X
+3853(to)X
+3937(prepare)X
+4201(the)X
+555 3136(thread)N
+776(for)X
+890(later)X
+1053(restart.)X
+1314(For)X
+1445(example:)X
+8 s 7 f F
+843 3272(#include)N
+1185(<signal.h>)X
+843 3448(qt_t)N
+1033(*QT_PREEMT)X
+1451(\(struct)X
+1755(sigcontext)X
+2173(*preempted\))X
+10 s 1 f F
+755 3628(A)N
+842(\256nal)X
+1013(issue)X
+1202(is)X
+1284(that)X
+1433(preemption)X
+1827(during)X
+2065(a)X
+2129(context)X
+2393(switch)X
+2630(effectively)X
+3002(preempts)X
+3324(two)X
+3472(threads:)X
+3754(both)X
+3924(the)X
+4050(running)X
+555 3732(thread)N
+783(and)X
+926(the)X
+1051(thread)X
+1279(that)X
+1426(is)X
+1506(about)X
+1711(to)X
+1800(be)X
+1903(started)X
+2144(or)X
+2238(which)X
+2461(was)X
+2613(just)X
+2755(halted.)X
+3018(A)X
+3103(variety)X
+3353(of)X
+3447(subtle)X
+3665(race,)X
+3847(deadlock,)X
+4183(and)X
+555 3836(lock)N
+713(ownership)X
+1067(conditions)X
+1420(can)X
+1552(arise)X
+1724(in)X
+1806(the)X
+1924(face)X
+2079(of)X
+2166(preemption)X
+2551([BMVL92].)X
+3 f F
+555 4044(10.)N
+695(Conclusions)X
+1 f F
+555 4176(A)N
+633(minimalist)X
+994(thread)X
+1215(ADT)X
+1400(gives)X
+1589(a)X
+1645(threads)X
+1897(package)X
+2181(core)X
+2340(with:)X
+2524(good)X
+2704(performance,)X
+3151(client-built)X
+3522(functionality,)X
+3971(and)X
+4107(porta-)X
+555 4280(bility)N
+754(as)X
+852(good)X
+1043(as)X
+1141(the)X
+1270(client)X
+1479(that)X
+1630(calls)X
+1808(it.)X
+1923(Using)X
+2144(an)X
+2250(ADT)X
+2445(improves)X
+2773(over)X
+2946(full)X
+3087(threads)X
+3349(packages)X
+3674(in)X
+3766(two)X
+3916(ways:)X
+4133(First,)X
+555 4384(threads)N
+822(packages)X
+1152(have)X
+1339(been)X
+1525(notoriously)X
+1923(machine-dependent.)X
+2626(and)X
+2776(an)X
+2886(ADT)X
+3085(can)X
+3231(be)X
+3341(used)X
+3522(to)X
+3618(encapsulate)X
+4027(machine)X
+555 4488(dependencies)N
+1012(and)X
+1152(make)X
+1350(it)X
+1418(possible)X
+1704(to)X
+1790(build)X
+1978(threads)X
+2234(packages)X
+2553(that)X
+2696(are)X
+2818(both)X
+2983(portable)X
+3269(and)X
+3408(ef\256cient.)X
+3734(Second,)X
+4013(the)X
+4134(ADT)X
+555 4592(separates)N
+880(the)X
+1008(notion)X
+1242(of)X
+1339(execution)X
+1681(from)X
+1867(scheduling)X
+2244(and)X
+2390(allocation;)X
+2758(it)X
+2832(is)X
+2915(therefore)X
+3236(possible)X
+3528(to)X
+3620(implement)X
+3992(improved)X
+555 4696(idioms)N
+803(\(marker)X
+1089(threads,)X
+1372(faster)X
+1582(barriers,)X
+1879(etc.\))X
+2051(that)X
+2202(rely)X
+2358(on)X
+2468(particular)X
+2806(behavior)X
+3117(that)X
+3267(is)X
+3350(hidden)X
+3598(by)X
+3708(traditional)X
+4067(threads)X
+555 4800(packages.)N
+3 f F
+555 5008(11.)N
+695(Acknowledgements)X
+1 f F
+555 5140(Geoff)N
+770(Voelker)X
+1056(implemented)X
+1501(and)X
+1643(debugged)X
+1981(much)X
+2185(of)X
+2278(the)X
+2402(KSR1)X
+2623(port,)X
+2798(and)X
+2940(Paul)X
+3108(Barton-Davis)X
+3566(helped)X
+3806(solve)X
+4001(problems)X
+555 5244(with)N
+718(anomalous)X
+1086(timing.)X
+1355(Robert)X
+1594(Bedichek)X
+1918(helped)X
+2153(with)X
+2315(the)X
+2433(88000)X
+2653(port.)X
+2842(Dylan)X
+3058(McNamee)X
+3413(rewrote)X
+3679(NewThreads)X
+4110(to)X
+4192(use)X
+555 5348(QuickThreads.)N
+1076(Thanks)X
+1338(to)X
+1425(Tom)X
+1601(Anderson)X
+1938(for)X
+2057(discussions)X
+2446(on)X
+2551(thread)X
+2777(and)X
+2918(lock)X
+3081(implementations,)X
+3659(and)X
+3800(to)X
+3887(Paul)X
+4054(Barton-)X
+555 5452(Davis)N
+762(and)X
+898(Curtis)X
+1113(Brown)X
+1351(for)X
+1465(comments)X
+1814(on)X
+1914(earlier)X
+2140(drafts)X
+2343(of)X
+2430(this)X
+2565(paper.)X
+755 5584(This)N
+929(work)X
+1126(supported)X
+1474(by)X
+1586(NSF)X
+1764(CCR-8619663,)X
+2281(CCR-8702915A01,)X
+2936(CCR-8801806,)X
+3453(CCR-8904190,)X
+3970(PYI)X
+4130(MIP-)X
+555 5688(9058-439,)N
+902(by)X
+1002(Boeing)X
+1253(W280638,)X
+1609(and)X
+1745(by)X
+1845(Sun)X
+1989(Microsystems.)X
+
+%%Page: 25 25
+25 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(25)X
+2487(-)X
+3 f F
+555 680(References)N
+1 f F
+555 812([And90])N
+755 916(Thomas)N
+1041(E.)X
+1138(Anderson,)X
+2 f F
+1498(FastThreads)X
+1930(User's)X
+2172(Manual)X
+1 f F
+2421(.)X
+2489(In)X
+2583(the)X
+2 f F
+2708(Quartz)X
+1 f F
+2957(distribution,)X
+3372(available)X
+3689(via)X
+3814(anonymous)X
+4210(ftp)X
+755 1020(from)N
+9 s F
+929(`)X
+7 f F
+953(ftp.cs.washington.edu)X
+1 f F
+1856(')X
+10 s F
+1900(in)X
+9 s F
+1980(`)X
+7 f F
+2004(pub/Quartz1.0.tar.Z)X
+1 f F
+2821(')X
+10 s F
+2845(.)X
+555 1152([ABLL91])N
+755 1256(Thomas)N
+1039(E.)X
+1133(Anderson,)X
+1490(Brian)X
+1693(N.)X
+1796(Bershad,)X
+2104(Edward)X
+2379(D.)X
+2482(Lazowska,)X
+2853(and)X
+2994(Henry)X
+3220(M.)X
+3336(Levy.)X
+2 f F
+3566(Scheduler)X
+3912(Activations:)X
+755 1360(Effective)N
+1058(Kernel)X
+1298(Support)X
+1573(for)X
+1688(the)X
+1807(User-Level)X
+2185(Management)X
+2625(of)X
+2708(Parallelism)X
+1 f F
+(.)S
+3142(Proceedings)X
+3555(of)X
+3643(the)X
+3762(Thirteenth)X
+4117(ACM)X
+755 1464(Symposium)N
+1156(on)X
+1256(Operating)X
+1597(Systems)X
+1883(Principles,)X
+2243(October)X
+2522(1991.)X
+555 1596([ALL89])N
+755 1700(Thomas)N
+1040(E.)X
+1136(Anderson,)X
+1494(Edward)X
+1770(D.)X
+1874(Lazowska,)X
+2246(and)X
+2388(Henry)X
+2615(M.)X
+2732(Levy.)X
+2 f F
+2963(The)X
+3109(Performance)X
+3554(Implications)X
+3980(of)X
+4068(Thread)X
+755 1804(Management)N
+1194(Alternatives)X
+1601(for)X
+1714(Shared)X
+1961(Memory)X
+2249(Multiprocessors)X
+1 f F
+2769(.)X
+2829(IEEE)X
+3023(Transactions)X
+3453(on)X
+3553(Computers)X
+3924(38\(12\),)X
+4178(De-)X
+755 1908(cember)N
+1012(1989,)X
+1212(pp.)X
+1332(1631-1644.)X
+555 2040([Bar93])N
+755 2144(Paul)N
+917(Barton-Davis.)X
+1409(Personal)X
+1705(communication,)X
+2243(1993.)X
+555 2276([Ber88])N
+755 2380(Brian)N
+956(N.)X
+1057(Bershad.)X
+2 f F
+1383(The)X
+1526(PRESTO)X
+1837(User's)X
+2073(Manual)X
+1 f F
+2322(.)X
+2384(UWCSE)X
+2686(TR)X
+2810(88-01-04,)X
+3146(January)X
+3418(1988.)X
+3640(University)X
+4000(of)X
+4089(Wash-)X
+755 2484(ington.)N
+555 2616([BLL88])N
+755 2720(Brian)N
+954(N.)X
+1053(Bershad,)X
+1356(Edward)X
+1626(D.)X
+1724(Lazowska,)X
+2090(and)X
+2226(Henry)X
+2447(M.)X
+2558(Levy.)X
+2 f F
+2783(PRESTO:)X
+3119(A)X
+3188(System)X
+3431(for)X
+3544(Object-Oriented)X
+4090(Paral-)X
+755 2824(lel)N
+855(Programming)X
+1 f F
+1304(,)X
+1344(Software)X
+9 f F
+1634(-)X
+1 f F
+1678(Practice)X
+1957(and)X
+2093(Experience,)X
+2495(18\(8\),)X
+2709(pp.)X
+2829(713-732.)X
+555 2956([BLLW88])N
+755 3060(Brian)N
+960(N.)X
+1065(Bershad,)X
+1375(Edward)X
+1652(D.)X
+1757(Lazowska)X
+2110(Henry)X
+2338(M.)X
+2456(Levy,)X
+2667(and)X
+2809(David)X
+3031(B.)X
+3130(Wagner.)X
+2 f F
+3451(An)X
+3566(Open)X
+3766(Environment)X
+4206(for)X
+755 3164(Building)N
+1050(Parallel)X
+1332(Programming)X
+1801(Systems)X
+1 f F
+2055(.)X
+2115(UWCSE)X
+2415(TR)X
+2537(88-01-03,)X
+2871(January)X
+3141(1988.)X
+3361(University)X
+3719(of)X
+3806(Washington.)X
+555 3296([BMVL92])N
+755 3400(Paul)N
+921(Barton-Davis,)X
+1397(Dylan)X
+1617(McNamee,)X
+1996(Raj)X
+2131(Vaswani)X
+2436(and)X
+2576(Edward)X
+2850(D.)X
+2952(Lazowska.)X
+2 f F
+3341(Adding)X
+3595(Scheduler)X
+3939(Activations)X
+755 3504(to)N
+837(Mach)X
+1040(3.0)X
+1 f F
+(.)S
+1200(UWCSE)X
+1500(TR)X
+1622(92-08-03)X
+1936(October)X
+2215(1992.)X
+2435(University)X
+2793(of)X
+2880(Washington.)X
+555 3636([Bir89]Andrew)N
+1070(D.)X
+1168(Birrell.)X
+2 f F
+1437(An)X
+1546(Introduction)X
+1966(to)X
+2048(Programming)X
+2517(with)X
+2674(Threads)X
+1 f F
+2936(.)X
+2996(Digital)X
+3238(Equipment)X
+3609(Corporation,)X
+4036(1989.)X
+555 3768([Cha90])N
+755 3872(Jeff)N
+896(Chase.)X
+1152(Personal)X
+1448(Communication,)X
+2003(1990)X
+555 4004([CLBL92])N
+755 4108(Jeffrey)N
+1006(S.)X
+1097(Chase,)X
+1339(Hemry)X
+1588(M.)X
+1705(Levy,)X
+1916(Miche)X
+2147(Baker-Harvy)X
+2593(and)X
+2735(Edward)X
+3011(D.)X
+3135(Lazowska.)X
+2 f F
+3527(Opal:)X
+3740(A)X
+3815(Single)X
+4041(Address)X
+755 4212(Space)N
+975(System)X
+1226(for)X
+1347(64-Bit)X
+1574(Architectures)X
+1 f F
+2006(,)X
+2053(Third)X
+2258(IEEE)X
+2459(Workshop)X
+2820(on)X
+2927(Workstation)X
+3350(Operating)X
+3698(Systems)X
+3991(\(WWOS-)X
+755 4316(III\).)N
+923(April)X
+1112(1992.)X
+555 4448([CD88])N
+755 4552(Eric)N
+914(C.)X
+1011(Cooper)X
+1271(and)X
+1411(Richard)X
+1689(P.)X
+1777(Draves.)X
+2 f F
+2069(C)X
+2146(Threads)X
+1 f F
+2408(,)X
+2452(Carnegie)X
+2766(Mellon)X
+3021(University)X
+3383(Technical)X
+3724(Report)X
+3966(CMU-CS-)X
+755 4656(88-154,)N
+1022(June)X
+1189(1988.)X
+555 4788([DEC81])N
+2 f F
+755 4892(VAX)N
+922(Architecture)X
+1 f F
+1323(.)X
+1383(Digital)X
+1625(Equipment)X
+1996(Corporation,)X
+2423(1981.)X
+555 5024([EAL93])N
+755 5128(Dawson)N
+1039(R.)X
+1133(Engler,)X
+1388(Gregory)X
+1676(R.)X
+1769(Andrews,)X
+2099(and)X
+2235(David)X
+2451(K.)X
+2549(Lowenthal.)X
+2 f F
+2952(Ef\256cient)X
+3239(Support)X
+3512(for)X
+3625(Fine-Grain)X
+4010(Parallel-)X
+755 5232(ism)N
+1 f F
+(.)S
+926(TR)X
+1048(93-13,)X
+1275(University)X
+1633(of)X
+1720(Arizona)X
+1999(Department)X
+2398(of)X
+2485(Computer)X
+2825(Science.)X
+555 5364([ELZ86])N
+755 5468(Derek)N
+982(Eager,)X
+1220(Edward)X
+1500(Lazowska,)X
+1876(and)X
+2022(John)X
+2203(Zahorjan.)X
+2 f F
+2563(Adaptive)X
+2878(Load)X
+3072(Sharing)X
+3355(in)X
+3447(Homogeneous)X
+3935(Distributed)X
+755 5572(Systems)N
+1 f F
+1009(.)X
+1069(IEEE)X
+1263(Transactions)X
+1693(on)X
+1793(Software)X
+2103(Engineering,)X
+2535(12\(5\),)X
+2749(May)X
+2916(1986,)X
+3116(pp.)X
+3236(662-675.)X
+555 5704([FM92])N
+755 5808(Edward)N
+1025(W.)X
+1141(Felten)X
+1361(and)X
+1497(Dylan)X
+1713(McNamee.)X
+2 f F
+2108(NewThreads)X
+2532(2.0)X
+2652(User's)X
+2886(Guide)X
+1 f F
+3082(.)X
+3142(August)X
+3393(1992,)X
+3593(unpublished.)X
+
+%%Page: 26 26
+26 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(26)X
+2487(-)X
+555 680([Gru91])N
+755 784(Dirk)N
+922(Grunwald.)X
+1303(Personal)X
+1599(communication,)X
+2137(1991.)X
+555 916([Her88])N
+755 1020(Maurice)N
+1050(Herlihy.)X
+2 f F
+1362(Impossibility)X
+1802(and)X
+1949(Universality)X
+2372(Results)X
+2629(for)X
+2748(Wait-Free)X
+3104(Synchronization)X
+1 f F
+3624(.)X
+3690(Proceedings)X
+4108(of)X
+4201(the)X
+755 1124(Seventh)N
+1033(Annual)X
+1289(ACM)X
+1491(Symposium)X
+1892(on)X
+1992(Principles)X
+2332(of)X
+2419(Distributed)X
+2799(Computing,)X
+3198(1988,)X
+3398(pp.)X
+3518(276-291.)X
+555 1256([Kan87])N
+755 1360(Gerry)N
+963(Kane.)X
+2 f F
+1193(MIPS)X
+1396(R2000)X
+1625(RISC)X
+1814(Architecture)X
+1 f F
+2215(.)X
+2275(Prentice)X
+2558(Hall,)X
+2736(1987.)X
+555 1492([Kep91])N
+755 1596(David)N
+980(Keppel.)X
+2 f F
+1281(Register)X
+1577(Windows)X
+1899(and)X
+2048(User-Space)X
+2452(Threads)X
+2743(on)X
+2852(the)X
+2979(SPARC)X
+1 f F
+3219(.)X
+3288(UWCSE)X
+3596(TR)X
+3726(91-07-01,)X
+4068(August)X
+755 1700(1991.)N
+975(University)X
+1333(of)X
+1420(Washington.)X
+555 1832([Kep93])N
+755 1936(David)N
+975(Keppel.)X
+2 f F
+1271(Managing)X
+1624(Abstraction-Induced)X
+2307(Complexity)X
+1 f F
+2672(.)X
+2736(Technical)X
+3077(Report)X
+3319(UWCSE)X
+3623(93-06-02,)X
+3961(University)X
+755 2040(of)N
+842(Washington,)X
+1269(June)X
+1436(1993.)X
+555 2172([Kic92])N
+755 2276(Gregor)N
+1005(Kiczales.)X
+2 f F
+1344(Towards)X
+1645(a)X
+1707(New)X
+1871(Model)X
+2098(of)X
+2182(Abstraction)X
+2577(in)X
+2661(Software)X
+2967(Engineering)X
+1 f F
+3363(.)X
+3424(Proceedings)X
+3837(of)X
+3925(the)X
+4044(Interna-)X
+755 2380(tional)N
+957(Workshop)X
+1311(on)X
+1411(Re\257ection)X
+1760(and)X
+1896(Meta-Level)X
+2291(Architecture,)X
+2733(November)X
+3092(1992,)X
+3292(pp)X
+3392(1-11.)X
+555 2512([Knu73])N
+755 2616(Donald)N
+1014(Knuth.)X
+2 f F
+1277(The)X
+1420(Art)X
+1545(of)X
+1630(Computer)X
+1973(Programming)X
+1 f F
+2422(,)X
+2464(Volume)X
+2744(1:)X
+2 f F
+2828(Fundamental)X
+3277(Algorithms)X
+1 f F
+3632(.)X
+3694(1973.)X
+3916(Second)X
+4174(edi-)X
+755 2720(tion.)N
+939(Addison)X
+1230(Wesley,)X
+1511(Reading,)X
+1818(Mass.)X
+555 2852([KSR91])N
+2 f F
+755 2956(Principles)N
+1104(of)X
+1186(Operations)X
+1 f F
+1546(,)X
+1586(Kendall)X
+1860(Square)X
+2103(Research,)X
+2438(Incorporated.)X
+2909(1991.)X
+555 3088([MSLM91])N
+755 3192(Brian)N
+962(D.)X
+1068(Marsh,)X
+1321(Michael)X
+1612(L.)X
+1709(Scott,)X
+1921(Thomas)X
+2207(J.)X
+2286(LeBlanc)X
+2586(and)X
+2730(Evangelos)X
+3092(P.)X
+3184(Markatos.)X
+2 f F
+3555(First-Class)X
+3942(User-Level)X
+755 3296(Threads)N
+1 f F
+1017(.)X
+1083(Proceedings)X
+1501(of)X
+1593(the)X
+1716(13th)X
+1883(ACM)X
+2090(Symposium)X
+2496(on)X
+2601(Operating)X
+2947(Systems)X
+3238(Principles.)X
+3623(October)X
+3907(13-16)X
+4119(1991.)X
+755 3400(Paci\256c)N
+993(Grove,)X
+1234(California.)X
+1619(pp.)X
+1739(110-121.)X
+555 3532([MP88])N
+755 3636(Henry)N
+980(Massalin)X
+1293(and)X
+1433(Calton)X
+1670(Pu.)X
+2 f F
+1818(Fine-Grain)X
+2206(Scheduling)X
+1 f F
+2562(.)X
+2625(Technical)X
+2965(Report)X
+3206(CUCS-381-88,)X
+3711(Columbia)X
+4049(Univer-)X
+755 3740(sity,)N
+910(November)X
+1269(1988.)X
+555 3872([MP89])N
+755 3976(Henry)N
+983(Massalin)X
+1298(and)X
+1440(Calton)X
+1679(Pu.)X
+2 f F
+1829(Threads)X
+2117(and)X
+2263(Input/Output)X
+2702(in)X
+2790(the)X
+2914(Synthesis)X
+3238(Kernel)X
+1 f F
+3456(.)X
+3522(Proceedings)X
+3940(of)X
+4033(the)X
+4157(12th)X
+755 4080(ACM)N
+957(Symposium)X
+1358(on)X
+1458(Operating)X
+1799(Systems)X
+2085(Principles,)X
+2445(December)X
+2796(1989,)X
+2996(pp.)X
+3116(191-201.)X
+555 4212([Mot89])N
+2 f F
+755 4316(MC88100)N
+1095(RISC)X
+1284(Microprocessor)X
+1816(User's)X
+2050(Manual)X
+1 f F
+2299(,)X
+2339(Motorola)X
+2657(Corporation,)X
+3084(1989.)X
+555 4448([MVZ90])N
+755 4552(Cathy)N
+980(McCann,)X
+1310(Raj)X
+1455(Vaswani,)X
+1790(and)X
+1940(John)X
+2125(Zahorjan.)X
+2 f F
+2489(A)X
+2572(Dynamic)X
+2896(Processor)X
+3255(Allocation)X
+3622(Policy)X
+3861(for)X
+3988(Multipro-)X
+755 4656(grammed,)N
+1102(Shared)X
+1353(Memory)X
+1645(Multiprocessors)X
+1 f F
+2165(.)X
+2229(UWCSE)X
+2533(TR)X
+2659(90-03-02,)X
+2997(February)X
+3311(1991.)X
+3535(University)X
+3897(of)X
+3987(Washing-)X
+755 4760(ton.)N
+555 4892([Pin93])N
+755 4996(Brian)N
+953(Pinkerton.)X
+1324(Personal)X
+1620(communication,)X
+2158(February)X
+2468(1993.)X
+555 5128([PKB+91])N
+755 5232(Mike)N
+951(L.)X
+1047(Powell,)X
+1316(S.)X
+1407(R.)X
+1507(Kleiman,)X
+1830(S.)X
+1921(Barton,)X
+2186(D.)X
+2291(Shan,)X
+2498(D.)X
+2603(Sten,)X
+2792(M.)X
+2910(Weeks,)X
+2 f F
+3176(SunOS)X
+3421(Multi-Thread)X
+3878(Architecture)X
+1 f F
+4279(.)X
+755 5336(Appears)N
+1043(in)X
+2 f F
+1125(The)X
+1265(SPARC)X
+1525(Technical)X
+1861(Papers)X
+1 f F
+2088(,)X
+2128(Ben)X
+2277(J.)X
+2348(Catanzaro,)X
+2714(Editor.)X
+2974(Springer-Verlag,)X
+3536(1991.)X
+3756(pp.)X
+3876(229-372.)X
+555 5468([Pra86])N
+755 5572(Terence)N
+1062(W.)X
+1205(Pratt.)X
+2 f F
+1443(Programming)X
+1939(Language)X
+2306(Design)X
+2580(and)X
+2747(Implementation)X
+1 f F
+3250(.)X
+3336(May)X
+3529(1986.)X
+3775(Second)X
+4057(edition.)X
+755 5676(Prentice-Hall,)N
+1223(Englewood)X
+1608(Cliffs,)X
+1830(New)X
+2002(Jersey.)X
+
+%%Page: 27 27
+27 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(27)X
+2487(-)X
+555 680([Ros92])N
+755 784(O.)N
+853(Rose.)X
+1073(Personal)X
+1369(Communication,)X
+1924(April)X
+2113(1992.)X
+555 916([Seq88])N
+2 f F
+755 1020(Symmetry)N
+1092(Technical)X
+1428(Summary)X
+1 f F
+1731(,)X
+1771(Sequent)X
+2049(Computer)X
+2389(Systems,)X
+2695(Inc.,)X
+2858(1988.)X
+555 1152([Sit93])N
+755 1256(Richard)N
+1029(Sites.)X
+2 f F
+1244(Alpha)X
+1455(AXP)X
+1622(Architecture)X
+1 f F
+2023(.)X
+2083(Communications)X
+2649(of)X
+2736(the)X
+2854(ACM)X
+3056(\(CACM\))X
+3365(36\(2\),)X
+3579(1993.)X
+555 1388([SPA92])N
+755 1492(SPARC)N
+1050(International.)X
+2 f F
+1543(The)X
+1706(SPARC)X
+1989(Architecture)X
+2432(Manual)X
+1 f F
+2681(.)X
+2763(Prentice-Hall,)X
+3253(Englewood)X
+3660(Cliffs,)X
+3904(New)X
+4098(Jersey)X
+755 1596(07632.)N
+1015(ISBN)X
+1217(0-13-825001-4.)X
+555 1728([Sta92])N
+755 1832(Richard)N
+1029(M.)X
+1140(Stallman.)X
+2 f F
+1484(Using)X
+1695(and)X
+1835(Porting)X
+2099(GNU)X
+2288(CC)X
+1 f F
+2394(.)X
+2454(The)X
+2599(Free)X
+2762(Software)X
+3072(Foundation,)X
+3476(1992.)X
+555 1964([Sun88])N
+2 f F
+755 2068(SunOS)N
+993(Reference)X
+1335(Manual)X
+1 f F
+1584(,)X
+1624(Sun)X
+1768(Microsystems.)X
+2277(Part)X
+2426(Number)X
+2709(800-1751-10,)X
+3163(May)X
+3330(1988.)X
+555 2200([TSS88])N
+755 2304(Charles)N
+1021(M.)X
+1133(Thacker,)X
+1438(Lawrance)X
+1777(Stewart,)X
+2062(and)X
+2198(Edward)X
+2468(Satterthwaite,)X
+2931(Jr.)X
+2 f F
+3049(Fire\257y:)X
+3310(A)X
+3379(Multiprocessor)X
+3888(Workstation)X
+1 f F
+4279(.)X
+755 2408(IEEE)N
+949(Transactions)X
+1379(on)X
+1479(Computers,)X
+1870(37\(8\):909-920,)X
+2373(August)X
+2624(1988.)X
+555 2540([Tho68])N
+755 2644(Ken)N
+915(Thompson.)X
+2 f F
+1323(Regular)X
+1607(Expression)X
+1989(Search)X
+2238(Algorithm)X
+1 f F
+2562(.)X
+2628(Communications)X
+3200(of)X
+3293(the)X
+3417(Association)X
+3821(for)X
+3940(Computing)X
+755 2748(Machinery)N
+1123(\(CACM\),)X
+1452(11\(6\):419-422,)X
+1955(June)X
+2122(1968.)X
+3 f F
+555 2956(Appendix)N
+907(A)X
+1045(Variant)X
+1332(Argument)X
+1704(Lists)X
+1 f F
+755 3088(Thread)N
+1009(creation)X
+1294(functions)X
+1618(that)X
+1764(accept)X
+1996(variant)X
+2245(argument)X
+2573(lists)X
+2726(are)X
+2850(slower)X
+3089(and)X
+3230(less)X
+3375(portable)X
+3663(than)X
+3826(those)X
+4020(that)X
+4165(take)X
+555 3192(\256xed)N
+736(argument)X
+1060(lists.)X
+1249(They)X
+1435(are)X
+1555(slower)X
+1790(because)X
+2066(the)X
+2185(argument)X
+2509(list)X
+2626(must)X
+2801(be)X
+2897(copied)X
+3131(and)X
+3267(the)X
+3385(size)X
+3530(is)X
+3603(not)X
+3725(known)X
+3963(at)X
+4041(compile)X
+555 3296(time;)N
+740(if)X
+810(the)X
+929(same)X
+1114(arguments)X
+1468(are)X
+1587(passed)X
+1821(in)X
+1903(a)X
+1959(structure,)X
+2280(the)X
+2398(compiler)X
+2703(can)X
+2835(produce)X
+3114(optimized)X
+3454(code)X
+3626(for)X
+3740(the)X
+3858(job.)X
+4020(The)X
+4165(por-)X
+555 3400(tability)N
+807(problems)X
+1131(come)X
+1331(from)X
+1513(a)X
+1575(number)X
+1846(of)X
+1938(places)X
+2164(and,)X
+2325(unfortunately,)X
+2802(cause)X
+3006(reliability)X
+3342(problems,)X
+3685(not)X
+3812(just)X
+3952(worse)X
+4169(per-)X
+555 3504(formance.)N
+755 3636(Some)N
+969(C)X
+1054(libraries)X
+1349(provide)X
+1626(a)X
+1694(function,)X
+7 f F
+2013(nargs)X
+1 f F
+(,)S
+2305(that)X
+2457(returns)X
+2711(the)X
+2840(number)X
+3116(of)X
+3214(words)X
+3441(of)X
+3539(arguments.)X
+3944(In)X
+4042(general,)X
+555 3740(however,)N
+875(it)X
+942(is)X
+1017(impossible)X
+1385(to)X
+1469(implement)X
+7 f F
+1833(nargs)X
+1 f F
+2095(without)X
+2361(special)X
+2606(support.)X
+2908(On)X
+3028(the)X
+3148(VAX,)X
+3364(arguments)X
+3720(are)X
+3841(popped)X
+4099(by)X
+4201(the)X
+555 3844(callee,)N
+785(so)X
+878(the)X
+998(number)X
+1265(of)X
+1354(words)X
+1572(must)X
+1749(be)X
+1847(passed)X
+2083(to)X
+2166(the)X
+2285(callee,)X
+2514(and,)X
+2671(is)X
+2745(available)X
+3056(for)X
+3171(use)X
+3299(by)X
+7 f F
+3400(nargs)X
+1 f F
+(.)S
+3701(The)X
+3847(Sequent)X
+4126(Sym-)X
+555 3948(metry)N
+766(also)X
+919(provides)X
+7 f F
+1219(nargs)X
+1 f F
+(,)S
+1503(but)X
+1629(relies)X
+1827(on)X
+1931(the)X
+2053(caller)X
+2256(to)X
+2341(pop)X
+2484(arguments)X
+2841(from)X
+3020(the)X
+3141(stack)X
+3329(immediately)X
+3752(after)X
+3923(the)X
+4044(call)X
+4183(and)X
+555 4052(in)N
+641(certain)X
+884(stylized)X
+1157(ways.)X
+1386(Today,)X
+1635(it)X
+1703(is)X
+1780(more)X
+1969(common)X
+2273(for)X
+2391(the)X
+2513(caller)X
+2716(to)X
+2802(allocate)X
+3076(and)X
+3216(free)X
+3366(argument)X
+3693(space)X
+3896(at)X
+3977(procedure)X
+555 4156(entry,)N
+764(though)X
+1010(some)X
+1203(optimizing)X
+1573(compilers)X
+1913(have)X
+2089(\257ags)X
+2263(to)X
+2348(force)X
+2537(argument)X
+2863(popping)X
+3148(immediately)X
+3571(after)X
+3742(procedure)X
+4087(return.)X
+555 4260(For)N
+691(example,)X
+1008(programs)X
+1336(compiled)X
+1659(with)X
+1826(GNU)X
+2025(CC)X
+2156([Sta92])X
+2417(can)X
+2553(use)X
+2684(the)X
+7 f F
+2806(-fno-defer-pop)X
+1 f F
+3502(compiler)X
+3811(\257ag.)X
+3995(The)X
+4144(KSR)X
+555 4364(implements)N
+7 f F
+962(nargs)X
+1 f F
+1235(with)X
+1410(a)X
+1479(callback)X
+1780(from)X
+1969(the)X
+2100(callee)X
+2321(to)X
+2416(a)X
+2485(code)X
+2670(fragment)X
+2993(in)X
+3088(the)X
+3219(caller)X
+3431(and)X
+3580(the)X
+3711(caller)X
+3923(embeds)X
+4201(the)X
+7 f F
+555 4468(nargs)N
+1 f F
+822(value)X
+1023(in)X
+1112(an)X
+1215(instruction)X
+1584(immediate)X
+1949([KSR91].)X
+2304(In)X
+2397(a)X
+2459(threads)X
+2717(package,)X
+3027(the)X
+3151(caller)X
+3356(is)X
+3435(the)X
+3559(thread)X
+3786(startup)X
+4030(code,)X
+4228(so)X
+555 4572(that)N
+699(code)X
+875(must)X
+1054(contain)X
+1314(the)X
+1436(needed)X
+1688(code)X
+1864(fragment.)X
+2218(Thus,)X
+2422(a)X
+2481(threads)X
+2736(package)X
+3023(implementation)X
+3548(of)X
+7 f F
+3638(nargs)X
+1 f F
+3901(requires)X
+4183(one)X
+555 4676(startup)N
+806(routine)X
+1066(for)X
+1193(each)X
+1374(possible)X
+7 f F
+1669(nargs)X
+1 f F
+1942(value)X
+2149(or)X
+2248(dynamic)X
+2556(compilation)X
+2970(to)X
+3064(create)X
+3289(the)X
+3419(needed)X
+3679(startup)X
+3929(routines)X
+4219(on)X
+555 4780(demand.)N
+755 4912(Some)N
+973(thread)X
+1210(libraries)X
+1509(have)X
+1696(thread)X
+1932(creation)X
+2226(routines)X
+2519(that)X
+2674(require)X
+2937(the)X
+3070(user)X
+3239(to)X
+3336(pass)X
+3509(an)X
+3620(argument)X
+3958(that)X
+4113(is)X
+4201(the)X
+555 5016(number)N
+825(of)X
+917(words)X
+1138(of)X
+1230(arguments)X
+1589(that)X
+1734(should)X
+1972(be)X
+2073(passed)X
+2312(to)X
+2398(the)X
+2520(thread.)X
+2785(The)X
+2934(\256rst)X
+3082(problem)X
+3373(is)X
+3450(solved,)X
+3703(because)X
+7 f F
+3982(nargs)X
+1 f F
+4246(is)X
+555 5120(not)N
+679(needed.)X
+969(However,)X
+1306(the)X
+1426(argument)X
+1751(list)X
+1870(may)X
+2030(be)X
+2128(larger)X
+2338(than)X
+2498(the)X
+2618(sum)X
+2773(of)X
+2862(the)X
+2982(sizes)X
+3160(of)X
+3249(the)X
+3369(arguments,)X
+3745(so)X
+3838(the)X
+3958(user)X
+4113(of)X
+4201(the)X
+555 5224(thread)N
+784(library)X
+1026(must)X
+1209(know)X
+1415(the)X
+1541(details)X
+1778(of)X
+1873(the)X
+1999(calling)X
+2245(convention,)X
+2648(which)X
+2871(varies)X
+3090(from)X
+3273(machine)X
+3572(to)X
+3661(machine)X
+3960(and)X
+4103(some-)X
+555 5328(times)N
+748(from)X
+924(compiler)X
+1229(to)X
+1311(compiler.)X
+755 5460(The)N
+902(SunOS)X
+7 f F
+1150(lwp)X
+1 f F
+1316(package)X
+1602(simpli\256es)X
+1934(matters)X
+2192(by)X
+2294(allowing)X
+2596(only)X
+2760(integer)X
+3005(and)X
+3143(pointer)X
+3392(arguments)X
+3748(and)X
+3886(requiring)X
+4201(the)X
+555 5564(end)N
+695(user)X
+853(to)X
+939(pass)X
+1100(in)X
+1185(the)X
+1306(number)X
+1574(of)X
+1664(such)X
+1834(arguments)X
+2191([Sun88,)X
+2465(PKB+91].)X
+2835(However,)X
+3173(problems)X
+3494(can)X
+3629(still)X
+3771(arise)X
+3946(with)X
+4111(archi-)X
+555 5668(tectures)N
+825(where)X
+1042(pointers)X
+1320(and)X
+1456(integers)X
+1730(are)X
+1849(different)X
+2146(sizes)X
+2322(\(e.g.,)X
+2505(DEC)X
+2685(AXP)X
+2865([Sit93])X
+3107(and)X
+3243(KSR1)X
+3458([KSR91]\).)X
+
+%%Page: 28 28
+28 p
+10 s 0 xH 0 xS 1 f F
+2340 392(-)N
+2387(28)X
+2487(-)X
+755 680(Varargs)N
+1035(functions)X
+1358(and)X
+1499(\256xed-argument)X
+2014(functions)X
+2337(may)X
+2499(use)X
+2630(different)X
+2931(calling)X
+3173(conventions.)X
+3624(Thus,)X
+3828(a)X
+3888(function)X
+4179(that)X
+555 784(gets)N
+716(passed)X
+962(parameters)X
+1347(with)X
+1521(varargs)X
+1790(is)X
+1875(only)X
+2049(supposed)X
+2379(to)X
+2473(access)X
+2711(them)X
+2903(with)X
+3077(varargs.)X
+3386(Thus,)X
+3597(calling)X
+7 f F
+3846(printf)X
+1 f F
+4165(as)X
+4263(a)X
+555 888(thread)N
+779(routine)X
+1029(is)X
+1105(safe)X
+1258(because)X
+7 f F
+1536(printf)X
+1 f F
+1847(is)X
+1923(a)X
+1982(varargs)X
+2242(function.)X
+2572(Using)X
+7 f F
+2786(puts)X
+1 f F
+3001(as)X
+3091(a)X
+3149(thread)X
+3372(routine,)X
+3641(however,)X
+3960(may)X
+4120(break)X
+555 992(since)N
+7 f F
+748(puts)X
+1 f F
+968(does)X
+1143(not)X
+1273(access)X
+1507(its)X
+1610(arguments)X
+1972(with)X
+2142(varargs.)X
+2446(Although)X
+2775(the)X
+2900(differences)X
+3285(are)X
+3411(rarely)X
+3626(important)X
+3964(on)X
+4071(current)X
+555 1096(systems,)N
+848(future)X
+1060(compilers)X
+1396(that)X
+1536(perform)X
+1815(better)X
+2018(optimization)X
+2442(may)X
+2600(be)X
+2696(incompatible)X
+3134(with)X
+3296(mixed)X
+3516(use.)X
+755 1228(Alignment)N
+1126(restrictions)X
+1511(may)X
+1678(make)X
+1881(it)X
+1954(impossible)X
+2329(to)X
+2420(use)X
+2556(varargs)X
+2822(reliably.)X
+3136(The)X
+3290(Motorola)X
+3616(88000)X
+3844(family)X
+4081(calling)X
+555 1332(convention)N
+936(double-aligns)X
+1396(the)X
+1518(argument)X
+1845(area)X
+2004(and)X
+2144(all)X
+2248(double-sized)X
+2682(parameters.)X
+3099(For)X
+3234(varargs)X
+3495(under)X
+3702(QuickThreads,)X
+4201(the)X
+555 1436(argument)N
+898(list)X
+1035(is)X
+1128(copied)X
+1382(from)X
+1578(the)X
+1716(caller's)X
+1993(stack)X
+2198(to)X
+2300(the)X
+2438(callee's)X
+2724(stack.)X
+2969(In)X
+3076(general,)X
+3373(the)X
+3510(client)X
+3727(routine)X
+3993(that)X
+4152(calls)X
+7 f F
+555 1540(QT_VARGS)N
+1 f F
+961(has)X
+1090(both)X
+1254(varargs)X
+1513(parameters)X
+1888(to)X
+1972(pass)X
+2132(to)X
+2216(the)X
+2336(user's)X
+2550(routine,)X
+2819(and)X
+2957(non-varargs)X
+3363(parameters,)X
+3758(such)X
+3927(as)X
+4015(a)X
+4072(pointer)X
+555 1644(the)N
+679(user)X
+838(routine)X
+1090(to)X
+1177(call)X
+1318(on)X
+1423(thread)X
+1649(startup.)X
+1932(The)X
+2082(non-varargs)X
+2491(parameters)X
+2869(are)X
+2993(stripped)X
+3276(\(do)X
+3408(not)X
+3535(get)X
+3658(passed)X
+3897(to)X
+3984(the)X
+4107(user's)X
+555 1748(routines\))N
+873(which)X
+1102(shifts)X
+1308(the)X
+1439(varargs)X
+1709(alignment.)X
+2102(The)X
+2260(number)X
+2537(of)X
+2636(words)X
+2864(of)X
+2963(shifting)X
+3239(depends)X
+3534(on)X
+3646(the)X
+3776(number)X
+4053(of)X
+4152(non-)X
+555 1852(varargs)N
+814(arguments)X
+1170(that)X
+1312(are)X
+1433(passed)X
+1669(to)X
+1753(the)X
+1873(routine)X
+2122(that)X
+2264(calls)X
+7 f F
+2433(va_start)X
+1 f F
+(.)S
+2878(If)X
+2953(there)X
+3135(are)X
+3255(an)X
+3352(odd)X
+3493(number)X
+3759(of)X
+3847(words)X
+4064(of)X
+4152(non-)X
+555 1956(varargs)N
+814(parameters,)X
+1208(the)X
+1327(varargs)X
+1585(argument)X
+1909(list)X
+2027(is)X
+2101(shifted)X
+2340(by)X
+2441(an)X
+2538(odd)X
+2679(number)X
+2945(of)X
+3033(words,)X
+3270(leaving)X
+3527(it)X
+3592(unaligned)X
+3929(in)X
+4012(memory.)X
+555 2060(The)N
+704(threads)X
+960(package)X
+1248(lacks)X
+1437(suf\256cient)X
+1759(type)X
+1921(information)X
+2323(to)X
+2409(realign)X
+2656(the)X
+2778(parameters)X
+3155(when)X
+3353(they)X
+3515(are)X
+3638(shifted.)X
+3919(The)X
+4067(threads)X
+555 2164(package)N
+842(likewise)X
+1132(lacks)X
+1320(control)X
+1570(over)X
+1736(the)X
+1856(user)X
+2012(routine's)X
+2319(use)X
+2448(of)X
+2537(varargs)X
+2796(in)X
+2880(the)X
+3000(callee,)X
+3230(so)X
+3323(it)X
+3389(is)X
+3464(not)X
+3588(possible)X
+3872(to)X
+3956(realign)X
+4201(the)X
+555 2268(parameters)N
+928(when)X
+1122(they)X
+1280(are)X
+1399(used.)X
+3 f F
+555 2476(Appendix)N
+907(B)X
+1040(Restarting)X
+1421(A)X
+1499(Thread)X
+1 f F
+755 2608(In)N
+843(some)X
+1033(circumstances)X
+1509(it)X
+1574(is)X
+1648(useful)X
+1865(to)X
+1948(block)X
+2147(a)X
+2204(thread)X
+2426(tentatively,)X
+2805(then)X
+2964(restart)X
+3186(it)X
+3251(if)X
+3321(conditions)X
+3674(have)X
+3846(changed.)X
+4174(The)X
+555 2712(basic)N
+749(idea)X
+912(is)X
+994(to)X
+1085(test)X
+1225(a)X
+1290(condition;)X
+1643(if)X
+1721(the)X
+1847(condition)X
+2177(is)X
+2258(true,)X
+2431(select)X
+2642(a)X
+2706(next)X
+2872(thread)X
+3101(and)X
+3245(block)X
+3451(the)X
+3577(old)X
+3707(thread.)X
+3976(In)X
+4071(the)X
+4197(old)X
+555 2816(thread's)N
+838(helper,)X
+1083(retest)X
+1281(the)X
+1402(condition:)X
+1749(if)X
+1821(it)X
+1888(is)X
+1964(still)X
+2106(true,)X
+2274(\256nish)X
+2474(blocking)X
+2777(the)X
+2898(thread.)X
+3162(But)X
+3300(if)X
+3372(the)X
+3493(condition)X
+3818(has)X
+3948(gone)X
+4127(false,)X
+555 2920(the)N
+673(old)X
+795(thread)X
+1016(is)X
+1089(restarted)X
+1386(and)X
+1522(what)X
+1698(was)X
+1843(to)X
+1925(have)X
+2097(been)X
+2269(the)X
+2387(next)X
+2545(thread)X
+2766(is)X
+2839(returned)X
+3127(to)X
+3209(the)X
+3327(runable)X
+3588(queue.)X
+755 3052(In)N
+858(Figure)X
+1102(10a,)X
+1273(the)X
+1406(routine)X
+7 f F
+1668(tentative_block)X
+1 f F
+2423(suspends)X
+2747(the)X
+2880(current)X
+3143(thread)X
+3379(and)X
+3530(runs)X
+3703(the)X
+3836(helper)X
+4072(routine)X
+7 f F
+555 3156(tentative_help1)N
+1 f F
+1299(on)X
+1403(the)X
+1525(stack)X
+1714(of)X
+1805(a)X
+1865(new)X
+2023(thread.)X
+2288(Three)X
+2500(arguments)X
+2858(are)X
+2981(passed)X
+3219(to)X
+3304(the)X
+3425(helper:)X
+3671(the)X
+3792(thread)X
+4016(to)X
+4101(block,)X
+555 3260(the)N
+682(queue)X
+903(to)X
+994(block)X
+1201(on,)X
+1330(and)X
+1475(the)X
+1602(next)X
+1769(thread)X
+1999(\(which)X
+2251(might)X
+2466(be)X
+2570(returned)X
+2866(to)X
+2956(the)X
+3082(runable)X
+3351(queue\).)X
+3638(Since)X
+3844(QuickThreads)X
+555 3364(passes)N
+783(only)X
+948(two)X
+1091(arguments,)X
+1468(three)X
+1651(arguments)X
+2007(are)X
+2128(passed)X
+2364(by)X
+2466(passing)X
+2728(the)X
+2848(helper)X
+3071(a)X
+3129(pointer)X
+3378(to)X
+3462(a)X
+3520(structure)X
+3823(with)X
+3987(two)X
+4129(argu-)X
+555 3468(ments.)N
+8 s 7 f F
+843 3604(tentative_block\(\))N
+843 3692({)N
+919 3780(arg_t)N
+1147(self;)X
+919 3956(next)N
+1109(=)X
+1185(qget)X
+1375(\(&runableq\);)X
+919 4044(self.thread)N
+1375(=)X
+1451(global_curr_runni)X
+2097(ng;)X
+919 4132(self.blockon)N
+1413(=)X
+1489(&runableq;)X
+919 4220(QT_BLOCK)N
+1261(\(tentative_help1,)X
+1945(&self,)X
+2211(next,)X
+2439(next->sp\);)X
+919 4308(/*)N
+1033(Woke)X
+1223(up)X
+1337(again.)X
+1603(*/)X
+843 4396(})N
+9 s 3 f F
+1933 4548(Figure)N
+2155(10a.)X
+1 f F
+2317(Blocking)X
+2599(tentatively.)X
+10 s F
+755 4784(Figure)N
+989(10b)X
+1134(shows)X
+1359(a)X
+1420(helper)X
+1646(function)X
+1938(that)X
+2083(tests)X
+2250(a)X
+2311(condition,)X
+2658(and,)X
+2819(if)X
+2893(true,)X
+3062(\256nishes)X
+3330(blocking)X
+3634(the)X
+3756(old)X
+3882(thread.)X
+4147(\(The)X
+555 4888(test)N
+691(and)X
+832(block)X
+1035(must)X
+1215(be)X
+1316(atomic;)X
+1581(for)X
+1700(clarity,)X
+1950(synchronization)X
+2487(operations)X
+2846(are)X
+2970(omitted.\))X
+3306(If)X
+3385(the)X
+3508(condition)X
+3835(is)X
+3913(false,)X
+4110(it)X
+4178(res-)X
+555 4992(tarts)N
+713(the)X
+831(old)X
+953(thread)X
+1174(by)X
+1274(calling)X
+1512(another)X
+1773(helper)X
+1994(function)X
+2281(on)X
+2381(the)X
+2499(old)X
+2621(thread's)X
+2900(stack.)X
+755 5124(Figure)N
+991(10c)X
+1134(shows)X
+1361(a)X
+1424(second)X
+1674(helper)X
+1902(function)X
+2196(that)X
+2343(puts)X
+2503(the)X
+2628(next)X
+2793(thread)X
+3021(back)X
+3199(on)X
+3305(the)X
+3429(runable)X
+3696(queue)X
+3914(and)X
+4056(returns.)X
+555 5228(Although)N
+879(the)X
+999(next)X
+1159(thread's)X
+1440(stack)X
+1627(was)X
+1774(used,)X
+1963(the)X
+2083(next)X
+2243(thread)X
+2466(was)X
+2613(never)X
+2814(actually)X
+3090(run.)X
+3259(Thus,)X
+3461(it)X
+3527(can)X
+3660(be)X
+3757(re-queued)X
+4100(on)X
+4201(the)X
+555 5332(runable)N
+817(queue)X
+1030(and)X
+1167(it)X
+1231(will)X
+1375(be)X
+1471(ready)X
+1670(to)X
+1752(run,)X
+1899(just)X
+2034(as)X
+2121(it)X
+2185(was)X
+2330(when)X
+2524(it)X
+2588(was)X
+2733(pulled)X
+2953(from)X
+3129(the)X
+3247(queue)X
+3459(by)X
+7 f F
+3559(tentative_block)X
+1 f F
+(.)S
+555 5436(Note)N
+733(that)X
+875(the)X
+995(next)X
+1155(thread's)X
+1436(original)X
+1707(stack)X
+1894(pointer)X
+2143(\(that)X
+2312(used)X
+2480(by)X
+7 f F
+2581(tentative_block)X
+1 f F
+(\))S
+3349(is)X
+3423(used,)X
+3611(and)X
+3748(not)X
+3871(the)X
+3990(\(garbage\))X
+555 5540(value)N
+749(that)X
+889(results)X
+1118(from)X
+1294(calling)X
+1532(a)X
+1588(blocking)X
+1888(routine)X
+2135(in)X
+2217(the)X
+2335(helper)X
+2556(function.)X
+8 s F
+2843 5500(10)N
+9 f F
+555 5620 MXY
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+(ru)137 500 oc
+1 f F
+555 5720(10.)N
+651(Note)X
+794(to)X
+863(QuickThreads)X
+1243(implementors:)X
+7 f F
+1632(QT_ABORT)X
+1 f F
+1955(may)X
+2083(walk)X
+2225(the)X
+2321(call)X
+2431(chain.)X
+2619(The)X
+2736(implementation)X
+3156(must)X
+3299(arrange)X
+3507(that)X
+3621(walks)X
+3788(started)X
+3976(in)X
+4044(helpers)X
+4246(or)X
+651 5792(their)N
+784(descendants)X
+1108(will)X
+1224(walk)X
+1364(only)X
+1494(the)X
+1588(helper)X
+1763(function's)X
+2038(call)X
+2146(chain,)X
+2316(and)X
+2424(not)X
+2522(that)X
+2634(of)X
+2703(the)X
+2797(whole)X
+2969(stack.)X
+
+%%Page: 29 29
+29 p
+8 s 0 xH 0 xS 1 f F
+10 s F
+2340 392(-)N
+2387(29)X
+2487(-)X
+8 s 7 f F
+843 712(tentative_help1)N
+1451(\(oldsp,)X
+1755(oldself,)X
+2097(next\))X
+843 800({)N
+919 888(if)N
+1033(\(condition\))X
+1489({)X
+995 976(oldself->thread->)N
+1641(sp)X
+1755(=)X
+1831(oldsp;)X
+995 1064(qput)N
+1185(\(oldself->blockon)X
+1831(,)X
+1907(oldself->thread\);)X
+919 1152(})N
+995(else)X
+1185({)X
+995 1240(QT_ABORT)N
+1337(\(tentative_help2,)X
+2021(NULL,)X
+2249(next,)X
+2477(oldsp\);)X
+919 1328(})N
+843 1416(})N
+9 s 3 f F
+1609 1568(Figure)N
+1831(10b.)X
+1 f F
+1997(A)X
+2067(helper)X
+2265(to)X
+2339(either)X
+2521(\256nish)X
+2699(blocking)X
+2969(or)X
+3047(restart.)X
+8 s 7 f F
+843 1808(tentative_help2)N
+1451(\(unused1,)X
+1831(unused2,)X
+2173(next\))X
+843 1896({)N
+919 1984(qput)N
+1109(\(&runableq,)X
+1565(next\);)X
+843 2072(})N
+9 s 3 f F
+1545 2224(Figure)N
+1767(10c.)X
+1 f F
+1925(A)X
+1995(helper)X
+2193(called)X
+2383(from)X
+2541(a)X
+2591(helper)X
+2789(to)X
+2863(restart)X
+3061(a)X
+3111(thread.)X
+10 s F
+755 2432(The)N
+908(second)X
+1159(helper)X
+1388(returns)X
+1639(the)X
+1765(new)X
+1927(thread)X
+2156(to)X
+2246(the)X
+2372(runable)X
+2641(queue.)X
+2901(When)X
+3121(the)X
+3247(second)X
+3498(helper)X
+3726(returns,)X
+3996(it)X
+4067(restarts)X
+7 f F
+555 2536(tentative_block)N
+1 f F
+1295(and)X
+1431(allows)X
+1660(the)X
+1778(old)X
+1900(thread)X
+2121(to)X
+2203(continue)X
+2499(runing.)X
+
+%%Trailer
+xt
+
+xs
diff --git a/src/QuickThreads/md/axp.README b/src/QuickThreads/md/axp.README
new file mode 100644 (file)
index 0000000..b6a705c
--- /dev/null
@@ -0,0 +1,10 @@
+The handling of varargs is platform-dependent.  Assar Westerlund
+stared at the problem for a while and deduces the following table:
+
+vers / compiler         cc              gcc
+----------------------------------------------------------------------
+1.3                     a0, offset      __base, __offset
+2.0                     _a0, _offset    __base, __offset
+
+The current code should handle both cc and gcc versions, provided
+you configure for the correct compiler.
diff --git a/src/QuickThreads/md/axp.h b/src/QuickThreads/md/axp.h
new file mode 100644 (file)
index 0000000..ff951a0
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QT_AXP_H
+#define QT_AXP_H
+
+#define QT_GROW_DOWN
+
+typedef unsigned long qt_word_t;
+
+
+/* Stack layout on the Alpha:
+
+   Integer:
+
+     Caller-save: r0..r8, r22..r25, r27..r29
+     argument/caller-save: r16..r21
+     callee-save: r9..r15
+     return pc *callee-save*: r26
+     stack pointer: r30
+     zero: r31
+
+   Floating-point:
+
+     Caller-save: f0..f1, f10..f15
+     argument/caller-save: f16..f21, f22..f30
+     callee-save: f2..f9
+     zero: f31
+
+   Non-varargs:
+
+   +---
+   | padding
+   | f9
+   | f8
+   | f7
+   | f6
+   | f5
+   | f4
+   | f3
+   | f2
+   | r26
+   +---
+   | padding
+   | r29
+   | r15
+   | r14
+   | r13
+   | r12       on startup === `only'
+   | r11       on startup === `userf'
+   | r10       on startup === `qt'
+   | r9                on startup === `qu'
+   | r26       on startup === qt_start         <--- qt.sp
+   +---
+
+   Conventions for varargs startup:
+
+   |  :
+   | arg6
+   | iarg5
+   |  :
+   | iarg0
+   | farg5
+   |  :
+   | farg0
+   +---
+   | padding
+   | r29
+   | r15
+   | r14
+   | r13
+   | r12       on startup === `startup'
+   | r11       on startup === `vuserf'
+   | r10       on startup === `cleanup'
+   | r9                on startup === `qt'
+   | r26       on startup === qt_vstart        <--- qt.sp
+   +---
+
+   Note: this is a pretty cheap/sleazy way to get things going,
+   but ``there must be a better way.''  For instance, some varargs
+   parameters could be loaded in to integer registers, or the return
+   address could be stored on top of the stack. */
+
+
+/* Stack must be 16-byte aligned. */
+#define QT_STKALIGN    (16)
+
+/* How much space is allocated to hold all the crud for
+   initialization: 7 registers times 8 bytes/register. */
+
+#define QT_STKBASE     (10 * 8)
+#define QT_VSTKBASE    QT_STKBASE
+
+
+/* Offsets of various registers. */
+#define QT_R26 0
+#define QT_R9  1
+#define QT_R10 2
+#define QT_R11 3
+#define QT_R12 4
+
+
+/* When a never-before-run thread is restored, the return pc points
+   to a fragment of code that starts the thread running.  For
+   non-vargs functions, it just calls the client's `only' function.
+   For varargs functions, it calls the startup, user, and cleanup
+   functions.
+
+   The varargs startup routine always reads 12 8-byte arguments from
+   the stack.  If fewer argumets were pushed, the startup routine
+   would read off the top of the stack.  To prevent errors we always
+   allocate enough space.  When there are fewer args, the preallocated
+   words are simply wasted. */
+
+extern void qt_start(void);
+#define QT_ARGS_MD(sp) (QT_SPUT (sp, QT_R26, qt_start))
+
+
+/* The AXP uses a struct for `va_list', so pass a pointer to the
+   struct.  This may break some uses of `QT_VARGS', but then we never
+   claimed it was totally portable. */
+
+typedef void (qt_function_t)(void);
+
+struct qt_t;
+struct va_list;
+extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
+                             struct va_list *vargs, void *pt,
+                             qt_function_t *startup,
+                             qt_function_t *vuserf,
+                             qt_function_t *cleanup);
+
+#define QT_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
+  (qt_vargs (sp, nbytes, (struct va_list *)(&(vargs)), pt, \
+            (qt_function_t *) startup, (qt_function_t *)vuserf, \
+            (qt_function_t *)cleanup));
+
+
+/* The *index* (positive offset) of where to put each value. */
+#define QT_ONLY_INDEX  (QT_R12)
+#define QT_USER_INDEX  (QT_R11)
+#define QT_ARGT_INDEX  (QT_R10)
+#define QT_ARGU_INDEX  (QT_R9)
+
+#define QT_VCLEANUP_INDEX      (QT_R10)
+#define QT_VUSERF_INDEX                (QT_R11)
+#define QT_VSTARTUP_INDEX      (QT_R12)
+#define QT_VARGT_INDEX         (QT_R9)
+
+#endif /* ndef QT_AXP_H */
diff --git a/src/QuickThreads/md/axp.s b/src/QuickThreads/md/axp.s
new file mode 100644 (file)
index 0000000..a84aab2
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/* axp.s -- assembly support. */
+
+       .text
+       .align 4
+       .file 2 "axp.s"
+
+       .globl qt_block
+       .globl qt_blocki
+       .globl qt_abort
+       .globl qt_start
+       .globl qt_vstart
+
+       /*
+       ** $16: ptr to function to call once curr is suspended
+       **      and control is on r19's stack.
+       ** $17: 1'th arg to (*$16)(...).
+       ** $18: 2'th arg to (*$16)(...).
+       ** $19: sp of thread to resume.
+       **
+       ** The helper routine returns a value that is passed on as the
+       ** return value from the blocking routine.  Since we don't
+       ** touch r0 between the helper's return and the end of
+       ** function, we get this behavior for free.
+       */
+
+       .ent qt_blocki
+qt_blocki:
+       subq $30,80, $30        /* Allocate save area. */
+       stq $26, 0($30)         /* Save registers. */
+       stq  $9, 8($30)
+       stq $10,16($30)
+       stq $11,24($30)
+       stq $12,32($30)
+       stq $13,40($30)
+       stq $14,48($30)
+       stq $15,56($30)
+       stq $29,64($30)
+       .end qt_blocki
+       .ent qt_abort
+qt_abort:
+       addq $16,$31, $27       /* Put argument function in PV. */
+       addq $30,$31, $16       /* Save stack ptr in outgoing arg. */
+       addq $19,$31, $30       /* Set new stack pointer. */
+       jsr $26,($27),0         /* Call helper function. */
+
+       ldq $26, 0($30)         /* Restore registers. */
+       ldq  $9, 8($30)
+       ldq $10,16($30)
+       ldq $11,24($30)
+       ldq $12,32($30)
+       ldq $13,40($30)
+       ldq $14,48($30)
+       ldq $15,56($30)
+       ldq $29,64($30)
+
+       addq $30,80, $30        /* Deallocate save area. */
+       ret $31,($26),1         /* Return, predict===RET. */
+       .end qt_abort
+
+
+       /*
+       ** Non-varargs thread startup.
+       */
+       .ent qt_start
+qt_start:
+       addq $9,$31,  $16       /* Load up `qu'. */
+       addq $10,$31, $17       /* ... user function's `pt'. */
+       addq $11,$31, $18       /* ... user function's `userf'. */
+       addq $12,$31, $27       /* ... set procedure value to `only'. */
+       jsr $26,($27),0         /* Call `only'. */
+
+       jsr $26,qt_error        /* `only' erroniously returned. */
+       .end qt_start
+
+
+       .ent qt_vstart:
+qt_vstart:
+       /* Call startup function. */
+       addq $9,$31, $16        /* Arg0 to `startup'. */
+       addq $12,$31, $27       /* Set procedure value. */
+       jsr $26,($27),0         /* Call `startup'. */
+
+       /* Call user function. */
+       ldt $f16, 0($30)        /* Load fp arg regs. */
+       ldt $f17, 8($30)
+       ldt $f18,16($30)
+       ldt $f19,24($30)
+       ldt $f20,32($30)
+       ldt $f21,40($30)
+       ldq $16,48($30)         /* And integer arg regs. */
+       ldq $17,56($30)
+       ldq $18,64($30)
+       ldq $19,72($30)
+       ldq $20,80($30)
+       ldq $21,88($30)
+       addq $30,96 $30         /* Pop 6*2*8 saved arg regs. */
+       addq $11,$31, $27       /* Set procedure value. */
+       jsr $26,($27),0         /* Call `vuserf'. */
+
+       /* Call cleanup. */
+       addq $9,$31, $16        /* Arg0 to `cleanup'. */
+       addq $0,$31, $17        /* Users's return value is arg1. */
+       addq $10,$31, $27       /* Set procedure value. */
+       jsr $26,($27),0         /* Call `cleanup'. */
+
+       jsr $26,qt_error        /* Cleanup erroniously returned. */
+       .end qt_start
+
+
+       /*
+       ** Save calle-save floating-point regs $f2..$f9.
+       ** Also save return pc from whomever called us.
+       **
+       ** Return value from `qt_block' is the same as the return from
+       ** `qt_blocki'.  We get that for free since we don't touch $0
+       ** between the return from `qt_blocki' and the return from
+       ** `qt_block'.
+       */
+       .ent qt_block
+qt_block:
+       subq $30,80, $30        /* Allocate a save space. */
+       stq $26, 0($30)         /* Save registers. */
+       stt $f2, 8($30)
+       stt $f3,16($30)
+       stt $f4,24($30)
+       stt $f5,32($30)
+       stt $f6,40($30)
+       stt $f7,48($30)
+       stt $f8,56($30)
+       stt $f9,64($30)
+
+       jsr $26,qt_blocki       /* Call helper. */
+                               /* .. who will also restore $gp. */
+
+       ldq $26, 0($30)         /* restore registers. */
+       ldt $f2, 8($30)
+       ldt $f3,16($30)
+       ldt $f4,24($30)
+       ldt $f5,32($30)
+       ldt $f6,40($30)
+       ldt $f7,48($30)
+       ldt $f8,56($30)
+       ldt $f9,64($30)
+
+       addq $30,80, $30        /* Deallcate save space. */
+       ret $31,($26),1         /* Return, predict===RET. */
+       .end qt_block
diff --git a/src/QuickThreads/md/axp_b.s b/src/QuickThreads/md/axp_b.s
new file mode 100644 (file)
index 0000000..60be726
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+       .text
+       .globl b_call_reg
+       .globl b_call_imm
+       .globl b_add
+       .globl b_load
+
+       .ent b_null
+b_null:
+       ret $31,($18),1
+       .end b_null
+
+       .ent b_call_reg
+b_call_reg:
+       lda $27,b_null
+$L0:
+       jsr $18,($27)
+       jsr $18,($27)
+       jsr $18,($27)
+       jsr $18,($27)
+       jsr $18,($27)
+
+       jsr $18,($27)
+       jsr $18,($27)
+       jsr $18,($27)
+       jsr $18,($27)
+       jsr $18,($27)
+
+       subq $16,1,$16
+       bgt $16,$L0
+
+       ret $31,($26),1
+       .end
+
+
+       .ent b_call_imm
+b_call_imm:
+$L1:
+       jsr $18,b_null
+       jsr $18,b_null
+       jsr $18,b_null
+       jsr $18,b_null
+       jsr $18,b_null
+
+       jsr $18,b_null
+       jsr $18,b_null
+       jsr $18,b_null
+       jsr $18,b_null
+       jsr $18,b_null
+
+       subq $16,1,$16
+       bgt $16,$L1
+
+       ret $31,($26),1
+       .end
+
+
+       .ent b_add
+b_add:
+$L2:
+       addq $31,$31,$31
+       addq $31,$31,$31
+       addq $31,$31,$31
+       addq $31,$31,$31
+       addq $31,$31,$31
+
+       addq $31,$31,$31
+       addq $31,$31,$31
+       addq $31,$31,$31
+       addq $31,$31,$31
+       addq $31,$31,$31
+
+       subq $16,1,$16
+       bgt $16,$L2
+
+       ret $31,($26),1
+       .end
+
+
+       .ent b_load
+b_load:
+$L3:
+       ldq $31,0($30)
+       ldq $31,8($30)
+       ldq $31,16($30)
+       ldq $31,24($30)
+       ldq $31,32($30)
+
+       ldq $31,0($30)
+       ldq $31,8($30)
+       ldq $31,16($30)
+       ldq $31,24($30)
+       ldq $31,32($30)
+
+       subq $16,1,$16
+       bgt $16,$L3
+
+       ret $31,($26),1
+       .end
diff --git a/src/QuickThreads/md/hppa.h b/src/QuickThreads/md/hppa.h
new file mode 100644 (file)
index 0000000..0df98de
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/*
+ * This file (pa-risc.h) is part of the port of QuickThreads for the
+ * PA-RISC 1.1 architecture.  This file is a machine dependent header
+ * file.  It was written in 1994 by Uwe Reder
+ * (`uereder@cip.informatik.uni-erlangen.de') for the Operating Systems
+ * Department (IMMD4) at the University of Erlangen/Nuernberg Germany.
+ */
+
+
+#ifndef QT_PA_RISC_H
+#define QT_PA_RISC_H
+
+#include <qt.h>
+
+/* size of an integer-register (32 bit) */
+typedef unsigned long qt_word_t;
+
+/* PA-RISC's stack grows up */
+#define QT_GROW_UP
+
+/* Stack layout on PA-RISC according to PA-RISC Procedure Calling Conventions:
+
+    Callee-save registers are: gr3-gr18, fr12-fr21.
+    Also save gr2, return pointer.
+
+    +---
+    | fr12          Each floating register is a double word (8 bytes).
+    | fr13          Floating registers are only saved if `qt_block' is
+    | fr14          called, in which case it saves the floating-point
+    | fr15          registers then calls `qt_blocki' to save the integer
+    | fr16         registers.
+    | fr17
+    | fr18
+    | fr19
+    | fr20
+    | fr21
+    | <arg word 3>  fixed arguments (must be allocated; may remain unused)
+    | <arg word 2>
+    | <arg word 1>
+    | <arg word 0>
+    | <LPT>         frame marker
+    | <LPT'>
+    | <RP'>
+    | <Current RP>
+    | <Static Link>
+    | <Clean Up>
+    | <RP''>
+    | <Previous SP>
+    +---
+    | gr3           word each (4 bytes)
+    | gr4
+    | gr5
+    | gr6
+    | gr7
+    | gr8
+    | gr9
+    | gr10
+    | gr11
+    | gr12
+    | gr13
+    | gr14
+    | gr15
+    | gr16
+    | gr17
+    | gr18
+    | <16 bytes filled in (sp has to be 64-bytes aligned)>
+    | <arg word 3>  fixed arguments (must be allocated; may remain unused)
+    | <arg word 2>
+    | <arg word 1>
+    | <arg word 0>
+    | <LPT>         frame marker
+    | <LPT'>
+    | <RP'>
+    | <Current RP>
+    | <Static Link>
+    | <Clean Up>
+    | <RP''>
+    | <Previous SP>
+    +---            <--- sp
+*/
+
+/* When a never-before-run thread is restored, the return pc points
+   to a fragment of code that starts the thread running.  For
+   non-vargs functions, it just calls the client's `only' function.
+   For varargs functions, it calls the startup, user, and cleanup
+   functions. */
+
+/* Note: Procedue Labels on PA-RISC
+
+   <--2--><-------28---------><1-><1->
+   -----------------------------------
+   | SID |    Adress Part    | L | X |
+   -----------------------------------
+
+   On HP-UX the L field is used to flag wheather the procedure
+   label (plabel) is a pointer to an LT entry or to the entry point
+   of the procedure (PA-RISC Procedure Calling Conventions Reference
+   Manual, 5.3.2 Procedure Labels and Dynamic Calls). */
+
+#define QT_PA_RISC_READ_PLABEL(plabel) \
+    ( (((int)plabel) & 2) ? \
+        ( (*((int *)(((int)plabel) & 0xfffffffc)))) : ((int)plabel) )
+
+/* Stack must be 64 bytes aligned. */
+#define QT_STKALIGN (64)
+
+/* Internal helper for putting stuff on stack (negative index!). */
+#define QT_SPUT(top, at, val)   \
+    (((qt_word_t *)(top))[-(at)] = (qt_word_t)(val))
+
+/* Offsets of various registers which are modified on the stack.
+   rp (return-pointer) has to be stored in the frame-marker-area
+   of the "older" stack-segment. */
+
+#define QT_crp  (12+4+16+5)
+#define QT_15   (12+4+4)
+#define QT_16   (12+4+3)
+#define QT_17   (12+4+2)
+#define QT_18   (12+4+1)
+
+
+/** This stuff is for NON-VARARGS. **/
+
+/* Stack looks like this (2 stack frames):
+
+    <--- 64-bytes aligned --><------- 64-bytes aligned ------------>
+   |                        ||                                      |
+    <--16--><------48-------><----16*4-----><--16-><------48------->
+   ||      |                ||             |      |                ||
+   ||filler|arg|frame-marker||register-save|filler|arg|frame-marker||
+   ------------------------------------------------------------------
+ */
+
+#define QT_STKBASE  (16+48+(16*sizeof(qt_word_t))+16+48)
+
+/* The index, relative to sp, of where to put each value. */
+#define QT_ONLY_INDEX   (QT_15)
+#define QT_USER_INDEX   (QT_16)
+#define QT_ARGT_INDEX   (QT_17)
+#define QT_ARGU_INDEX   (QT_18)
+
+extern void qt_start(void);
+#define QT_ARGS_MD(sp)  \
+    (QT_SPUT (sp, QT_crp, QT_PA_RISC_READ_PLABEL(qt_start)))
+
+
+/** This is for VARARGS. **/
+
+#define QT_VARGS_DEFAULT
+
+/* Stack looks like this (2 stack frames):
+
+    <------ 64-bytes aligned -------><--------- 64-bytes aligned ---------->
+   |                                ||                                      |
+    <---?--><--?---><16><----32-----><----16*4-----><-16--><16><----32----->
+   ||      |       |   |            ||             |      |   |            ||
+   ||filler|varargs|arg|frame-marker||register-save|filler|arg|frame-marker||
+   --------------------------------------------------------------------------
+ */
+
+/* Sp is moved to the end of the first stack frame. */
+#define QT_VARGS_MD0(sp, vasize) \
+    ((qt_t *)(((char *)sp) + QT_STKROUNDUP(vasize + 4*4 + 32)))
+
+/* To reach the arguments from the end of the first stack frame use 32
+   as a negative adjustment. */
+#define QT_VARGS_ADJUST(sp)    ((qt_t *)(((char *)sp) - 32))
+
+/* Offset to reach the end of the second stack frame. */
+#define QT_VSTKBASE    ((16*sizeof(qt_word_t)) + 16 + 4*4 + 32)
+
+extern void qt_vstart(void);
+#define QT_VARGS_MD1(sp) \
+    (QT_SPUT (sp, QT_crp, QT_PA_RISC_READ_PLABEL(qt_vstart)))
+
+#define QT_VARGT_INDEX      (QT_15)
+#define QT_VSTARTUP_INDEX   (QT_16)
+#define QT_VUSERF_INDEX     (QT_17)
+#define QT_VCLEANUP_INDEX   (QT_18)
+
+#endif /* ndef QT_PA_RISC_H */
diff --git a/src/QuickThreads/md/hppa.s b/src/QuickThreads/md/hppa.s
new file mode 100644 (file)
index 0000000..84d8e87
--- /dev/null
@@ -0,0 +1,237 @@
+; pa-risc.s -- assembly support.
+
+; QuickThreads -- Threads-building toolkit.
+; Copyright (c) 1993 by David Keppel
+;
+; Permission to use, copy, modify and distribute this software and
+; its documentation for any purpose and without fee is hereby
+; granted, provided that the above copyright notice and this notice
+; appear in all copies.  This software is provided as a
+; proof-of-concept and for demonstration purposes; there is no
+; representation about the suitability of this software for any
+; purpose.
+
+; This file (pa-risc.s) is part of the port of QuickThreads for
+; PA-RISC 1.1 architecture.  This file implements context switches
+; and thread startup.  It was written in 1994 by Uwe Reder
+; (`uereder@cip.informatik.uni-erlangen.de') for the Operating
+; Systems Department (IMMD4) at the University of Erlangen/Nuernberg
+; Germany.
+
+
+; Callee saves general registers gr3..gr18,
+;              floating-point registers fr12..fr21.
+
+            .CODE
+
+            .IMPORT $$dyncall, MILLICODE
+            .IMPORT qt_error, CODE
+
+            .EXPORT qt_blocki, ENTRY
+            .EXPORT qt_block, ENTRY
+            .EXPORT qt_abort, ENTRY
+            .EXPORT qt_start, ENTRY
+            .EXPORT qt_vstart, ENTRY
+
+
+; arg0: ptr to function (helper) to call once curr is suspended
+;       and control is on arg3's stack.
+; arg1: 1'th arg to *arg0.
+; arg2: 2'th arg to *arg0.
+; arg3: sp of new thread.
+
+qt_blocki
+            .PROC
+            .CALLINFO   CALLER, FRAME=0, SAVE_RP, ENTRY_GR=18
+            .ENTRY
+
+            stw         %rp,-20(%sp)    ; save rp to old frame-marker
+
+            stwm        %r3,128(%sp)    ; save callee-saves general registers
+            stw         %r4,-124(%sp)
+            stw         %r5,-120(%sp)
+            stw         %r6,-116(%sp)
+            stw         %r7,-112(%sp)
+            stw         %r8,-108(%sp)
+            stw         %r9,-104(%sp)
+            stw         %r10,-100(%sp)
+            stw         %r11,-96(%sp)
+            stw         %r12,-92(%sp)
+            stw         %r13,-88(%sp)
+            stw         %r14,-84(%sp)
+            stw         %r15,-80(%sp)
+            stw         %r16,-76(%sp)
+            stw         %r17,-72(%sp)
+            stw         %r18,-68(%sp)
+
+qt_abort
+            copy        %arg0,%r22      ; helper to be called by $$dyncall
+            copy        %sp,%arg0       ; pass current sp as arg0 to helper
+            copy        %arg3,%sp       ; set new sp
+
+            .CALL
+            bl          $$dyncall,%mrp  ; call helper
+            copy        %mrp,%rp
+
+            ldw         -68(%sp),%r18   ; restore general registers
+            ldw         -72(%sp),%r17
+            ldw         -76(%sp),%r16
+            ldw         -80(%sp),%r15
+            ldw         -84(%sp),%r14
+            ldw         -88(%sp),%r13
+            ldw         -92(%sp),%r12
+            ldw         -96(%sp),%r11
+            ldw         -100(%sp),%r10
+            ldw         -104(%sp),%r9
+            ldw         -108(%sp),%r8
+            ldw         -112(%sp),%r7
+            ldw         -116(%sp),%r6
+            ldw         -120(%sp),%r5
+            ldw         -124(%sp),%r4
+
+            ldw         -148(%sp),%rp   ; restore return-pointer
+
+            bv          %r0(%rp)        ; return to caller
+            ldwm        -128(%sp),%r3
+
+            .EXIT
+            .PROCEND
+
+
+qt_block
+            .PROC
+            .CALLINFO   CALLER, FRAME=0, SAVE_RP, ENTRY_FR=21
+            .ENTRY
+
+            stw         %rp,-20(%sp)    ; save rp to old frame-marker
+
+            fstds,ma    %fr12,8(%sp)    ; save callee-saves float registers
+            fstds,ma    %fr13,8(%sp)
+            fstds,ma    %fr14,8(%sp)
+            fstds,ma    %fr15,8(%sp)
+            fstds,ma    %fr16,8(%sp)
+            fstds,ma    %fr17,8(%sp)
+            fstds,ma    %fr18,8(%sp)
+            fstds,ma    %fr19,8(%sp)
+            fstds,ma    %fr20,8(%sp)
+            fstds,ma    %fr21,8(%sp)
+
+            .CALL
+            bl          qt_blocki,%rp
+            ldo         48(%sp),%sp
+
+            ldo         -48(%sp),%sp
+
+            fldds,mb    -8(%sp),%fr21   ; restore callee-saves float registers
+            fldds,mb    -8(%sp),%fr20
+            fldds,mb    -8(%sp),%fr19
+            fldds,mb    -8(%sp),%fr18
+            fldds,mb    -8(%sp),%fr17
+            fldds,mb    -8(%sp),%fr16
+            fldds,mb    -8(%sp),%fr15
+            fldds,mb    -8(%sp),%fr14
+            fldds,mb    -8(%sp),%fr13
+
+            ldw         -28(%sp),%rp    ; restore return-pointer
+            
+            bv          %r0(%rp)        ; return to caller.
+            fldds,mb    -8(%sp),%fr12
+            
+            .EXIT
+            .PROCEND
+
+
+qt_start
+            .PROC
+            .CALLINFO   CALLER, FRAME=0
+            .ENTRY
+
+            copy        %r18,%arg0      ; set user arg `pu'.
+            copy        %r17,%arg1      ; ... user function pt.
+            copy        %r16,%arg2      ; ... user function userf.
+                                        ; %r22 is a caller-saves register
+            copy        %r15,%r22       ; function to be called by $$dyncall
+
+            .CALL                       ; in=%r22
+            bl          $$dyncall,%mrp  ; call `only'.
+            copy        %mrp,%rp
+            
+            bl,n        qt_error,%r0    ; `only' erroniously returned.
+
+            .EXIT
+            .PROCEND
+
+
+; Varargs
+;
+; First, call `startup' with the `pt' argument.
+;
+; Next, call the user's function with all arguments.
+; We don't know whether arguments are integers, 32-bit floating-points or
+; even 64-bit floating-points, so we reload all the registers, possibly
+; with garbage arguments.  The thread creator provided non-garbage for
+; the arguments that the callee actually uses, so the callee never gets
+; garbage.
+;
+;            -48    -44    -40    -36    -32
+;             | arg3 | arg2 | arg1 | arg0 |
+;             -----------------------------
+; integers:     arg3   arg2   arg1   arg0
+; 32-bit fps:  farg3  farg2  farg1  farg0
+; 64-bit fps:  <---farg3-->  <---farg1-->
+;
+; Finally, call `cleanup' with the `pt' argument and with the return value
+; from the user's function.  It is an error for `cleanup' to return.
+
+qt_vstart
+            .PROC
+            .CALLINFO   CALLER, FRAME=0
+            .ENTRY
+
+            ; Because the startup function may damage the fixed arguments
+            ; on the stack (PA-RISC Procedure Calling Conventions Reference
+            ; Manual, 2.4 Fixed Arguments Area), we allocate a seperate
+            ; stack frame for it.
+            ldo         64(%sp),%sp
+
+            ; call: void startup(void *pt)
+
+            copy        %r15,%arg0      ; `pt' is arg0 to `startup'.
+            copy        %r16,%r22
+            .CALL
+            bl          $$dyncall,%mrp  ; Call `startup'.
+            copy        %mrp,%rp
+
+            ldo         -64(%sp),%sp
+
+            ; call: void *qt_vuserf_t(...)
+
+            ldw         -36(%sp),%arg0  ; Load args to integer registers.
+            ldw         -40(%sp),%arg1
+            ldw         -44(%sp),%arg2
+            ldw         -48(%sp),%arg3
+            ; Index of fld[w|d]s only ranges from -16 to 15, so we
+            ; take r22 to be our new base register.
+            ldo         -32(%sp),%r22
+            fldws       -4(%r22),%farg0 ; Load args to floating-point registers.
+            fldds       -8(%r22),%farg1
+            fldws       -12(%r22),%farg2
+            fldds       -16(%r22),%farg3
+            copy        %r17,%r22
+            .CALL
+            bl          $$dyncall,%mrp  ; Call `userf'.
+            copy        %mrp,%rp
+
+            ; call: void cleanup(void *pt, void *vuserf_return)
+
+            copy        %r15,%arg0      ; `pt' is arg0 to `cleanup'.
+            copy        %ret0,%arg1     ; Return-value is arg1 to `cleanup'.
+            copy        %r18,%r22
+            .CALL
+            bl          $$dyncall,%mrp  ; Call `cleanup'.
+            copy        %mrp,%rp
+
+            bl,n        qt_error,%r0
+
+            .EXIT
+            .PROCEND
diff --git a/src/QuickThreads/md/hppa_b.s b/src/QuickThreads/md/hppa_b.s
new file mode 100644 (file)
index 0000000..1b1e826
--- /dev/null
@@ -0,0 +1,203 @@
+; QuickThreads -- Threads-building toolkit.
+; Copyright (c) 1993 by David Keppel
+
+; Permission to use, copy, modify and distribute this software and
+; its documentation for any purpose and without fee is hereby
+; granted, provided that the above copyright notice and this notice
+; appear in all copies.  This software is provided as a
+; proof-of-concept and for demonstration purposes; there is no
+; representation about the suitability of this software for any
+; purpose.
+
+; This file (pa-risc_b.s) is part of the port of QuickThreads for
+; PA-RISC 1.1 architecture.  It contains assembly-level support for
+; raw processor performance measurement.  It was written in 1994 by
+; Uwe Reder (`uereder@cip.informatik.uni-erlangen.de')
+; for the Operating Systems Department (IMMD4) at the
+; University of Erlangen/Nuernberg Germany.
+
+
+; Note that the number of instructions in the measurement-loops, differ
+; from implementation to implementation. I took eight instructions in a loop
+; for every test (execute eight instructions and loop to the start).
+
+            .CODE
+
+            .IMPORT $global$,DATA
+            .IMPORT $$dyncall,MILLICODE
+            .EXPORT b_call_reg
+            .EXPORT b_call_imm
+            .EXPORT b_add
+            .EXPORT b_load
+
+; Just do nothing, only return to caller. This procedure is called by
+; `b_call_reg' and `b_call_imm'.
+
+b_null
+            .PROC
+            .CALLINFO   NO_CALLS, FRAME=0
+            .ENTRY
+
+            bv,n        %r0(%rp)        ; just return
+
+            .EXIT
+            .PROCEND
+
+; Call the procedure `b_null' with function pointer in a register.
+
+b_call_reg
+            .PROC
+            .CALLINFO   CALLER, FRAME=0
+            .ENTRY
+    
+            stwm        %r3,64(%sp)     ; store r3 (may be used by caller)
+            stw         %rp,-20(%sp)    ; save return-pointer to frame-marker
+
+            addil       LR'to_call-$global$,%r27
+            ldw         RR'to_call-$global$(%r1),%r3
+
+_loop0
+            copy        %r3,%r22        ; copy the procedure label to r22, ...
+            .CALL                       ; ...this is the input to $$dyncall
+            bl          $$dyncall,%mrp  ; call $$dyncall (millicode function)
+            copy        %mrp,%rp        ; remember the return-pointer
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            copy        %r3,%r22
+            .CALL
+            bl          $$dyncall,%mrp
+            copy        %mrp,%rp
+
+            addibf,<=   -8,%arg0,_loop0 ; decrement counter by 8 and loop
+            nop
+
+            ldw         -20(%sp),%rp    ; restore return-pointer
+            bv          %r0(%rp)        ; return to caller
+            ldwm        -64(%sp),%r3    ; resore r3 and remove stack frame
+
+            .EXIT
+            .PROCEND
+
+; Call the procedure `b_null' immediate.
+
+b_call_imm
+            .PROC
+            .CALLINFO   CALLER, FRAME=0, SAVE_RP
+            .ENTRY
+
+            ldo         64(%sp),%sp     ; caller needs a stack-frame
+            stw         %rp,-20(%sp)    ; save return-pointer to frame-marker
+
+_loop1
+            bl          b_null,%rp      ; call `b_null' immediate (8 times)
+            nop 
+            bl          b_null,%rp
+            nop
+            bl          b_null,%rp
+            nop
+            bl          b_null,%rp
+            nop
+            bl          b_null,%rp
+            nop
+            bl          b_null,%rp
+            nop
+            bl          b_null,%rp
+            nop
+            bl          b_null,%rp
+            nop
+
+            addibf,<=   -8,%arg0,_loop1 ; decrement counter by 8 and loop
+            nop
+            
+            ldw         -20(%sp),%rp    ; restore return-pointer
+            bv          %r0(%rp)        ; return to caller
+            ldo         -64(%sp),%sp    ; remove stack-frame
+
+            .EXIT
+            .PROCEND
+
+; Copy register-to-register.
+; On PA-RISC this is implemented with an `or'.
+; The `or' is hidden by a pseudo-operation called `copy'.
+
+b_add
+            .PROC
+            .CALLINFO   NO_CALLS, FRAME=0
+            .ENTRY
+
+_loop2
+            copy        %r19,%r20       ; copy register-to-register
+            copy        %r20,%r21       ; use caller-saves registers
+            copy        %r21,%r22
+            copy        %r22,%r21
+            copy        %r21,%r20
+            copy        %r20,%r19
+            copy        %r19,%r20
+            copy        %r20,%r21
+
+            addibf,<=   -8,%arg0,_loop2 ; decrement counter by 8 and loop
+            nop
+
+            bv,n        %r0(%rp)
+
+            .EXIT
+            .PROCEND
+
+; Load memory to a register.
+
+b_load
+            .PROC
+            .CALLINFO   NO_CALLS, FRAME=0
+            .ENTRY
+
+_loop3
+            ldw         -4(%sp),%r22    ; load data from frame-marker
+            ldw         -8(%sp),%r22    ; use a caller-saves register
+            ldw         -12(%sp),%r22
+            ldw         -16(%sp),%r22
+            ldw         -20(%sp),%r22
+            ldw         -24(%sp),%r22
+            ldw         -28(%sp),%r22
+            ldw         -32(%sp),%r22
+
+            addibf,<=   -8,%arg0,_loop3 ; decrement counter by 8 and loop
+            nop
+
+            bv,n        %r0(%rp)
+
+            .EXIT
+            .PROCEND
+
+
+            .ALIGN 8
+to_call
+            .WORD       b_null
diff --git a/src/QuickThreads/md/i386.README b/src/QuickThreads/md/i386.README
new file mode 100644 (file)
index 0000000..8ffb921
--- /dev/null
@@ -0,0 +1,7 @@
+Note that some machines want labels to have leading underscores,
+while others (e.g. System V) do not.  Thus, several labels appear
+duplicated except for the leading underscore, e.g.
+
+       _qt_cswap:
+       qt_cswap:
+
diff --git a/src/QuickThreads/md/i386.h b/src/QuickThreads/md/i386.h
new file mode 100644 (file)
index 0000000..158fe27
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QT_386_H
+#define QT_386_H
+
+typedef unsigned long qt_word_t;
+
+/* Thread's initial stack layout on the i386:
+
+   non-varargs:
+
+   +---
+   | arg[2]    === `userf' on startup
+   | arg[1]    === `pt' on startup
+   | arg[0]    === `pu' on startup
+   +---
+   | ret pc === qt_error
+   +---
+   | ret pc    === `only' on startup
+   +---
+   | %ebp
+   | %esi
+   | %edi
+   | %ebx                              <--- qt_t.sp
+   +---
+
+   When a non-varargs thread is started, it ``returns'' directly to
+   the client's `only' function.
+
+   varargs:
+
+   +---
+   | arg[n-1]
+   | ..
+   | arg[0]
+   +---
+   | ret pc    === `qt_vstart'
+   +---
+   | %ebp      === `startup'
+   | %esi      === `cleanup'
+   | %edi      === `pt'
+   | %ebx      === `vuserf'            <--- qt_t.sp
+   +---
+
+   When a varargs thread is started, it ``returns'' to the `qt_vstart'
+   startup code.  The startup code calls the appropriate functions. */
+
+
+/* What to do to start a varargs thread running. */
+extern void qt_vstart (void);
+
+
+/* Hold 4 saved regs plus two return pcs (qt_error, qt_start) plus
+   three args. */
+#define QT_STKBASE     (9 * 4)
+
+/* Hold 4 saved regs plus one return pc (qt_vstart). */
+#define QT_VSTKBASE    (5 * 4)
+
+
+/* Stack must be 4-byte aligned. */
+#define QT_STKALIGN    (4)
+
+
+/* Where to place various arguments. */
+#define QT_ONLY_INDEX  (QT_PC)
+#define QT_USER_INDEX  (QT_ARG2)
+#define QT_ARGT_INDEX  (QT_ARG1)
+#define QT_ARGU_INDEX  (QT_ARG0)
+
+#define QT_VSTARTUP_INDEX      (QT_EBP)
+#define QT_VUSERF_INDEX                (QT_EBX)
+#define QT_VCLEANUP_INDEX      (QT_ESI)
+#define QT_VARGT_INDEX         (QT_EDI)
+
+
+#define QT_EBX 0
+#define QT_EDI 1
+#define QT_ESI 2
+#define QT_EBP 3
+#define QT_PC  4
+/* The following are defined only for non-varargs. */
+#define QT_RPC 5
+#define QT_ARG0        6
+#define QT_ARG1        7
+#define QT_ARG2        8
+
+
+/* Stack grows down.  The top of the stack is the first thing to
+   pop off (preincrement, postdecrement). */
+#define QT_GROW_DOWN
+
+extern void qt_error (void);
+
+/* Push on the error return address. */
+#define QT_ARGS_MD(sto) \
+  (QT_SPUT (sto, QT_RPC, qt_error))
+
+
+/* When varargs are pushed, allocate space for all the args. */
+#define QT_VARGS_MD0(sto, nbytes) \
+  ((qt_t *)(((char *)(sto)) - QT_STKROUNDUP(nbytes)))
+
+#define QT_VARGS_MD1(sto) \
+  (QT_SPUT (sto, QT_PC, qt_vstart))
+
+#define QT_VARGS_DEFAULT
+
+#endif /* QT_386_H */
diff --git a/src/QuickThreads/md/i386.s b/src/QuickThreads/md/i386.s
new file mode 100644 (file)
index 0000000..ed2c533
--- /dev/null
@@ -0,0 +1,108 @@
+/* i386.s -- assembly support. */
+
+/*
+// QuickThreads -- Threads-building toolkit.
+// Copyright (c) 1993 by David Keppel
+//
+// Permission to use, copy, modify and distribute this software and
+// its documentation for any purpose and without fee is hereby
+// granted, provided that the above copyright notice and this notice
+// appear in all copies.  This software is provided as a
+// proof-of-concept and for demonstration purposes; there is no
+// representation about the suitability of this software for any
+// purpose. */
+
+/* NOTE: double-labeled `_name' and `name' for System V compatability.  */
+/* NOTE: Comment lines start with '/*' and '//' ONLY.  Sorry! */
+
+/* Callee-save: %esi, %edi, %ebx, %ebp
+// Caller-save: %eax, %ecx
+// Can't tell: %edx (seems to work w/o saving it.)
+//
+// Assignment:
+//
+// See ``i386.h'' for the somewhat unconventional stack layout.  */
+
+
+       .text
+       .align 2
+
+       .globl _qt_abort
+       .globl qt_abort
+       .globl _qt_block
+       .globl qt_block
+       .globl _qt_blocki
+       .globl qt_blocki
+
+/* These all have the type signature
+//
+//     void *blocking (helper, arg0, arg1, new)
+//
+// On procedure entry, the helper is at 4(sp), args at 8(sp) and
+// 12(sp) and the new thread's sp at 16(sp).  It *appears* that the
+// calling convention for the 8X86 requires the caller to save all
+// floating-point registers, this makes our life easy.  */
+
+/* Halt the currently-running thread.  Save it's callee-save regs on
+// to the stack, 32 bytes.  Switch to the new stack (next == 16+32(sp))
+// and call the user function (f == 4+32(sp) with arguments: old sp
+// arg1 (8+32(sp)) and arg2 (12+32(sp)).  When the user function is
+// done, restore the new thread's state and return.
+//
+// `qt_abort' is (currently) an alias for `qt_block' because most of
+// the work is shared.  We could save the insns up to `qt_common' by
+// replicating, but w/o replicating we need an inital subtract (to
+// offset the stack as if it had been a qt_block) and then a jump
+// to qt_common.  For the cost of a jump, we might as well just do
+// all the work.
+//
+// The helper function (4(sp)) can return a void* that is returned
+// by the call to `qt_blockk{,i}'.  Since we don't touch %eax in
+// between, we get that ``for free''.  */
+
+_qt_abort:
+qt_abort:
+_qt_block:
+qt_block:
+_qt_blocki:
+qt_blocki:
+       pushl %ebp              /* Save callee-save, sp-=4. */
+       pushl %esi              /* Save callee-save, sp-=4. */
+       pushl %edi              /* Save callee-save, sp-=4. */
+       pushl %ebx              /* Save callee-save, sp-=4. */
+       movl %esp, %eax         /* Remember old stack pointer. */
+
+qt_common:
+       movl 32(%esp), %esp     /* Move to new thread. */
+       pushl 28(%eax)          /* Push arg 2. */
+       pushl 24(%eax)          /* Push arg 1. */
+       pushl %eax              /* Push arg 0. */
+       movl 20(%eax), %ebx     /* Get function to call. */
+       call *%ebx              /* Call f. */
+       addl $12, %esp          /* Pop args. */
+
+       popl %ebx               /* Restore callee-save, sp+=4. */
+       popl %edi               /* Restore callee-save, sp+=4. */
+       popl %esi               /* Restore callee-save, sp+=4. */
+       popl %ebp               /* Restore callee-save, sp+=4. */
+       ret                     /* Resume the stopped function. */
+       hlt
+
+
+/* Start a varargs thread. */
+
+       .globl _qt_vstart
+       .globl qt_vstart
+_qt_vstart:
+qt_vstart:
+       pushl %edi              /* Push `pt' arg to `startup'. */
+       call *%ebp              /* Call `startup'. */
+       popl %eax               /* Clean up the stack. */
+
+       call *%ebx              /* Call the user's function. */
+
+       pushl %eax              /* Push return from user's. */
+       pushl %edi              /* Push `pt' arg to `cleanup'. */
+       call *%esi              /* Call `cleanup'. */
+
+       hlt                     /* `cleanup' never returns. */
diff --git a/src/QuickThreads/md/i386_b.s b/src/QuickThreads/md/i386_b.s
new file mode 100644 (file)
index 0000000..32129a5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+// QuickThreads -- Threads-building toolkit.
+// Copyright (c) 1993 by David Keppel
+//
+// Permission to use, copy, modify and distribute this software and
+// its documentation for any purpose and without fee is hereby
+// granted, provided that the above copyright notice and this notice
+// appear in all copies.  This software is provided as a
+// proof-of-concept and for demonstration purposes; there is no
+// representation about the suitability of this software for any
+// purpose.  */
+
+       .globl _b_call_reg
+       .globl b_call_reg
+       .globl _b_call_imm
+       .globl b_call_imm
+       .globl _b_add
+       .globl b_add
+       .globl _b_load
+       .globl b_load
+
+_b_call_reg:
+b_call_reg:
+_b_call_imm:
+b_call_imm:
+_b_add:
+b_add:
+_b_load:
+b_load:
+       hlt
diff --git a/src/QuickThreads/md/ksr1.h b/src/QuickThreads/md/ksr1.h
new file mode 100644 (file)
index 0000000..83537a3
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QT_KSR1_H
+#define QT_KSR1_H
+
+/* 
+   Stack layout:
+
+   Registers are saved in strictly low to high order, FPU regs first 
+   (only if qt_block is called), CEU regs second, IPU regs next, with no
+   padding between the groups.
+
+   Callee-save:  f16..f63; c15..c30; i12..i30.
+   Args passed in i2..i5.
+
+   Note: c31 is a private data pointer.  It is not changed on thread
+   swaps with the assumption that it represents per-processor rather
+   than per-thread state.
+
+   Note: i31 is an instruction count register that is updated by the
+   context switch routines.  Like c31, it is not changed on context
+   switches.
+
+   This is what we want on startup:
+
+
+   +------             <-- BOS: Bottom of stack (grows down)
+   | 80 (128 - 48) bytes of padding to a 128-byte boundary
+   +---
+   | only
+   | userf
+   | t
+   | u
+   | qt_start$TXT
+   | (empty)           <-- qt.sp
+   +------             <-- (BOS - 128)
+
+   This is why we want this on startup:
+   
+   A thread begins running when the restore procedure switches thread stacks
+   and pops a return address off of the top of the new stack (see below
+   for the reason why we explicitly store qt_start$TXT).  The
+   block procedure pushes two jump addresses on a thread's stack before
+   it switches stacks.  The first is the return address for the block
+   procedure, and the second is a restore address.  The return address
+   is used to jump back to the thread that has been switched to;  the
+   restore address is a jump within the block code to restore the registers.
+   Normally, this is just a jump to the next address.  However, on thread
+   startup, this is a jump to qt_start$TXT.  (The block procedure stores
+   the restore address at an offset of 8 bytes from the top of the stack,
+   which is also the offset at which qt_start$TXT is stored on the stacks
+   of new threads.  Hence, when the block procedure switches to a new
+   thread stack, it will initially jump to qt_start$TXT; thereafter,
+   it jumps to the restore code.)
+
+   qt_start$TXT, after it has read the initial data on the new thread's
+   stack and placed it in registers, pops the initial stack frame
+   and gives the thread the entire stack to use for execution.
+
+   The KSR runtime system has an unusual treatment of pointers to
+   functions.  From C, taking the `name' of a function yields a
+   pointer to a _constant block_ and *not* the address of the
+   function.  The zero'th entry in the constant block is a pointer to
+   the function.
+
+   We have to be careful: the restore procedure expects a return
+   address on the top of the stack (pointed to by qt.sp).  This is not
+   a problem when restoring a thread that has run before, since the
+   block routine would have stored the return address on top of the
+   stack.  However, when ``faking up'' a thread start (bootstrapping a
+   thread stack frame), the top of the stack needs to contain a
+   pointer to the code that will start the thread running.
+
+   The pointer to the startup code is *not* `qt_start'.  It is the
+   word *pointed to* by `qt_start'.  Thus, we dereference `qt_start',
+   see QT_ARGS_MD below.
+
+   On varargs startup (still unimplemented):
+
+   | padding to 128 byte boundary
+   | varargs           <-- padded to a 128-byte-boundary
+   +---
+   | caller's frame, 16 bytes
+   | 80 bytes of padding (frame padded to a 128-byte boundary)
+   +---
+   | cleanup
+   | vuserf
+   | startup
+   | t
+   +---
+   | qt_start          <-- qt.sp
+   +---
+
+   Of a suspended thread:
+
+   +---
+   | caller's frame, 16 bytes
+   | fpu registers 47 regs * 8 bytes/reg 376 bytes
+   | ceu registers 16 regs * 8 bytes/reg 128 bytes
+   | ipu registers 19 regs * 8 bytes/reg 152 bytes
+   |  :
+   | 80 bytes of padding
+   |  :
+   | qt_restore                <-- qt.sp
+   +---
+
+   */
+
+
+#define QT_STKALIGN    128
+#define QT_GROW_DOWN
+typedef unsigned long qt_word_t;
+
+#define QT_STKBASE     QT_STKALIGN
+#define QT_VSTKBASE    QT_STKBASE
+
+extern void qt_start(void);
+/*
+ * See the discussion above for what indexing into a procedure ptr 
+ * does for us (it's lovely, though, isn't it?).
+ *
+ * This assumes that the address of a procedure's code is the
+ * first word in a procedure's constant block.  That's how the manual
+ * says it will be arranged.
+ */
+#define QT_ARGS_MD(sp) (QT_SPUT (sp, 1, ((qt_word_t *)qt_start)[0]))
+
+/* 
+ * The *index* (positive offset) of where to put each value.
+ * See the picture of the stack above that explains the offsets.
+ */
+#define QT_ONLY_INDEX  (5)
+#define QT_USER_INDEX  (4)
+#define QT_ARGT_INDEX  (3)
+#define QT_ARGU_INDEX  (2)
+
+#define QT_VARGS_DEFAULT
+#define QT_VARGS(sp, nb, vargs, pt, startup, vuserf, cleanup) \
+      (qt_vargs (sp, nbytes, &vargs, pt, startup, vuserf, cleanup))
+
+
+#define QT_VARGS_MD0(sp, vabytes) \
+  ((qt_t *)(((char *)(sp)) - 4*8 - QT_STKROUNDUP(vabytes)))
+
+extern void qt_vstart(void);
+#define QT_VARGS_MD1(sp)       (QT_SPUT (sp, 0, ((qt_word_t *)qt_vstart)[0]))
+
+#define QT_VCLEANUP_INDEX      (4)
+#define QT_VUSERF_INDEX                (3)
+#define QT_VSTARTUP_INDEX      (2)
+#define QT_VARGT_INDEX         (1)
+
+#endif /* def QT_KSR1_H */
diff --git a/src/QuickThreads/md/ksr1.s b/src/QuickThreads/md/ksr1.s
new file mode 100644 (file)
index 0000000..d4d51a0
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies.  This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+       .file   "ksr1.s"
+       .def    .debug; .endef
+
+       .align 128
+       .globl qt_blocki
+       .globl qt_blocki$TXT
+       .globl qt_block
+       .globl qt_block$TXT
+       .globl qt_start$TXT
+        .globl qt_start
+       .globl qt_abort$TXT
+       .globl qt_abort
+       .globl qt_vstart
+       .globl qt_vstart$TXT
+
+#
+# KSR convention: on procedure calls, load both the procedure address
+# and a pointer to a constant block.  The address of function `f' is
+# `f$TXT', and the constant block address is `f'.  The constant block
+# has several reserved values:
+#
+#      8 bytes fpu register save mask
+#      4 bytes ipu register save mask
+#      4 bytes ceu register save mask
+#   f:  f$TXT
+#      ... whatever you want ... (not quite...read on)
+#
+# Note, by the way, that a pointer to a function is passed as a
+# pointer to the constant area, and the constant area has the text
+# address.
+#
+
+#
+# Procedures that do not return structures prefix their code with
+#
+# proc$TXT:
+#   finop; cxnop
+#   finop; cxnop
+#   <proc code>
+#
+# Calls to those procedures branch to a 16 byte offset (4 instrs) in
+# to the procedure to skip those instructions.
+#
+# Procedures that return structures use a different code prefix:
+#
+# proc$TXT:
+#   finop; beq.qt %rc, %rc, 24         # return value entry
+#   finop; cxnop
+#   finop; movi8 0, %rc                        # no return value entry
+#   <proc code>
+#
+# Calls that want the returned structure branch directly to the
+# procedure address.  Callers that don't want (or aren't expecting) a
+# return value branche 16 bytes in to the procedure, which will zero
+# %rc, telling the called procedure not to return a structure.
+#
+
+#
+# On entry:
+#   %i2 -- control block of helper function to run
+#          (dereference to get helper)
+#   %i3 -- a1
+#   %i4 -- a2
+#   %i5 -- sp of new to run
+#
+
+        .data
+       .half 0x0, 0x0, 0x7ffff000, 0x7fff8000
+qt_blocki:
+qt_abort:
+       .word qt_blocki$TXT
+       .word qt_restore$TXT
+
+       .text
+qt_abort$TXT:
+qt_blocki$TXT:
+       finop                   ; cxnop                 # entry prefix
+       finop                   ; cxnop                 # entry prefix
+       add8.ntr 75,%i31,%i31   ; movi8 512,%c5         # ICR; stk adjust
+       finop                   ; ssub8.ntr 0,%sp,%c5,%sp
+       finop                   ; st8 %fp,504(%sp)      # Save caller's fp
+       finop                   ; st8 %cp,496(%sp)      # Save caller's cp
+       finop                   ; ld8 8(%c10),%c5       # ld qt_restore$TXT
+       finop                   ; st8 %c14,0(%sp)       # Save special ret addr
+       finop                   ; mov8_8 %c10, %cp      # Our cp
+       finop                   ; sadd8.ntr 0,%sp,%c5,%fp # Our frame ptr
+       finop                   ; st8 %c5,8(%sp)        # st qt_restore$TXT
+#
+# CEU registers %c15-%c24, %c26-%c30 (%c14 we restore later)
+#
+       finop                   ; st8  %c15,456(%sp)
+       finop                   ; st8  %c16,448(%sp)
+       finop                   ; st8  %c17,440(%sp)
+       finop                   ; st8  %c18,432(%sp)
+       finop                   ; st8  %c19,424(%sp)
+       finop                   ; st8  %c20,416(%sp)
+       finop                   ; st8  %c21,408(%sp)
+       finop                   ; st8  %c22,400(%sp)
+       finop                   ; st8  %c23,392(%sp)
+       finop                   ; st8  %c24,384(%sp)
+#
+# %c25 is the Enclosing Frame Pointer (EFP) -- since C doesn't
+# use nested procedures, we ignore it (leaving a gap, though)
+#
+       finop                   ; st8 %c26,368(%sp)
+       finop                   ; st8 %c27,360(%sp)
+       finop                   ; st8 %c28,352(%sp)
+       finop                   ; st8 %c29,344(%sp)
+       finop                   ; st8 %c30,336(%sp)
+#
+# IPU registers %i12-%i30
+# 
+       finop                   ; st8 %i12,328(%sp)
+       finop                   ; st8 %i13,320(%sp)
+       finop                   ; st8 %i14,312(%sp)
+       finop                   ; st8 %i15,304(%sp)
+# (gap to get alignment for st64)
+# -- Doesn't work on version 1.1.3 of the OS
+#      finop                   ; st64 %i16,256(%sp)
+
+       finop                   ; st8 %i16,256(%sp)
+       finop                   ; st8 %i17,248(%sp)
+       finop                   ; st8 %i18,240(%sp)
+       finop                   ; st8 %i19,232(%sp)
+       finop                   ; st8 %i20,224(%sp)
+       finop                   ; st8 %i21,216(%sp)
+       finop                   ; st8 %i22,208(%sp)
+       finop                   ; st8 %i23,200(%sp)
+       finop                   ; st8 %i24,192(%sp)
+       finop                   ; st8 %i25,184(%sp)
+       finop                   ; st8 %i26,176(%sp)
+       finop                   ; st8 %i27,168(%sp)
+       finop                   ; st8 %i28,160(%sp)
+       finop                   ; st8 %i29,152(%sp)
+       finop                   ; st8 %i30,144(%sp)
+#
+# FPU already saved, or saving not necessary
+#
+
+#
+# Switch to the stack passed in as fourth argument to the block
+# routine (%i5) and call the helper routine passed in as the first
+# argument (%i2).  Note that the address of the helper's constant
+# block is passed in, so we must derefence it to get the helper's text
+# address.
+#
+       finop                   ; movb8_8 %i2,%c10      # helper's ConstBlock
+       finop                   ; cxnop                 # Delay slot, fill w/
+       finop                   ; cxnop                 # .. 2 st8 from above
+       finop                   ; ld8 0(%c10),%c4       # load addr of helper
+       finop                   ; movb8_8 %sp, %i2      # 1st arg to helper
+                                                       # is this stack; other
+                                                       # args remain in regs
+       finop                   ; movb8_8 %i5,%sp       # switch stacks
+       finop                   ; jsr %c14,16(%c4)      # call helper
+       movi8 3, %i0            ; movi8 0,%c8           # nargs brain dmg
+       finop                   ; cxnop 
+       finop                   ; cxnop 
+#
+# Here is where behavior differs for threads being restored and threads
+# being started.  Blocked threads have a pointer to qt_restore$TXT on
+# the top of their stacks; manufactured stacks have a pointer to qt_start$TXT
+# on the top of their stacks.  With this setup, starting threads
+# skip the (unecessary) restore operations.
+#
+# We jump to an offset of 16 to either (1) skip past the two noop pairs
+# at the start of qt_start$TXT, or (2) skip past the two noop pairs
+# after qt_restore$TXT.
+#
+       finop                   ; ld8 8(%sp),%c4
+       finop                   ; cxnop
+       finop                   ; cxnop
+       finop                   ; jmp 16(%c4)
+qt_restore$TXT:
+       finop                   ; cxnop
+       finop                   ; cxnop
+#
+# Point of Restore:
+#
+# The helper funtion will return here.  Any result it has placed in
+# a return register (most likely %i0) will not get overwritten below
+# and will consequently be the return value of the blocking routine.
+#
+
+#
+# CEU registers %c15-%c24, %c26-%c30 (%c14 we restore later)
+#
+       finop                   ; ld8  456(%sp),%c15
+       finop                   ; ld8  448(%sp),%c16
+       finop                   ; ld8  440(%sp),%c17
+       finop                   ; ld8  432(%sp),%c18
+       finop                   ; ld8  424(%sp),%c19
+       finop                   ; ld8  416(%sp),%c20
+       finop                   ; ld8  408(%sp),%c21
+       finop                   ; ld8  400(%sp),%c22
+       finop                   ; ld8  392(%sp),%c23
+       finop                   ; ld8  384(%sp),%c24
+#
+# %c25 is the Enclosing Frame Pointer (EFP) -- since C doesn't
+# use nested procedures, we ignore it (leaving a gap, though)
+#
+       finop                   ; ld8 368(%sp),%c26
+       finop                   ; ld8 360(%sp),%c27
+       finop                   ; ld8 352(%sp),%c28
+       finop                   ; ld8 344(%sp),%c29
+       finop                   ; ld8 336(%sp),%c30
+#
+# IPU registers %i12-%i30
+# 
+       finop                   ; ld8 328(%sp),%i12
+       finop                   ; ld8 320(%sp),%i13
+       finop                   ; ld8 312(%sp),%i14
+       finop                   ; ld8 304(%sp),%i15
+# (gap to get alignment for ld64)
+# -- Doesn't work on version 1.1.3 of the OS
+#      finop                   ; ld64 256(%sp),%i16
+
+       finop                   ; ld8 256(%sp),%i16
+       finop                   ; ld8 248(%sp),%i17
+       finop                   ; ld8 240(%sp),%i18
+       finop                   ; ld8 232(%sp),%i19
+       finop                   ; ld8 224(%sp),%i20
+       finop                   ; ld8 216(%sp),%i21
+       finop                   ; ld8 208(%sp),%i22
+       finop                   ; ld8 200(%sp),%i23
+       finop                   ; ld8 192(%sp),%i24
+       finop                   ; ld8 184(%sp),%i25
+       finop                   ; ld8 176(%sp),%i26
+       finop                   ; ld8 168(%sp),%i27
+       finop                   ; ld8 160(%sp),%i28
+       finop                   ; ld8 152(%sp),%i29
+       finop                   ; ld8 144(%sp),%i30
+
+#
+# FPU registers don't need to be loaded, or will be loaded by an
+# enclosing scope (e.g., if this is called by qt_block).
+#
+
+#
+# Load the special registers.  We don't load the stack ptr because
+# the new stack is passed in as an argument, we don't load the EFP
+# because we don't use it, and we load the return address specially
+# off the top of the stack.
+#
+       finop                   ; ld8 0(%sp),%c14       # return addr
+       finop                   ; ld8 496(%sp),%cp
+       finop                   ; ld8 504(%sp),%fp
+
+       finop                   ; jmp 32(%c14)          # jump back to thread
+       finop                   ; movi8 512,%c5         # stack adjust
+       finop                   ; sadd8.ntr 0,%sp,%c5,%sp
+
+        .data
+       .half 0x0, 0x0, 0x7ffff000, 0x7fff8000
+qt_block:
+       .word   qt_block$TXT
+       .word   qt_error
+       .word   qt_error$TXT
+       .word   qt_blocki
+#
+# Handle&