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.mm.mmtk;
014
015import org.mmtk.utility.statistics.PerfEvent;
016import org.jikesrvm.runtime.Time;
017import static org.jikesrvm.runtime.SysCall.sysCall;
018
019import org.vmmagic.pragma.*;
020
021@Uninterruptible
022public final class Statistics extends org.mmtk.vm.Statistics {
023
024  /**
025   * Read nanoTime (high resolution, monotonically increasing clock).
026   * Has same semantics as java.lang.System.nanoTime().
027   */
028  @Override
029  public long nanoTime() {
030    return Time.nanoTime();
031  }
032
033  /**
034   * Read a cycle counter (high resolution, non-monotonic clock).
035   * This method should be used with care as the cycle counters (especially on IA32 SMP machines)
036   * are not a reliably time source.
037   */
038  @Override
039  public long cycles() {
040    return Time.cycles();
041  }
042
043  @Override
044  public double nanosToMillis(long c) {
045    return (c) / 1e6;
046  }
047
048  @Override
049  public double nanosToSecs(long c) {
050    return (c) / 1e9;
051  }
052
053  @Override
054  public long millisToNanos(double t) {
055    return (long)(t * 1e6);
056  }
057
058  @Override
059  public long secsToNanos(double t) {
060    return (long)(t * 1e9);
061  }
062
063  private PerfEvent[] perfEvents;
064
065  @Override
066  @Interruptible
067  public void perfEventInit(String events) {
068    if (events.length() == 0) {
069      // no initialization needed
070      return;
071    }
072    // initialize perf event
073    String[] perfEventNames = events.split(",");
074    int n = perfEventNames.length;
075    sysCall.sysPerfEventInit(n);
076    perfEvents = new PerfEvent[n];
077    for (int i = 0; i < n; i++) {
078      sysCall.sysPerfEventCreate(i, perfEventNames[i].concat("\0").getBytes());
079      perfEvents[i] = new PerfEvent(i, perfEventNames[i]);
080    }
081    sysCall.sysPerfEventEnable();
082  }
083
084  @Override
085  public void perfEventRead(int id, long[] values) {
086    sysCall.sysPerfEventRead(id, values);
087  }
088}
089