@@ -70,13 +70,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
7070/* The ID of the Sioux apple menu */
7171#define SIOUX_APPLEID 32000
7272
73- #ifndef HAVE_UNIVERSAL_HEADERS
74- #define GetResourceSizeOnDisk (x ) SizeResource(x)
75- typedef DlgHookYDProcPtr DlgHookYDUPP ;
76- #define NewDlgHookYDProc (userRoutine ) ((DlgHookYDUPP) (userRoutine))
77- typedef FileFilterYDProcPtr FileFilterYDUPP ;
78- #endif
79-
8073#include <signal.h>
8174#include <stdio.h>
8275
@@ -113,8 +106,29 @@ extern FSSpec *mfs_GetFSSpecFSSpec();
113106static int interrupted ; /* Set to true when cmd-. seen */
114107static RETSIGTYPE intcatcher Py_PROTO ((int ));
115108
116- static void PyMac_DoYield Py_PROTO ((int ));
109+ static void PyMac_DoYield Py_PROTO ((int , int ));
110+
111+ /*
112+ ** These are the real scheduling parameters that control what we check
113+ ** in the event loop, and how often we check. The values are initialized
114+ ** from pyMac_SchedParamStruct.
115+ */
116+
117+ struct real_sched_param_struct {
118+ int check_interrupt ; /* if true check for command-dot */
119+ int process_events ; /* if nonzero enable evt processing, this mask */
120+ int besocial ; /* if nonzero be a little social with CPU */
121+ unsigned long check_interval ; /* how often to check, in ticks */
122+ unsigned long bg_yield ; /* yield so long when in background */
123+ /* these are computed from previous and clock and such */
124+ int enabled ; /* check_interrupt OR process_event OR yield */
125+ unsigned long next_check ; /* when to check/yield next, in ticks */
126+ };
127+
128+ static struct real_sched_param_struct schedparams =
129+ { 1 , MAINLOOP_EVENTMASK , 1 , 15 , 15 , 1 , 0 };
117130
131+ #if 0
118132/*
119133** We attempt to be a good citizen by giving up the CPU periodically.
120134** When in the foreground we do this less often and for shorter periods
@@ -129,7 +143,7 @@ static long interval_fg = 12;
129143static long interval_bg = 6 ;
130144static long yield_fg = 1 ;
131145static long yield_bg = 2 ;
132- static long lastyield ;
146+ static unsigned long lastyield ;
133147static int in_foreground ;
134148
135149/*
@@ -138,6 +152,7 @@ static int in_foreground;
138152** when < 0, don't do any event scanning
139153*/
140154int PyMac_DoYieldEnabled = 1 ;
155+ #endif
141156
142157/*
143158** Workaround for sioux/gusi combo: set when we are exiting
@@ -189,8 +204,8 @@ void SpinCursor(short x) { /* Dummy */ }
189204static int
190205PyMac_GUSISpin (spin_msg msg , long arg )
191206{
192- static Boolean inForeground = true;
193- int maysleep ;
207+ static Boolean inForeground = true;
208+ int maxsleep = 6 ; /* 6 ticks is "normal" sleeptime */
194209
195210 if (PyMac_ConsoleIsDead ) return 0 ;
196211#if 0
@@ -200,12 +215,12 @@ PyMac_GUSISpin(spin_msg msg, long arg)
200215
201216 if (interrupted ) return -1 ;
202217
203- if ( msg == SP_AUTO_SPIN || (( msg == SP_SLEEP || msg == SP_SELECT ) && arg <= yield_fg ) )
204- maysleep = 0 ;
205- else
206- maysleep = 0 ;
218+ if ( msg == SP_AUTO_SPIN )
219+ maxsleep = 0 ;
220+ if ( msg == SP_SLEEP || msg == SP_SELECT )
221+ maxsleep = arg ;
207222
208- PyMac_DoYield (maysleep );
223+ PyMac_DoYield (maxsleep , 0 ); /* XXXX or is it safe to call python here? */
209224
210225 return 0 ;
211226}
@@ -405,26 +420,22 @@ scan_event_queue(flush)
405420int
406421PyOS_InterruptOccurred ()
407422{
408- static unsigned long nextticktime ;
409- unsigned long curticktime ;
410-
411- if (PyMac_DoYieldEnabled < 0 )
412- return 0 ;
413- curticktime = (unsigned long )LMGetTicks ();
414- if ( curticktime < nextticktime )
415- return 0 ;
416- nextticktime = curticktime + TICKCOUNT ;
417- #ifdef THINK_C
418- scan_event_queue (1 );
419- #endif
420- PyMac_Yield ();
421- if (interrupted ) {
422- interrupted = 0 ;
423- return 1 ;
423+ if (schedparams .enabled ) {
424+ if ( (unsigned long )LMGetTicks () > schedparams .next_check ) {
425+ PyMac_Yield ();
426+ schedparams .next_check = (unsigned long )LMGetTicks ()
427+ + schedparams .check_interval ;
428+ if (interrupted ) {
429+ interrupted = 0 ;
430+ return 1 ;
431+ }
432+ }
424433 }
425434 return 0 ;
426435}
427436
437+ #if 0
438+
428439/* intrpeek() is like intrcheck(), but it doesn't flush the events. The
429440** idea is that you call intrpeek() somewhere in a busy-wait loop, and return
430441** None as soon as it returns 1. The mainloop will then pick up the cmd-. soon
@@ -438,6 +449,7 @@ intrpeek()
438449#endif
439450 return interrupted ;
440451}
452+ #endif
441453
442454/* Check whether we are in the foreground */
443455int
@@ -448,9 +460,10 @@ PyMac_InForeground()
448460 ProcessSerialNumber curfg ;
449461 Boolean eq ;
450462
451- if ( inited == 0 )
463+ if ( inited == 0 ) {
452464 (void )GetCurrentProcess (& ours );
453- inited = 1 ;
465+ inited = 1 ;
466+ }
454467 if ( GetFrontProcess (& curfg ) < 0 )
455468 eq = 1 ;
456469 else if ( SameProcess (& ours , & curfg , & eq ) < 0 )
@@ -459,27 +472,19 @@ PyMac_InForeground()
459472
460473}
461474
462- /*
463- ** Set yield timeouts
464- */
465- void
466- PyMac_SetYield (long fgi , long fgy , long bgi , long bgy )
467- {
468- interval_fg = fgi ;
469- yield_fg = fgy ;
470- interval_bg = bgi ;
471- yield_bg = bgy ;
472- }
473-
474475/*
475476** Handle an event, either one found in the mainloop eventhandler or
476477** one passed back from the python program.
477478*/
478479void
479- PyMac_HandleEvent (evp )
480+ PyMac_HandleEvent (evp , maycallpython )
480481 EventRecord * evp ;
482+ int maycallpython ;
481483{
482-
484+
485+ if ( maycallpython ) {
486+ /* To be implemented */
487+ }
483488#ifdef __MWERKS__
484489 {
485490 int siouxdidit ;
@@ -503,83 +508,94 @@ PyMac_HandleEvent(evp)
503508}
504509
505510/*
506- ** Yield the CPU to other tasks.
511+ ** Yield the CPU to other tasks without processing events .
507512*/
508513static void
509- PyMac_DoYield (int maysleep )
514+ PyMac_DoYield (int maxsleep , int maycallpython )
510515{
511516 EventRecord ev ;
512- long yield ;
513- static int no_waitnextevent = -1 ;
514517 int gotone ;
518+ long latest_time_ready ;
515519
516- if ( no_waitnextevent < 0 ) {
517- no_waitnextevent = (NGetTrapAddress (_WaitNextEvent , ToolTrap ) ==
518- NGetTrapAddress (_Unimplemented , ToolTrap ));
519- }
520-
521- lastyield = TickCount ();
522- #ifndef THINK_C
523- /* Under think this has been done before in intrcheck() or intrpeek() */
524- if (PyMac_DoYieldEnabled >= 0 )
520+ /*
521+ ** First check for interrupts, if wanted.
522+ ** This sets a flag that will be picked up at an appropriate
523+ ** moment in the mainloop.
524+ */
525+ if (schedparams .check_interrupt )
525526 scan_event_queue (0 );
526- #endif
527- if (PyMac_DoYieldEnabled == 0 )
528- return ;
529-
530- in_foreground = PyMac_InForeground ();
531- if ( maysleep ) {
532- if ( in_foreground )
533- yield = yield_fg ;
534- else
535- yield = yield_bg ;
536- } else {
537- yield = 0 ;
538- }
527+
528+ /* XXXX Implementing an idle routine goes here */
539529
540- while ( 1 ) {
541- if ( no_waitnextevent ) {
530+ /*
531+ ** Check which of the eventloop cases we have:
532+ ** - process events
533+ ** - don't process events but do yield
534+ ** - do neither
535+ */
536+ if ( !schedparams .process_events ) {
537+ if ( maxsleep >= 0 ) {
542538 SystemTask ();
543- gotone = GetNextEvent (MAINLOOP_EVENTMASK , & ev );
544- } else {
545- gotone = WaitNextEvent (MAINLOOP_EVENTMASK , & ev , yield , NULL );
546- }
547- /* Get out quickly if nothing interesting is happening */
548- if ( !gotone || ev .what == nullEvent )
549- break ;
550- PyMac_HandleEvent (& ev );
539+ }
540+ } else {
541+ latest_time_ready = LMGetTicks () + maxsleep ;
542+ while ( maxsleep >= 0 ) {
543+ gotone = WaitNextEvent (schedparams .process_events , & ev , 0 /*maxsleep*/ , NULL );
544+ /* Get out quickly if nothing interesting is happening */
545+ if ( !gotone || ev .what == nullEvent )
546+ break ;
547+ PyMac_HandleEvent (& ev , maycallpython );
548+ maxsleep = latest_time_ready - LMGetTicks ();
549+ }
551550 }
552551}
553552
554553/*
555- ** Yield the CPU to other tasks if opportune
554+ ** Process events and/or yield the CPU to other tasks if opportune
556555*/
557556void
558557PyMac_Yield () {
559- long iv ;
558+ unsigned long maxsleep ;
560559
561- if ( in_foreground )
562- iv = interval_fg ;
560+ if ( PyMac_InForeground () )
561+ maxsleep = 0 ;
563562 else
564- iv = interval_bg ;
565- if ( TickCount () > lastyield + iv )
566- PyMac_DoYield (1 );
563+ maxsleep = schedparams . bg_yield ;
564+
565+ PyMac_DoYield (maxsleep , 1 );
567566}
568567
569- #ifdef USE_MACTCP
570568/*
571- ** Idle routine for busy-wait loops.
572- ** Gives up CPU, handles events and returns true if an interrupt is pending
573- ** (but not actually handled yet).
569+ ** Return current scheduler parameters
574570*/
575- int
576- PyMac_Idle ( )
571+ void
572+ PyMac_GetSchedParams ( PyMacSchedParams * sp )
577573{
578- PyMac_DoYield (1 );
579- return intrpeek ();
574+ sp -> check_interrupt = schedparams .check_interrupt ;
575+ sp -> process_events = schedparams .process_events ;
576+ sp -> besocial = schedparams .besocial ;
577+ sp -> check_interval = schedparams .check_interval / 60.0 ;
578+ sp -> bg_yield = schedparams .bg_yield / 60.0 ;
580579}
581- #endif
582580
581+ /*
582+ ** Set current scheduler parameters
583+ */
584+ void
585+ PyMac_SetSchedParams (PyMacSchedParams * sp )
586+ {
587+ schedparams .check_interrupt = sp -> check_interrupt ;
588+ schedparams .process_events = sp -> process_events ;
589+ schedparams .besocial = sp -> besocial ;
590+ schedparams .check_interval = (unsigned long )(sp -> check_interval * 60 );
591+ schedparams .bg_yield = (unsigned long )(sp -> bg_yield * 60 );
592+ if ( schedparams .check_interrupt || schedparams .process_events ||
593+ schedparams .besocial )
594+ schedparams .enabled = 1 ;
595+ else
596+ schedparams .enabled = 0 ;
597+ schedparams .next_check = 0 ; /* Check immedeately */
598+ }
583599/*
584600** Install our menu bar.
585601*/
0 commit comments