[Next] [Previous] [Up] [Top] [Contents] [Index]

11.5 Run-Time Utilities

11.5.1 Timing

The PsyScope Toolbox provides and interface to the currently loaded TIMR for PSYXs which need access to millisecond timing information. A pointer to the millisecond timer is provided, as well as routines for waiting a specified amount of time and hooking user routines onto the timer's interrupt task. theTimer

typedef struct {
	void (*connect)(Ptr attribRef,long *resolution,long **millisecs);
	void (*disconnect)(void);
	void (*start)(void);
	void (*stop)(void);
	long *millisecs;
	long resolution;
	TIMRTask *taskListHead;
	TIMRTask *taskListTail;
} Timer;

extern Timer theTimer;

The variable theTimer.milliseconds is a pointer to the current TIMRs millisecond clock. The current time in milliseconds, as seen by the Trial Manager and all run-time subsystems can be accessed via *(theTimer.milliseconds). WaitTil()

extern void WaitTil(long time_val);

The function WaitTil() simply waits until the specified absolute time. TIMR Interrupt Tasks

The PsyScope Toolbox provides a utility for attaching functions to the current TIMRs interrupt task. This is done by creating a TIMRTask structure, and adding it to theTimer's interrupt task list using AddTIMRInterruptTask(). When the task is no-longer needed, it should be removed from the task list using DelTIMRInterruptTask().

typedef struct TIMRTask{
	struct TIMRTask *next,*prev;
	void (*proc)(void *params);
	void *params;
	long period;
	long last_run_msec;
} TIMRTask;

struct TIMRTask *next,*prev; - Maniputated by the TIMR Manager; should initially be set to NULL.

void (*proc)(void *params); - The procedure to be run.

void *params; - A pointer to parameters for the procedure; this pointer will be passed in to proc.

long period; - the period in milliseconds at which this routine should repeat.

long last_run_msec; - the time at which this routine was last run; used internally by the TIMR Manager; usually initially be set to 0, but can be set to a time in the future, for delayed execution of the proc.

Each time the currently installed TIMR runs its interrupt routine, it will check the queue of interrupt tasks and for each task for which
*(theTimer.millisecs) - task.last_run_msec >= period
is TRUE, task.proc(task.params) will be called.

It is the responsibility of the PSYX which installs a TIMR interrupt task to make sure that the currently installed TIMR has sufficient resolution to be able to run the installed task properly. The temporal resolution of the installed TIMR can be found in theTimer.resolution. This field contains the frequency of the current TIMR. Thus a TIMR which updates 1000 times per second would have a resolution of 1000.

As a general rule, TIMR Interrupt Routines should be small, fast routines, which will not interfere with the normal operation of the program. They also must follow all general rules for Macintosh interrupt routines, including not moving memory, and making sure, if they use global variables, to set and restore A4.

extern void AddTIMRInterruptTask(TIMRTask *task);
extern void DelTIMRInterruptTask(TIMRTask *task);

These routine add/remove the given task to/from the TIMR Interrupt task queue. - theTimer - WaitTil() - TIMR Interrupt Tasks

PSYX Programmer's Manual - 24 AUG 95
[Next] [Previous] [Up] [Top] [Contents] [Index]

Generated with CERN WebMaker