/* * Function: handle_tick() * * At each occurrence of a tick, the OS timer will invoke * handle_tick(). */ static void handle_tick(int unused STG_UNUSED) { handleProfTick(); if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0) { ticks_to_ctxt_switch--; if (ticks_to_ctxt_switch <= 0) { ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks; contextSwitchAllCapabilities(); /* schedule a context switch */ } } /* * If we've been inactive for idleGCDelayTime (set by +RTS * -I), tell the scheduler to wake up and do a GC, to check * for threads that are deadlocked. */ switch (recent_activity) { case ACTIVITY_YES: recent_activity = ACTIVITY_MAYBE_NO; ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTime / RtsFlags.MiscFlags.tickInterval; break; case ACTIVITY_MAYBE_NO: if (ticks_to_gc == 0) { if (RtsFlags.GcFlags.doIdleGC) { recent_activity = ACTIVITY_INACTIVE; #ifdef THREADED_RTS wakeUpRts(); // The scheduler will call stopTimer() when it has done // the GC. #endif } else { recent_activity = ACTIVITY_DONE_GC; // disable timer signals (see #1623, #5991, #9105) // but only if we're not profiling (e.g. passed -h or -p RTS // flags). If we are profiling we need to keep the timer active // so that samples continue to be collected. #ifdef PROFILING if (!(RtsFlags.ProfFlags.doHeapProfile || RtsFlags.CcFlags.doCostCentres)) { stopTimer(); } #else stopTimer(); #endif } } else { ticks_to_gc--; } break; default: break; } }
/* * Function: handle_tick() * * At each occurrence of a tick, the OS timer will invoke * handle_tick(). */ static void handle_tick(int unused STG_UNUSED) { handleProfTick(); // We don't want to dilute how often timer interrupts happen...because we have very high priority // haskell land code now. Scheduler can decide to give longer timeslices if it wants to. //if (TICKS_TO_TIMER_IRQ > 0) { //ticks_to_ctxt_switch--; //if (ticks_to_ctxt_switch <= 0) { //ticks_to_ctxt_switch = TICKS_TO_TIMER_IRQ; pending_irqs |= 1; /* flag that timerHandler should be run ASAP */ //} //} #if defined(THREADED_RTS) /* * If we've been inactive for idleGCDelayTime (set by +RTS * -I), tell the scheduler to wake up and do a GC, to check * for threads that are deadlocked. */ switch (recent_activity) { case ACTIVITY_YES: recent_activity = ACTIVITY_MAYBE_NO; ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTime / RtsFlags.MiscFlags.tickInterval; break; case ACTIVITY_MAYBE_NO: if (ticks_to_gc == 0) { /* 0 ==> no idle GC */ recent_activity = ACTIVITY_DONE_GC; // disable timer signals (see #1623) stopTimer(); } else { ticks_to_gc--; if (ticks_to_gc == 0) { ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTime / RtsFlags.MiscFlags.tickInterval; recent_activity = ACTIVITY_INACTIVE; blackholes_need_checking = rtsTrue; /* hack: re-use the blackholes_need_checking flag */ wakeUpRts(); } } break; default: break; } #endif }
/* * Function: handle_tick() * * At each occurrence of a tick, the OS timer will invoke * handle_tick(). */ static void handle_tick(int unused STG_UNUSED) { handleProfTick(); if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0) { ticks_to_ctxt_switch--; if (ticks_to_ctxt_switch <= 0) { ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks; contextSwitchAllCapabilities(); /* schedule a context switch */ } } /* * If we've been inactive for idleGCDelayTime (set by +RTS * -I), tell the scheduler to wake up and do a GC, to check * for threads that are deadlocked. */ switch (recent_activity) { case ACTIVITY_YES: recent_activity = ACTIVITY_MAYBE_NO; ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTime / RtsFlags.MiscFlags.tickInterval; break; case ACTIVITY_MAYBE_NO: if (ticks_to_gc == 0) { if (RtsFlags.GcFlags.doIdleGC) { recent_activity = ACTIVITY_INACTIVE; #ifdef THREADED_RTS wakeUpRts(); // The scheduler will call stopTimer() when it has done // the GC. #endif } else { recent_activity = ACTIVITY_DONE_GC; // disable timer signals (see #1623, #5991) // but only if we're not profiling #ifndef PROFILING stopTimer(); #endif } } else { ticks_to_gc--; } break; default: break; } }