Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 100 lines (92 sloc) 2.423 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team, 1995-2005
*
* Interval timer service for profiling and pre-emptive scheduling.
*
* ---------------------------------------------------------------------------*/

/*
* The interval timer is used for profiling and for context switching in the
* threaded build.
*
* This file defines the platform-independent view of interval timing, relying
* on platform-specific services to install and run the timers.
*
*/
#include "Rts.h"
#include "RtsFlags.h"
#include "Proftimer.h"
#include "Storage.h"
#include "Schedule.h"
#include "Timer.h"
#include "Ticker.h"
#include "Capability.h"
#include "RtsSignals.h"

/* ticks left before next pre-emptive context switch */
static int ticks_to_ctxt_switch = 0;

#if defined(THREADED_RTS)
/* idle ticks left before we perform a GC */
static int ticks_to_gc = 0;
#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)
{
#ifdef PROFILING
  handleProfTick();
#endif
  if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0) {
      ticks_to_ctxt_switch--;
      if (ticks_to_ctxt_switch <= 0) {
ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks;
context_switch = 1; /* schedule a context switch */
      }
  }

#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) break; /* 0 ==> no idle GC */
      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
}

int
startTimer(void)
{
#ifdef PROFILING
  initProfTimer();
#endif

  return startTicker(RtsFlags.MiscFlags.tickInterval, handle_tick);
}

int
stopTimer(void)
{
  return stopTicker();
}
Something went wrong with that request. Please try again.