[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: thread design



> We should definitely look at the LISPM stack group stuff before we commit
> to anything.  

I think Allegro's (which I've used) and Lucid's came from the LISPM
abstractions.  The Allegro manual is online.  To access it, type
/afs/cs/user/toad/bin/clman-browser (all systypes) which will start up a
browser and initially prompt you for a string.  Try "stack" or "process"
(topics produced below which see).  Commands are
M-x clman-apropos  and
M-x clman

 From these window "m" will take you to another entry (prompting with
default & completion), and "a" will do apropos again, making it easy to
jump around the manual.


>		An interesting feature of the LISPM stuff that I just
> remembered is that when you wait on a lock or hold a lock, you can say
> "why" you want the lock with some descriptive string.  

Stack-groups, processes, and locks all have a name slot; these *are* useful.


Here's the stack-group level functions in Allegro:

  mp:make-stack-group name [:preset-function fun] [:preset-arguments list]
  mp:process-stack-group process
  mp:stack-group-resume stack-group value
	  -  switch to a stack-group
  mp:stack-group-funcall stack-group value
	  -  switch to a stack group and set the resumer slot
  mp:stack-group-name stack-group
  mp:stack-group-preset stack-group function [args]*
	  -  reset a stack group and set its initial function and arguments
  mp:stack-group-resumer stack-group
	  -  get the value of the resumer slot of a stack group
  mp:stack-group-return value
	  -  resume the resumer of a stack group
  mp:stack-group-state stack-group
	  -  get the state of a stack group
  mp:symeval-in-stack-group symbol stack-group
  sys:*current-stack-group*
  sys:*current-stack-group-resumer*


Process-locks occur at a higher level.  Process-run-function is the
function I most often use; make-process-lock() creates a lock, and
with-process-lock((lock) &body) is what you usually do with them.

Here's the full list of functions:

  mp:*current-process*            mp:process-resume-hook              
  mp:make-process		  mp:process-revoke-arrest-reason     
  mp:make-process-lock		  mp:process-revoke-run-reason        
  mp:process-active-p		  mp:process-run-function             
  mp:process-add-arrest-reason	  mp:process-runnable-p               
  mp:process-add-run-reason	  mp:process-run-reasons              
  mp:process-allow-schedule	  mp:process-run-restartable-function 
  mp:process-arrest-reasons	  mp:process-sleep                    
  mp:process-disable		  mp:process-stack-group              
  mp:process-flush		  mp:process-unlock                   
  mp:process-initial-form	  mp:process-wait                     
  mp:process-initial-bindings	  mp:process-wait-args                
  mp:process-kill		  mp:process-wait-function            
  mp:process-lock		  mp:process-whostate                 
  mp:process-lock-locker	  mp:process-interrupt                
  mp:process-name		  mp:with-process-lock                
  mp:process-preset		  mp:*all-processes*                  
  mp:process-priority		  mp:process-wait-with-timeout        
  mp:process-property-list	  mp:process-enable                   
  mp:process-quantum		  mp:process-suspend-hook             
  mp:process-reset

The entry ``about-the-scheduler'' describes in more detail the relationship
between processes and stack-groups:  the scheduler process is always
running, and is responsible for resuming the stack-groups of user processes


The user interface:
 top-level commands :processes (lists processes), :kill, and when 
a keyboard interrupt is generated, the processes are listed and you select
which you want to interrupt (lisp listener is a separate process).


There are also some example programs in the manual, as well as introductory
sections (called about-multiprocessing or about-*); M-x clman<cr> followed
by "about?" will list them.

Scott says:
> The document needs to say explicitly what happens with Lispy environment
> stuff when threads get switched.  I guess special variables is the only
> thing we need to worry about.  A lot of Lisps, when they go in heavily for
> stack-groups, switch over to deep binding for specials, but we'll probably
> want to stick with shallow binding and do the wind-unwind when stack-groups
> are switched.  Even if we have an "exit this thread and don't do
> unwind-protects" option, we still need to restore the specials.

mp:process-run-function can take an :initial-bindings argument, which is an
alist of symbols and values.  Note the special
excl:*cl-default-special-bindings*, which is the default values to pass on.

By getting the thread of a process you can examine a a special, or use
process-interrupt to interrupt a process to run a function (which also
allows you to set it).


Another place to think about where these fit is with select() and signals.
I guess binding a function as a handler for a signal would be sufficient.

For fd's, it's very useful to be able to put a process into a wait state
until there is input available (this is how CLX does it; see
implementations of buffer-input-wait-default in dependent.cl.
You can also see the definitions of wait-for-input-from-server in
/afs/cs.cmu.edu/project/cmt/src/clm2.0/lisp/{lucid,excl}.lisp as an example
of how these two handle it (idomatically).  They both reference internal
undocumented functions, which you have to worm out of the companies
(``How can I do this?''  ``Oh, well, there's this function called...'').


I think this functionality (descended from the lispm) is sufficient for
just about everything that I can think of, and sticking close to this
design will allow people familiar with other lisps to transfer their skills
(and programs) easily.

If using mach cthreads makes it easy to implement the same functionality
for lisp, great. (Note that the other lisps don't assume this; probably use
timers & alarms).  From looking at threads.txt, it seems to me that all of
the above can be written in terms of the thread functions (except maybe
thread pre-empting;  having this allows access to the local specials too).

I'd even be willing to write a compatibility package using this..
er, sometime the summer.


 -todd


As for changing conditions to events, you've still left on-condition in...
Maybe another place too.