001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.adaptive.measurements.organizers;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.adaptive.controller.Controller;
017import org.jikesrvm.adaptive.database.methodsamples.MethodCountData;
018import org.jikesrvm.adaptive.measurements.RuntimeMeasurements;
019import org.jikesrvm.adaptive.measurements.listeners.MethodListener;
020import org.jikesrvm.adaptive.util.AOSLogging;
021import org.jikesrvm.scheduler.RVMThread;
022import org.jikesrvm.scheduler.SystemThread;
023import org.vmmagic.pragma.NonMoving;
024
025/**
026 * An organizer for method listener information that
027 * simply accumulates the samples into a private
028 * MethodCountData instance.
029 * <p>
030 * This organizer is used to simply gather aggregate sample data and
031 * report it.
032 */
033@NonMoving
034public final class AccumulatingMethodSampleOrganizer extends Organizer {
035
036  private MethodCountData data;
037
038  public AccumulatingMethodSampleOrganizer() {}
039
040  /**
041   * Initialization: set up data structures and sampling objects.
042   * <p>
043   * Uses either timer based sampling or counter based sampling,
044   * depending on {@link Controller#options}.
045   */
046  @Override
047  public void initialize() {
048    data = new MethodCountData();
049    new AsyncReporter().start();
050    int numSamples = Controller.options.METHOD_SAMPLE_SIZE * RVMThread.availableProcessors;
051    if (Controller.options.mlCBS()) {
052      numSamples *= VM.CBSMethodSamplesPerTick;
053    }
054    MethodListener methodListener = new MethodListener(numSamples);
055    listener = methodListener;
056    listener.setOrganizer(this);
057    if (Controller.options.mlTimer()) {
058      RuntimeMeasurements.installTimerMethodListener(methodListener);
059    } else if (Controller.options.mlCBS()) {
060      RuntimeMeasurements.installCBSMethodListener(methodListener);
061    } else {
062      if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED, "Unexpected value of method_listener_trigger");
063    }
064  }
065
066  @Override
067  void thresholdReached() {
068    AOSLogging.logger.organizerThresholdReached();
069    int numSamples = ((MethodListener) listener).getNumSamples();
070    int[] samples = ((MethodListener) listener).getSamples();
071    data.update(samples, numSamples);
072  }
073
074  @Override
075  public void report() {
076    VM.sysWrite("\nMethod sampler report");
077    if (data != null) data.report();
078  }
079  @NonMoving
080  class AsyncReporter extends SystemThread {
081    AsyncReporter() {
082      super("Async Profile Reporter");
083    }
084    @Override
085    public void run() {
086      for (;;) {
087        RVMThread.doProfileReport.waitAndCloseWithHandshake();
088        report();
089      }
090    }
091  }
092}
093