blob: 94909072e5f6642b49f6e2f5c3fada1324165e0a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2019 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Keith Seitz <keiths@redhat.com> - initial API and implementation
* Kent Sebastian <ksebasti@redhat.com>
*******************************************************************************/
package org.eclipse.linuxtools.internal.oprofile.core.daemon;
import java.util.HashSet;
import java.util.Set;
/**
* A class representing the unit mask that may be associated with oprofile
* events. Note that since this class was originally written, oprofile unit
* masks have changed -- a single unit mask may affect several bits at once.
* Hence, instead of a certain bit being flipped, the specific bits to be
* changed are determined by the particular mask's index
*/
public class OpUnitMask {
/**
* A class which describes an individual unit mask value. Used in XML parsing.
*/
public static class MaskInfo {
/**
* The integer value of the mask.
*/
public int value;
/**
* The name of the mask.
*/
public String name;
/**
* A description of the mask.
*/
public String description;
}
public static final int SET_DEFAULT_MASK = -1;
/**
* Invalid mask type.
*/
public static final int INVALID = -1;
/**
* The mask is mandatory. It must be used.
*/
public static final int MANDATORY = 1;
/**
* The mask is exclusive. Only one of its mask values may be used.
*/
public static final int EXCLUSIVE = 2;
/**
* The mask is a bitmask. Any combination of its values may be used.
*/
public static final int BITMASK = 3;
/**
* The current value of this unitmask
*/
private int mask;
/**
* The current name of this unitmask (EXCLUSIVE-only)
*/
private String maskName = ""; //$NON-NLS-1$
/**
* The default mask provided by the oprofile library
*/
private int defaultMask;
/**
* The type of this unitmask
*/
private int maskType;
/**
* Descriptions of the bits of this mask
*/
private String[] maskOptionDescriptions = new String[0];
/**
* mask values -- now bit masks have distinct values (eg: an all of the above)
*/
private int[] maskOptionValues;
/**
* Name of the bit mask
*/
private String[] maskOptionNames = new String[0];
/**
* Set of non-unique mask values (EXCLUSIVE type only) Some platforms allow
* multiple masks of same value and these need to be identified additionally by
* their name
*/
Set<Integer> nonUniqueValues = new HashSet<>();
/**
* Set the descriptions and values for this unitmask's mask options. Only used
* from the XML parsers.
*
* @param masks a list of all the mask options
*/
public void setMaskDescriptions(MaskInfo[] masks) {
maskOptionDescriptions = new String[masks.length];
maskOptionValues = new int[masks.length];
maskOptionNames = new String[masks.length];
Set<Integer> values = new HashSet<>();
for (int i = 0; i < masks.length; ++i) {
Integer val = Integer.valueOf(masks[i].value);
if (values.contains(Integer.valueOf(val))) {
nonUniqueValues.add(Integer.valueOf(val));
}
values.add(Integer.valueOf(val));
maskOptionDescriptions[i] = masks[i].description;
maskOptionValues[i] = masks[i].value;
maskOptionNames[i] = masks[i].name;
}
}
/**
* Sets the default value for this unitmask, and initializes the current
* unitmask value to this default. Only used from the XML parsers.
*
* @param theDefault the default value
*/
public void setDefault(int theDefault) {
defaultMask = theDefault;
setDefaultMaskValue();
}
/**
* Sets the unitmask type. Only used from the XML parsers.
*
* @param type the type
*/
public void setType(int type) {
maskType = type;
}
/**
* Returns the integer value of this unitmask, suitable for passing to oprofile.
*
* @return the integer value
*/
public int getMaskValue() {
return mask;
}
/**
* Returns the unitmask name if this is a non-unique bitmask (EXCLUSIVE-only),
* otherwise returns null.
*/
public String getMaskName() {
if (nonUniqueValues.contains(Integer.valueOf(mask))) {
return maskName;
}
return null;
}
/**
* Tests whether a particular mask is set in the unitmask value, based on the
* value of the mask option at the given index.
*
* @param index the index of the mask option to check
* @return whether the given mask option's value is set
*/
public boolean isMaskSetFromIndex(int index) {
boolean result = false;
if (index >= 0 && index < maskOptionValues.length) {
switch (maskType) {
case EXCLUSIVE:
result = (mask == maskOptionValues[index]
&& (maskName.isEmpty() || maskName.equals(maskOptionNames[index])));
break;
case BITMASK:
result = ((mask & maskOptionValues[index]) != 0);
break;
default:
result = false;
}
}
return result;
}
/**
* Sets the absolute unitmask value.
*
* @param newValue the new value of this unitmask
*/
public void setMaskValue(int newValue) {
if (newValue == SET_DEFAULT_MASK) {
mask = defaultMask;
} else {
mask = newValue;
}
}
/**
* Sets the unitmask name.
*
* @param newName the name of this unitmask
*/
public void setMaskName(String newName) {
maskName = newName;
}
/**
* Sets the bits of the given mask option's value in the unitmask value.
*
* @param index the index of the mask option to set
*/
public void setMaskFromIndex(int index) {
// mandatory masks only use the default value
if (index >= 0 && index < maskOptionValues.length) {
if (maskType == BITMASK)
mask |= maskOptionValues[index];
else if (maskType == EXCLUSIVE) {
mask = maskOptionValues[index];
maskName = maskOptionNames[index];
}
}
}
/**
* Returns the value of the mask based on the unitmask index.
*
* @param index the index of the mask option
* @return the mask option's value
*/
public int getMaskFromIndex(int index) {
// mandatory masks only use the default value
if (maskType == BITMASK) {
if (index >= 0 && index < maskOptionValues.length) {
return maskOptionValues[index];
}
} else if (maskType == EXCLUSIVE) {
if (index >= 0 && index < maskOptionValues.length) {
return maskOptionValues[index];
}
} else if (maskType == MANDATORY) {
return defaultMask;
}
// type invalid or unknown, or out of bounds
return -1;
}
/**
* Unset the bits of the given mask option's value in the unitmask value.
*
* @param index the index of the mask option to set
*/
public void unSetMaskFromIndex(int index) {
if (index >= 0 && index < maskOptionValues.length && maskType == BITMASK) {
mask = mask & ~maskOptionValues[index];
}
}
/**
* Sets the current unitmask value to the default mask value.
*/
public void setDefaultMaskValue() {
mask = defaultMask;
}
/**
* Returns a description of the requested mask option.
*
* @param num the mask option index
* @return the description
*/
public String getText(int num) {
if (num >= 0 && num < maskOptionDescriptions.length) {
return maskOptionDescriptions[num];
}
return null;
}
/**
* Returns the number of mask options in this unitmask.
*
* @return the number of mask options
*/
public int getNumMasks() {
return maskOptionDescriptions.length;
}
/**
* Returns the mask type for this unit mask.
*
* @return <code>BITMASK</code>, <code>EXCLUSIVE</code>, or
* <code>MANDATORY</code>
*/
public int getType() {
return maskType;
}
}