Skip to content

Commit

Permalink
docs: add some javadoc
Browse files Browse the repository at this point in the history
  • Loading branch information
metacosm committed Feb 14, 2024
1 parent f7d6d7a commit c747b80
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package net.laprun.sustainability.power;

/**
* A power consumption measure as recorded by a sensor, recorded over a given period of time, with an ordering information
* provided by a tick. The meaning of each component measure is provided by the {@link SensorMetadata} information associated
* with the sensor.
*
* @param components an array recording the power consumption reported by each component of this sensor
* @param tick the ordinal tick associated with this measure
*/
public record SensorMeasure(double[] components, long tick) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,33 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* The metadata associated with a power-consumption recording sensor. This allows to make sense of the data sent by the power
* server by providing information about each component (e.g. CPU) recorded by the sensor during each periodical measure.
*/
public class SensorMetadata {
/**
* The information associated with a recorded component
*
* @param name the name of the component (e.g. CPU)
* @param index the index at which the measure for this component is recorded in the {@link SensorMeasure#components} array
* @param description a short textual description of what this component is about when available (for automatically
* extracted components, this might be identical to the name)
* @param isAttributed whether or not this component provides an attributed value i.e. whether the value is already computed
* for the process during a measure or, to the contrary, if the measure is done globally and the computation of the
* attributed share for each process needs to be performed. This is needed because some sensors only provide
* system-wide measures instead of on a per-process basis.
* @param unit a textual representation of the unit used for measures associated with this component (e.g. mW)
*/
public record ComponentMetadata(String name, int index, String description, boolean isAttributed, String unit) {
}

/**
* Initializes sensor metadata information
*
* @param components a map describing the metadata for each component
* @param documentation a text providing any relevant information associated with the described sensor
*/
@JsonCreator
public SensorMetadata(@JsonProperty("metadata") Map<String, ComponentMetadata> components,
@JsonProperty("documentation") String documentation) {
Expand All @@ -23,26 +46,55 @@ public SensorMetadata(@JsonProperty("metadata") Map<String, ComponentMetadata> c
@JsonProperty("documentation")
private final String documentation;

/**
* Determines whether a component with the specified name is known for this sensor
*
* @param component the name of the component
* @return {@code true} if a component with the specified name exists for the associated sensor, {@code false} otherwise
*/
public boolean exists(String component) {
return components.containsKey(component);
}

public ComponentMetadata metadataFor(String component) {
/**
* Retrieves the {@link ComponentMetadata} associated with the specified component name if it exists
*
* @param component the name of the component which metadata is to be retrieved
* @return the {@link ComponentMetadata} associated with the specified name
* @throws IllegalArgumentException if no component with the specified name is known for the associated sensor
*/
public ComponentMetadata metadataFor(String component) throws IllegalArgumentException {
final var componentMetadata = components.get(component);
if (componentMetadata == null) {
throw new IllegalArgumentException("Unknown component: " + component);
}
return componentMetadata;
}

/**
* Retrieves the number of known components for the associated sensor
*
* @return the cardinality of known components
*/
public int componentCardinality() {
return components.size();
}

/**
* Retrieves the known {@link ComponentMetadata} for the associated sensor as an unmodifiable Map keyed by the components'
* name
*
* @return an unmodifiable Map of the known {@link ComponentMetadata}
*/
public Map<String, ComponentMetadata> components() {
return Collections.unmodifiableMap(components);
}

/**
* Retrieves the documentation, if any, associated with this SensorMetadata
*
* @return the documentation relevant for the associated sensor
*/
public String documentation() {
return documentation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,62 @@

import net.laprun.sustainability.power.SensorMeasure;

/**
* A representation of ongoing {@link PowerSensor} measures.
*/
public interface Measures {
/**
* Represents an invalid or somehow missed measure.
*/
SensorMeasure missing = new SensorMeasure(new double[] { -1.0 }, -1);

/**
* Tracks the provided process identifier (pid) in the measures. For sensors that only provide system-wide measures, this
* probably won't be doing much more than track which processes are of interest to clients of the sensor.
*
* @param pid the process identifier which power consumption is supposed to be tracked
* @return a {@link RegisteredPID} recording the tracking of the specified pid by the sensor
*/
RegisteredPID register(long pid);

/**
* Unregisters the specified {@link RegisteredPID} thus signaling that clients are not interested in tracking the
* consumption of the associated process anymore
*
* @param registeredPID the {@link RegisteredPID} that was returned when the process we want to stop tracking was first
* registered
*/
void unregister(RegisteredPID registeredPID);

/**
* Retrieves the set of tracked process identifiers
*
* @return the set of tracked process identifiers
*/
Set<RegisteredPID> trackedPIDs();

/**
* Retrieves the number of tracked processes
*
* @return the number of tracked processes
*/
int numberOfTrackerPIDs();

/**
* Records the specified measure and associates it to the specified tracked process, normally called once per tick
*
* @param pid the {@link RegisteredPID} representing the tracked process with which the recorded measure needs to be
* associated
* @param sensorMeasure the {@link SensorMeasure} to be recorded
*/
void record(RegisteredPID pid, SensorMeasure sensorMeasure);

/**
* Retrieves the last recorded {@link SensorMeasure} associated with the specified {@link RegisteredPID}
*
* @param pid the tracked process identifier which measure we want to retrieve
* @return the last recorded {@link SensorMeasure} associated with the specified process or {@link #missing} if it cannot be
* retrieved for any reason
*/
SensorMeasure getOrDefault(RegisteredPID pid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,65 @@

import net.laprun.sustainability.power.SensorMetadata;

/**
* A representation of a power-consumption sensor.
*/
public interface PowerSensor {

/**
* Stops measuring power consumption
*/
default void stop() {
}

/**
* Retrieves the metadata associated with the sensor, in particular, which components are supported and how they are laid
* out in the {@link net.laprun.sustainability.power.SensorMeasure} that the sensor outputs
*
* @return the metadata associated with the sensor
*/
SensorMetadata metadata();

/**
* Whether the sensor has started measuring power consumption or not
*
* @return {@code true} if measures are ongoing, {@code false} otherwise
*/
boolean isStarted();

/**
* Starts emitting power consumption measures at the given frequency
*
* @param samplingFrequencyInMillis the number of milliseconds between emitted measures
* @throws Exception if the sensor couldn't be started for some reason
*/
void start(long samplingFrequencyInMillis) throws Exception;

/**
* Registers the provided process identifier (pid) with the sensor in case it can provide per-process measures. For sensors
* that only provide system-wide measures, this probably won't be doing much more than track which processes are of interest
* to clients of the sensor.
*
* @param pid the process identifier which power consumption is supposed to be tracked
* @return a {@link RegisteredPID} recording the tracking of the specified pid by the sensor
*/
RegisteredPID register(long pid);

/**
* Updates the ongoing {@link Measures} being recorded by this sensor for the given tick
*
* @param tick an ordinal value tracking the number of recorded measures being taken by the sensor since it started
* measuring power consumption
* @return the {@link Measures} object recording the measures this sensor has taken since it started measuring
*/
Measures update(Long tick);

/**
* Unregisters the specified {@link RegisteredPID} with this sensor thus signaling that clients are not interested in
* tracking the consumption of the associated process anymore
*
* @param registeredPID the {@link RegisteredPID} that was returned when the process we want to stop tracking was first
* registered with this sensor
*/
void unregister(RegisteredPID registeredPID);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@
import net.laprun.sustainability.power.sensors.PowerSensor;
import net.laprun.sustainability.power.sensors.RegisteredPID;

/**
* A sensor using Intel's RAPL accessed via Linux' powercap system.
*/
public class IntelRAPLSensor implements PowerSensor {
private final RAPLFile[] raplFiles;
private final SensorMetadata metadata;
private final double[] lastMeasuredSensorValues;
private long frequency;
private final SingleMeasureMeasures measures = new SingleMeasureMeasures();

/**
* Initializes the RAPL sensor
*/
public IntelRAPLSensor() {
// if we total system energy is not available, read package and DRAM if possible
// todo: check Intel doc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,36 @@
import net.laprun.sustainability.power.sensors.PowerSensor;
import net.laprun.sustainability.power.sensors.RegisteredPID;

/**
* A macOS powermetrics based {@link PowerSensor} implementation.
*/
public abstract class MacOSPowermetricsSensor implements PowerSensor {
/**
* The Central Processing Unit component name
*/
public static final String CPU = "CPU";
/**
* The Graphics Procssing Unit component name
*/
public static final String GPU = "GPU";
/**
* The Apple Neural Engine component name
*/
public static final String ANE = "ANE";
/**
* The Dynamic Random Access Memory component name
*/
@SuppressWarnings("unused")
public static final String DRAM = "DRAM";
@SuppressWarnings("unused")
public static final String DCS = "DCS";
/**
* The package component name
*/
public static final String PACKAGE = "Package";
/**
* The extracted CPU share component name, this represents the process' share of the measured power consumption
*/
public static final String CPU_SHARE = "cpuShare";

private final Measures measures = new MapMeasures();
Expand Down

0 comments on commit c747b80

Please sign in to comment.