/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* ident "%Z%%M% %I% %E% SMI"
*/
/**
* This class maintains history about previous decisions. It can be
* used to ratify that a decision made on the basis of observed behavior
* over a limited time was historically shown to not degrade
* performance. The class maintains historical data in a history file.
* The format of this data is project-private and very likely to change
* as the implementation improves.
*/
/**
* The number of samples which a decision will be remembered.
*/
/**
* Map of values of historical decisions.
*/
/**
* Map of resources to be monitored for improvement in
* utilization to the corresponding decision. Maps Resources to
* their decision's key string.
*/
/**
* List of decisions, in order of creation, to manage expiry.
*/
/**
* Constructor.
*/
public DecisionHistory()
{
}
/**
* Record a decision that's been made regarding a processor.
* Such a decision is a (cpuid, from-pset-name, to-pset-name,
* (from-pset-composition), (to-pset-composition),
* original-utilization-class) tuple.
*/
{
")"));
/*
* Remember the most-recently-made decision regarding a
* resource until the next utilization sample is taken,
* so the next solve() may then reocrd the improvement.
* If another decision is made regarding this resource,
* the previous ones are forgotten, and their
* improvement fields are left 0.
*/
}
double utilization)
{
resource);
if (decisionKey != null) {
" improvement measured for decision " +
}
}
}
/**
* A Decision boils down to a tuple describing the resource
* configuration involved before and after a particular resource
* is moved. We use a textual representation to describe the
* decision, by value, to avoid holding references to any of the
* actual resources involved.
*/
/**
* Utilization of the resource before the move was made.
*/
/**
* Improvement in utilization (-1..1) after the move was
* made, if the determination is made.
*/
/**
* Number of times this decision has been reexamined.
*/
/**
* Monitor's sample count when the decision was made,
* used to expire this decision after DECISION_LIFETIME
* samples.
*/
private int startingSampleCount;
/**
* Decision's creation time.
*/
/**
* Returns a String key for this Decision.
*/
/**
* Returns a Decision corresponding to a given Move.
* @return a Decision corresponding to a given Move.
* @throws InvalidArgumentException if there is no
* Decision type corresponding to the move.
*/
double startingUtilization)
{
if (move instanceof ComponentMove)
return (new ComponentMoveDecision(
else
return (null);
}
private Decision()
{
}
/**
* Invoked after construction, sets the utilization
* corresponding to the affected resource before the move
* was made.
*/
public final void setStartingUtilization(
double startingUtilization)
{
}
/**
* Invoked after construction, sets the sampleCount from
* the monitor, used to expire this decision after
* DECISION_LIFETIME samples.
*/
{
this.startingSampleCount = sampleCount;
}
/**
* sampleCount accessor.
*/
public int getStartingSampleCount()
{
return (startingSampleCount);
}
/**
* Stores the improvement, computed in a
* subclass-specific way.
*/
abstract public void setImprovementWithNewUtilization(
double newUtilization);
/**
* Allow subclasses to record the improvement.
*/
{
this.improvement = improvement;
}
/**
* Returns the improvement in utilization measured by
* the monitor after the move is made.
*/
public final double getImprovement()
{
return (improvement);
}
/**
* Returns the utilization corresponding to the affected
* resource before the move was made.
*/
public final double getStartingUtilization()
{
return (startingUtilization);
}
public abstract int hashCode();
/**
* Number of times this decision has been reexamined.
*/
public final int getUsage()
{
return (usage);
}
private final void incrementUsage()
{
usage++;
}
/**
* Returns the time this decision was created.
*/
{
return date;
}
/**
* Formatter for printing creation date.
*/
/**
* Format for printing creation date.
*/
/**
* Returns a more comprehensive textual representation
* of this devision than toString().
*/
{
if (dateFormatter == null)
dateFormatter = new SimpleDateFormat(
return (toString() + " made at " +
" with improvement " + getImprovement() +
}
}
/**
* A Decision affecting the transfer of one CPU between
* processor sets.
*/
/**
* The CPU Id of the involved CPU.
*/
/**
* The name of the donating processor set.
*/
/**
* The name of the receiving processor set.
*/
/**
* The string representation of the list of CPU IDs
* composing the donating set.
*/
/**
* The string representation of the list of CPU IDs
* composing the receiving set.
*/
/**
* The number of CPUs in the receiving set, after the
* move is made.
*/
private int toPsetSize;
/**
* A Decision-subclass-specific utilization group.
*/
/**
* Constructs a ComponentMoveDecision based on the
* ComponentMove.
* @throws IllegalArgumentException if the ComponentMove
* can't be interpreted.
*/
double startingUtilization) throws IllegalArgumentException
{
try {
.size();
} catch (PoolsException pe) {
throw(IllegalArgumentException)(
pe));
}
}
{
}
public void setImprovementWithNewUtilization(
double newUtilization)
{
double expectedUtilization = sizeRatio *
"pset improvement calculation expected " +
}
public int hashCode() {
}
if (!(o instanceof ComponentMoveDecision))
return false;
else {
cmd.toPsetComposition) &&
}
}
/**
* Returns the group that this decision's utilization
* falls into. Presently, there is only one group, but
* ostensibly decisions will later be grouped (e.g.
* into control-zone-wide groups).
*/
double startingUtilization)
{
return "I";
}
{
}
}
/**
* Vetoes a Move only if there is a prior decision that showed a
* degradation in resource utilization.
*/
{
return true;
}
}
return false;
}
/**
* Synchronize the decision history with the persistent version.
*/
throws IOException, ClassNotFoundException
{
}
/**
* Synchronize the persistent decision history with the present
* history.
*/
{
}
/**
* Synchronize the decision history with the persistent version,
* from the given stream.
*/
throws IOException, ClassNotFoundException
{
return (dh);
}
/**
* Serialize the persistent decision history to the given
* stream.
*/
{
}
{
}
}
/**
* Measures the improvement in utilization of any resource for
* which a decision was recently made.
*/
{
/*
* Measure the improvement in resources involved in
* recent decisions.
*/
try {
double utilization = mon.
} catch (StaleMonitorException sme) {
/*
* We can't access the utilization, so
* remove the decision.
*/
if (decisionKey != null)
}
}
}
/*
* Expire decisions which have outlived
* DECISION_LIFETIME samples.
*/
if (cutoff > 0) {
if (sc > 0) {
"expiring decision (" +
decision + ")");
}
} else
break;
}
}
}
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
resourcesAwaitingImprovement = new HashMap();
decisionList = new LinkedList();
}
}
}