os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacInterupt.c
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacInterupt.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,289 @@
1.4 +/*
1.5 + * tclMacInterupt.c --
1.6 + *
1.7 + * This file contains routines that deal with the Macintosh's low level
1.8 + * time manager. This code provides a better resolution timer than what
1.9 + * can be provided by WaitNextEvent.
1.10 + *
1.11 + * Copyright (c) 1996 Sun Microsystems, Inc.
1.12 + *
1.13 + * See the file "license.terms" for information on usage and redistribution
1.14 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
1.15 + *
1.16 + * RCS: @(#) $Id: tclMacInterupt.c,v 1.2 1998/09/14 18:40:05 stanton Exp $
1.17 + */
1.18 +
1.19 +#include "tclInt.h"
1.20 +#include "tclMacInt.h"
1.21 +#include <LowMem.h>
1.22 +#include <Processes.h>
1.23 +#include <Timer.h>
1.24 +
1.25 +/*
1.26 + * Data structure for timer tasks.
1.27 + */
1.28 +typedef struct TMInfo {
1.29 + TMTask tmTask;
1.30 + ProcessSerialNumber psn;
1.31 + Point lastPoint;
1.32 + Point newPoint;
1.33 + long currentA5;
1.34 + long ourA5;
1.35 + int installed;
1.36 +} TMInfo;
1.37 +
1.38 +/*
1.39 + * Globals used within this file.
1.40 + */
1.41 +
1.42 +static TimerUPP sleepTimerProc = NULL;
1.43 +static int interuptsInited = false;
1.44 +static ProcessSerialNumber applicationPSN;
1.45 +#define MAX_TIMER_ARRAY_SIZE 16
1.46 +static TMInfo timerInfoArray[MAX_TIMER_ARRAY_SIZE];
1.47 +static int topTimerElement = 0;
1.48 +
1.49 +/*
1.50 + * Prototypes for procedures that are referenced only in this file:
1.51 + */
1.52 +
1.53 +#if !GENERATINGCFM
1.54 +static TMInfo * GetTMInfo(void) ONEWORDINLINE(0x2E89); /* MOVE.L A1,(SP) */
1.55 +#endif
1.56 +static void SleepTimerProc _ANSI_ARGS_((void));
1.57 +static pascal void CleanUpExitProc _ANSI_ARGS_((void));
1.58 +static void InitInteruptSystem _ANSI_ARGS_((void));
1.59 +
1.60 +/*
1.61 + *----------------------------------------------------------------------
1.62 + *
1.63 + * InitInteruptSystem --
1.64 + *
1.65 + * Does various initialization for the functions used in this
1.66 + * file. Sets up Universial Pricedure Pointers, installs a trap
1.67 + * patch for ExitToShell, etc.
1.68 + *
1.69 + * Results:
1.70 + * None.
1.71 + *
1.72 + * Side effects:
1.73 + * Various initialization.
1.74 + *
1.75 + *----------------------------------------------------------------------
1.76 + */
1.77 +
1.78 +void
1.79 +InitInteruptSystem()
1.80 +{
1.81 + int i;
1.82 +
1.83 + sleepTimerProc = NewTimerProc(SleepTimerProc);
1.84 + GetCurrentProcess(&applicationPSN);
1.85 + for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) {
1.86 + timerInfoArray[i].installed = false;
1.87 + }
1.88 +
1.89 + /*
1.90 + * Install the ExitToShell patch. We use this patch instead
1.91 + * of the Tcl exit mechanism because we need to ensure that
1.92 + * these routines are cleaned up even if we crash or are forced
1.93 + * to quit. There are some circumstances when the Tcl exit
1.94 + * handlers may not fire.
1.95 + */
1.96 +
1.97 + TclMacInstallExitToShellPatch(CleanUpExitProc);
1.98 + interuptsInited = true;
1.99 +}
1.100 +
1.101 +/*
1.102 + *----------------------------------------------------------------------
1.103 + *
1.104 + * TclMacStartTimer --
1.105 + *
1.106 + * Install a Time Manager task to wake our process up in the
1.107 + * future. The process should get a NULL event after ms
1.108 + * milliseconds.
1.109 + *
1.110 + * Results:
1.111 + * None.
1.112 + *
1.113 + * Side effects:
1.114 + * Schedules our process to wake up.
1.115 + *
1.116 + *----------------------------------------------------------------------
1.117 + */
1.118 +
1.119 +void *
1.120 +TclMacStartTimer(
1.121 + long ms) /* Milliseconds. */
1.122 +{
1.123 + TMInfo *timerInfoPtr;
1.124 +
1.125 + if (!interuptsInited) {
1.126 + InitInteruptSystem();
1.127 + }
1.128 +
1.129 + /*
1.130 + * Obtain a pointer for the timer. We only allocate up
1.131 + * to MAX_TIMER_ARRAY_SIZE timers. If we are past that
1.132 + * max we return NULL.
1.133 + */
1.134 + if (topTimerElement < MAX_TIMER_ARRAY_SIZE) {
1.135 + timerInfoPtr = &timerInfoArray[topTimerElement];
1.136 + topTimerElement++;
1.137 + } else {
1.138 + return NULL;
1.139 + }
1.140 +
1.141 + /*
1.142 + * Install timer to wake process in ms milliseconds.
1.143 + */
1.144 + timerInfoPtr->tmTask.tmAddr = sleepTimerProc;
1.145 + timerInfoPtr->tmTask.tmWakeUp = 0;
1.146 + timerInfoPtr->tmTask.tmReserved = 0;
1.147 + timerInfoPtr->psn = applicationPSN;
1.148 + timerInfoPtr->installed = true;
1.149 +
1.150 + InsTime((QElemPtr) timerInfoPtr);
1.151 + PrimeTime((QElemPtr) timerInfoPtr, (long) ms);
1.152 +
1.153 + return (void *) timerInfoPtr;
1.154 +}
1.155 +
1.156 +/*
1.157 + *----------------------------------------------------------------------
1.158 + *
1.159 + * TclMacRemoveTimer --
1.160 + *
1.161 + * Remove the timer event from the Time Manager.
1.162 + *
1.163 + * Results:
1.164 + * None.
1.165 + *
1.166 + * Side effects:
1.167 + * A scheduled timer would be removed.
1.168 + *
1.169 + *----------------------------------------------------------------------
1.170 + */
1.171 +
1.172 +void
1.173 +TclMacRemoveTimer(
1.174 + void * timerToken) /* Token got from start timer. */
1.175 +{
1.176 + TMInfo *timerInfoPtr = (TMInfo *) timerToken;
1.177 +
1.178 + if (timerInfoPtr == NULL) {
1.179 + return;
1.180 + }
1.181 +
1.182 + RmvTime((QElemPtr) timerInfoPtr);
1.183 + timerInfoPtr->installed = false;
1.184 + topTimerElement--;
1.185 +}
1.186 +
1.187 +/*
1.188 + *----------------------------------------------------------------------
1.189 + *
1.190 + * TclMacTimerExpired --
1.191 + *
1.192 + * Check to see if the installed timer has expired.
1.193 + *
1.194 + * Results:
1.195 + * True if timer has expired, false otherwise.
1.196 + *
1.197 + * Side effects:
1.198 + * None.
1.199 + *
1.200 + *----------------------------------------------------------------------
1.201 + */
1.202 +
1.203 +int
1.204 +TclMacTimerExpired(
1.205 + void * timerToken) /* Our token again. */
1.206 +{
1.207 + TMInfo *timerInfoPtr = (TMInfo *) timerToken;
1.208 +
1.209 + if ((timerInfoPtr == NULL) ||
1.210 + !(timerInfoPtr->tmTask.qType & kTMTaskActive)) {
1.211 + return true;
1.212 + } else {
1.213 + return false;
1.214 + }
1.215 +}
1.216 +
1.217 +/*
1.218 + *----------------------------------------------------------------------
1.219 + *
1.220 + * SleepTimerProc --
1.221 + *
1.222 + * Time proc is called by the is a callback routine placed in the
1.223 + * system by Tcl_Sleep. The routine is called at interupt time
1.224 + * and threrfor can not move or allocate memory. This call will
1.225 + * schedule our process to wake up the next time the process gets
1.226 + * around to consider running it.
1.227 + *
1.228 + * Results:
1.229 + * None.
1.230 + *
1.231 + * Side effects:
1.232 + * Schedules our process to wake up.
1.233 + *
1.234 + *----------------------------------------------------------------------
1.235 + */
1.236 +
1.237 +static void
1.238 +SleepTimerProc()
1.239 +{
1.240 + /*
1.241 + * In CFM code we can access our code directly. In 68k code that
1.242 + * isn't based on CFM we must do a glorious hack. The function
1.243 + * GetTMInfo is an inline assembler call that moves the pointer
1.244 + * at A1 to the top of the stack. The Time Manager keeps the TMTask
1.245 + * info record there before calling this call back. In order for
1.246 + * this to work the infoPtr argument must be the *last* item on the
1.247 + * stack. If we "piggyback" our data to the TMTask info record we
1.248 + * can get access to the information we need. While this is really
1.249 + * ugly - it's the way Apple recomends it be done - go figure...
1.250 + */
1.251 +
1.252 +#if GENERATINGCFM
1.253 + WakeUpProcess(&applicationPSN);
1.254 +#else
1.255 + TMInfo * infoPtr;
1.256 +
1.257 + infoPtr = GetTMInfo();
1.258 + WakeUpProcess(&infoPtr->psn);
1.259 +#endif
1.260 +}
1.261 +
1.262 +/*
1.263 + *----------------------------------------------------------------------
1.264 + *
1.265 + * CleanUpExitProc --
1.266 + *
1.267 + * This procedure is invoked as an exit handler when ExitToShell
1.268 + * is called. It removes the system level timer handler if it
1.269 + * is installed. This must be called or the Mac OS will more than
1.270 + * likely crash.
1.271 + *
1.272 + * Results:
1.273 + * None.
1.274 + *
1.275 + * Side effects:
1.276 + * None.
1.277 + *
1.278 + *----------------------------------------------------------------------
1.279 + */
1.280 +
1.281 +static pascal void
1.282 +CleanUpExitProc()
1.283 +{
1.284 + int i;
1.285 +
1.286 + for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) {
1.287 + if (timerInfoArray[i].installed) {
1.288 + RmvTime((QElemPtr) &timerInfoArray[i]);
1.289 + timerInfoArray[i].installed = false;
1.290 + }
1.291 + }
1.292 +}