[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Millisecond Timing in MACL...
- To: waander@cs.UMD.EDU
- Subject: Re: Millisecond Timing in MACL...
- From: Bill St. Clair <bill>
- Date: Mon, 18 Feb 91 13:35:08 -0500
- Cc: alms, info-macl
- In-reply-to: Your message of Mon, 18 Feb 91 11:12:38 -0500. <9102181612.AA14119@cambridge.apple.com>
Date: Mon, 18 Feb 91 11:12:38 -0500
From: Andrew L. M. Shalit <alms>
To: waander@cs.UMD.EDU
Cc: info-macl
Subject: Millisecond Timing in MACL...
Date: Sun, 17 Feb 91 23:21:07 -0500
From: waander@cs.UMD.EDU (Bill Andersen)
Is there an easy way to bypass the event handling mechanism in MACL
for getting responses from a user? I'm writing some code to perform
psychology experiments and the 1 tick (16.67 ms) granularity of the
event system is not going to do the trick. Please, someone save me
from having to do some real C hacking or (God help me) assembler!!!
I want to monitor both mouse clicks and keyboard responses. Thanks
in advance...
...Bill Andersen
waander@cs.umd.edu
What makes you think the event system has a 1 tick granularity?
Granted, that's the fastest rate at which EVENT-DISPATCH will
automatically be called by the MACL preemption mechanism. But,
your program is free to sit in a loop and call EVENT-DISPATCH as
frequently as it likes.
Yes, you can do event processing more often than every 1/60 second.
This won't help you measure the elapsed time with more precision,
which I assume is what you want. It is possible to use the time
manager to measure elapsed time completely in Lisp code. You'll
probably want to insert an *EVENTHOOK* that catches mouse down and/or
key down events and tells your timing code that the desired event
happenned. For more precision (EVENT-DISPATCH lets other applications
run under MultiFinder), you'll want to use the _BUTTON trap to check
for the mouse button pushed, and the _GetKeys trap to check for key
transitions. Here's an example use of _GetKeys:
(defun key-down-p (key-code)
(multiple-value-bind (byte bit) (floor key-code 8)
(%stack-block ((p #.(/ 128 8)))
(_GetKeys :ptr p)
(logbitp bit (%get-byte p byte)))))
And here's some code showing how to use the time manager (it assumes
existence of the Revised Time Manager which made it's appearance in
Macintosh System 6.0.3):
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; time-code.lisp
;
; Example of using the time manager to measure elapsed times from Lisp
; (TIME-CODE VAR . BODY)
; will execute BODY and setq VAR to the number of elapsed microseconds
; as a side-affect. The maximum time that can be measured is about 20 minutes.
; This version doesn't account for the time required do the timing, nor
; does it run WITHOUT-INTERRUPTS.
(in-package :ccl)
(export 'time-code :ccl)
(eval-when (eval compile)
(require :traps))
(defrecord TMTask
(qLink :pointer)
(qType :integer)
(tmAddr :pointer)
(tmCount :longint)
(tmWakeUp :longint)
(tmReserved :longint)
)
; Negative time = microseconds
(defconstant *max-time* (- (ash 1 30)))
(defmacro null-ptr ()
#+ :ccl-1 0
#+ :ccl-2 `(%null-ptr))
(defmacro time-code (time-var &body body)
(let ((tmtask (gensym)))
`(rlet ((,tmtask :tmtask
:qLink (null-ptr)
:qType 0
:tmAddr (null-ptr)
:tmCount 0))
(_InsTime :errchk :a0 ,tmtask)
(_PrimeTime :errchk :a0 ,tmtask :d0 *max-time*)
(unwind-protect
(progn ,@body)
(progn
(_RmvTime :errchk :a0 ,tmtask)
(setq ,time-var (rref ,tmtask :tmtask.tmCount))
(setq ,time-var (- ,time-var *max-time*)))))))