os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacInterupt.c
Update contrib.
4 * This file contains routines that deal with the Macintosh's low level
5 * time manager. This code provides a better resolution timer than what
6 * can be provided by WaitNextEvent.
8 * Copyright (c) 1996 Sun Microsystems, Inc.
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * RCS: @(#) $Id: tclMacInterupt.c,v 1.2 1998/09/14 18:40:05 stanton Exp $
17 #include "tclMacInt.h"
19 #include <Processes.h>
23 * Data structure for timer tasks.
25 typedef struct TMInfo {
27 ProcessSerialNumber psn;
36 * Globals used within this file.
39 static TimerUPP sleepTimerProc = NULL;
40 static int interuptsInited = false;
41 static ProcessSerialNumber applicationPSN;
42 #define MAX_TIMER_ARRAY_SIZE 16
43 static TMInfo timerInfoArray[MAX_TIMER_ARRAY_SIZE];
44 static int topTimerElement = 0;
47 * Prototypes for procedures that are referenced only in this file:
51 static TMInfo * GetTMInfo(void) ONEWORDINLINE(0x2E89); /* MOVE.L A1,(SP) */
53 static void SleepTimerProc _ANSI_ARGS_((void));
54 static pascal void CleanUpExitProc _ANSI_ARGS_((void));
55 static void InitInteruptSystem _ANSI_ARGS_((void));
58 *----------------------------------------------------------------------
60 * InitInteruptSystem --
62 * Does various initialization for the functions used in this
63 * file. Sets up Universial Pricedure Pointers, installs a trap
64 * patch for ExitToShell, etc.
70 * Various initialization.
72 *----------------------------------------------------------------------
80 sleepTimerProc = NewTimerProc(SleepTimerProc);
81 GetCurrentProcess(&applicationPSN);
82 for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) {
83 timerInfoArray[i].installed = false;
87 * Install the ExitToShell patch. We use this patch instead
88 * of the Tcl exit mechanism because we need to ensure that
89 * these routines are cleaned up even if we crash or are forced
90 * to quit. There are some circumstances when the Tcl exit
91 * handlers may not fire.
94 TclMacInstallExitToShellPatch(CleanUpExitProc);
95 interuptsInited = true;
99 *----------------------------------------------------------------------
101 * TclMacStartTimer --
103 * Install a Time Manager task to wake our process up in the
104 * future. The process should get a NULL event after ms
111 * Schedules our process to wake up.
113 *----------------------------------------------------------------------
118 long ms) /* Milliseconds. */
120 TMInfo *timerInfoPtr;
122 if (!interuptsInited) {
123 InitInteruptSystem();
127 * Obtain a pointer for the timer. We only allocate up
128 * to MAX_TIMER_ARRAY_SIZE timers. If we are past that
129 * max we return NULL.
131 if (topTimerElement < MAX_TIMER_ARRAY_SIZE) {
132 timerInfoPtr = &timerInfoArray[topTimerElement];
139 * Install timer to wake process in ms milliseconds.
141 timerInfoPtr->tmTask.tmAddr = sleepTimerProc;
142 timerInfoPtr->tmTask.tmWakeUp = 0;
143 timerInfoPtr->tmTask.tmReserved = 0;
144 timerInfoPtr->psn = applicationPSN;
145 timerInfoPtr->installed = true;
147 InsTime((QElemPtr) timerInfoPtr);
148 PrimeTime((QElemPtr) timerInfoPtr, (long) ms);
150 return (void *) timerInfoPtr;
154 *----------------------------------------------------------------------
156 * TclMacRemoveTimer --
158 * Remove the timer event from the Time Manager.
164 * A scheduled timer would be removed.
166 *----------------------------------------------------------------------
171 void * timerToken) /* Token got from start timer. */
173 TMInfo *timerInfoPtr = (TMInfo *) timerToken;
175 if (timerInfoPtr == NULL) {
179 RmvTime((QElemPtr) timerInfoPtr);
180 timerInfoPtr->installed = false;
185 *----------------------------------------------------------------------
187 * TclMacTimerExpired --
189 * Check to see if the installed timer has expired.
192 * True if timer has expired, false otherwise.
197 *----------------------------------------------------------------------
202 void * timerToken) /* Our token again. */
204 TMInfo *timerInfoPtr = (TMInfo *) timerToken;
206 if ((timerInfoPtr == NULL) ||
207 !(timerInfoPtr->tmTask.qType & kTMTaskActive)) {
215 *----------------------------------------------------------------------
219 * Time proc is called by the is a callback routine placed in the
220 * system by Tcl_Sleep. The routine is called at interupt time
221 * and threrfor can not move or allocate memory. This call will
222 * schedule our process to wake up the next time the process gets
223 * around to consider running it.
229 * Schedules our process to wake up.
231 *----------------------------------------------------------------------
238 * In CFM code we can access our code directly. In 68k code that
239 * isn't based on CFM we must do a glorious hack. The function
240 * GetTMInfo is an inline assembler call that moves the pointer
241 * at A1 to the top of the stack. The Time Manager keeps the TMTask
242 * info record there before calling this call back. In order for
243 * this to work the infoPtr argument must be the *last* item on the
244 * stack. If we "piggyback" our data to the TMTask info record we
245 * can get access to the information we need. While this is really
246 * ugly - it's the way Apple recomends it be done - go figure...
250 WakeUpProcess(&applicationPSN);
254 infoPtr = GetTMInfo();
255 WakeUpProcess(&infoPtr->psn);
260 *----------------------------------------------------------------------
264 * This procedure is invoked as an exit handler when ExitToShell
265 * is called. It removes the system level timer handler if it
266 * is installed. This must be called or the Mac OS will more than
275 *----------------------------------------------------------------------
283 for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) {
284 if (timerInfoArray[i].installed) {
285 RmvTime((QElemPtr) &timerInfoArray[i]);
286 timerInfoArray[i].installed = false;