| /******************************************************************************* |
| * 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; |
| } |
| } |