Package org.jnode.vm.x86.performance

Source Code of org.jnode.vm.x86.performance.DualMSRPerformanceCounters$DualMSREvent

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.x86.performance;

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;

import org.jnode.vm.performance.PerformanceCounterEvent;
import org.jnode.vm.performance.PresetEvent;
import org.jnode.vm.x86.MSR;
import org.jnode.vm.x86.VmX86Processor;
import org.jnode.vm.x86.VmX86Thread;
import org.vmmagic.pragma.UninterruptiblePragma;

/**
* Implementation of PerformanceCounters for models that implement performance
* monitoring counter using 2 MSR's per counter: a select MSR and a counter MSR.
*
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
class DualMSRPerformanceCounters extends X86PerformanceCounters {

    /**
     * Event implementation.
     *
     * @author Ewout Prangsma (epr@users.sourceforge.net)
     */
    public static class DualMSREvent extends PerformanceCounterEvent {

        /**
         * Value for the select MSR used to select this event
         */
        private final long selectValue;

        /**
         * @param id
         */
        public DualMSREvent(PresetEvent preset, long selectValue) {
            super(preset);
            this.selectValue = selectValue;
        }

        /**
         * @param id
         * @param selectValue
         */
        public DualMSREvent(PresetEvent preset, int eventMask, int unitMask) {
            this(preset, createSelectValue(eventMask, unitMask));
        }

        private static long createSelectValue(int eventMask, int unitMask) {
            long v = 0;
            v |= eventMask & 0xFF;
            v |= (unitMask & 0xFF) << 8;
            v |= 1 << 16; // USR
            v |= 1 << 22; // EN
            return v;
        }

        /**
         * @return Returns the selectValue.
         */
        public final long getSelectValue() {
            return selectValue;
        }
    }

    private final int[] countMSRIndexes;

    private final DualMSREvent[] events;

    private final Set<PerformanceCounterEvent> eventSet;

    private final int[] selectMSRIndexes;

    /**
     * @param id
     */
    public DualMSRPerformanceCounters(VmX86Processor cpu,
                                      int[] selectMSRIndexes, int[] countMSRIndexes, DualMSREvent[] events) {
        super(cpu, selectMSRIndexes.length);
        if (selectMSRIndexes.length != countMSRIndexes.length) {
            throw new IllegalArgumentException(
                "selectMSRs and countMSRs have diffent length");
        }
        this.selectMSRIndexes = selectMSRIndexes;
        this.countMSRIndexes = countMSRIndexes;
        this.events = events;
        this.eventSet = Collections
            .unmodifiableSet(new TreeSet<PerformanceCounterEvent>(Arrays
                .asList(events)));
    }

    /**
     * @see org.jnode.vm.x86.performance.X86PerformanceCounters#getAvailableEvents()
     */
    public final Set<PerformanceCounterEvent> getAvailableEvents() {
        return eventSet;
    }

    /**
     * @see org.jnode.vm.x86.performance.X86PerformanceCounters#getAvailableEvent(java.lang.String)
     */
    public final PerformanceCounterEvent getAvailableEvent(String id) {
        for (PerformanceCounterEvent e : events) {
            if (e.getId().equals(id)) {
                return e;
            }
        }
        return null;
    }

    /**
     * @see org.jnode.vm.x86.performance.X86PerformanceCounters#getCounterValues(long[])
     */
    protected final void getCounterValues(long[] counters, VmX86Thread thread)
        throws UninterruptiblePragma {
        final MSR[] countMSRs = thread.getReadWriteMSRs();
        if (countMSRs == null) {
            throw new IllegalArgumentException("No active counters");
        }
        final int cnt = counters.length;
        if (cnt > countMSRs.length) {
            throw new IllegalArgumentException("counters array is too long");
        }

        // Get the counters
        for (int i = 0; i < cnt; i++) {
            counters[i] = countMSRs[i].getValue();
        }
    }

    /**
     * @see org.jnode.vm.x86.performance.X86PerformanceCounters
     * #startCounters(org.jnode.vm.performance.PerformanceCounterEvent[])
     */
    protected final void startCounters(PerformanceCounterEvent[] events,
                                       VmX86Thread thread) throws IllegalArgumentException {
        final int cnt = events.length;
        final MSR[] countMSRs = new MSR[cnt];
        final MSR[] selectMSRs = new MSR[cnt];

        for (int i = 0; i < cnt; i++) {
            final DualMSREvent e = (DualMSREvent) events[i];
            countMSRs[i] = new MSR(this.countMSRIndexes[i]);
            selectMSRs[i] = new MSR(this.selectMSRIndexes[i], e.getSelectValue());
        }

        // Install MSR's
        thread.setMSRs(countMSRs, selectMSRs);
    }

    /**
     * @see org.jnode.vm.x86.performance.X86PerformanceCounters#stopCounters(org.jnode.vm.x86.VmX86Thread)
     */
    protected void stopCounters(VmX86Thread thread) throws IllegalArgumentException {
        final MSR[] selectMSRs = thread.getWriteOnlyMSRs();
        if (selectMSRs != null) {
            final int cnt = selectMSRs.length;
            // Reset the counter selectors
            for (int i = 0; i < cnt; i++) {
                selectMSRs[i].setValue(0);
            }
        }
    }
}
TOP

Related Classes of org.jnode.vm.x86.performance.DualMSRPerformanceCounters$DualMSREvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.