Skip to content
This repository was archived by the owner on Mar 11, 2019. It is now read-only.

Commit 70424f6

Browse files
committed
Merge pull request #66 from Spirals-Team/fix/#54
fix(#54): Refactors the LibpfmChildSensor
2 parents 737a202 + 0a73ab8 commit 70424f6

29 files changed

+734
-355
lines changed

.travis.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
language: scala
22
scala:
3-
- 2.11.4
3+
- 2.11.6
44
script:
5-
- sbt clean coverage test
6-
before_install:
7-
- openssl aes-256-cbc -K $encrypted_48ebb0d1c0b9_key -iv $encrypted_48ebb0d1c0b9_iv
8-
-in secrets.tar.enc -out secrets.tar -d
9-
- tar xf secrets.tar
5+
- sbt clean "project powerapi-core" coverage test
106
after_success:
11-
- sbt coverageReport
12-
- sbt coverageAggregate
13-
- sbt codacyCoverage
7+
- sbt "project powerapi-core" coverageReport
8+
- sbt "project powerapi-core" codacyCoverage

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ PowerAPI is used in a variety of projects to address key challenges of GreenIT:
4141
* [Greenspector](http://greenspector.com) optimises the power consumption of software by identifying potential energy leaks in the source code.
4242

4343
## Acknowledgments
44-
We all stand on the shoulders of giants and get by with a little help from our friends. PowerAPI is written in [Scala](http://www.scala-lang.org) (version 2.11.4 under [3-clause BSD license](http://www.scala-lang.org/license.html)) and built on top of:
45-
* [Akka](http://akka.io) (version 2.3.6 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for asynchronous processing
46-
* [Typesage Config](https://github.com/typesafehub/config) (version 1.2.1 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for reading configuration files.
47-
* [Apache log4j2](http://logging.apache.org/log4j/2.x) (version 2.1 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for logging outside actors.
44+
We all stand on the shoulders of giants and get by with a little help from our friends. PowerAPI is written in [Scala](http://www.scala-lang.org) (version 2.11.6 under [3-clause BSD license](http://www.scala-lang.org/license.html)) and built on top of:
45+
* [Akka](http://akka.io) (version 2.3.11 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for asynchronous processing
46+
* [Typesafe Config](https://github.com/typesafehub/config) (version 1.2.1 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for reading configuration files.
47+
* [Apache log4j2](http://logging.apache.org/log4j/2.x) (version 2.3 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for logging outside actors.
4848
* [powerspy.scala](https://github.com/Spirals-Team/powerspy.scala) (version 1.0.1 under [AGPL license](http://www.gnu.org/licenses/agpl-3.0.html)), for using the [PowerSpy powermeter](http://www.alciom.com/en/products/powerspy2-en-gb-2.html).
49-
* [BridJ](https://code.google.com/p/bridj/) (version 0.6.2 under [3-clause BSD license](https://github.com/ochafik/nativelibs4java/blob/master/libraries/BridJ/LICENSE)), for system or C calls.
49+
* [BridJ](https://code.google.com/p/bridj/) (version 0.7.0 under [3-clause BSD license](https://github.com/ochafik/nativelibs4java/blob/master/libraries/BridJ/LICENSE)), for system or C calls.
5050
* [perfmon2](http://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree) (version 4.6.0 under [MIT license](http://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree/COPYING)), for accessing hardware performance counters.
5151
* [JFreeChart](http://www.jfree.org/jfreechart/) (version 1.0.19 under [LGPL license](https://www.gnu.org/licenses/lgpl.html)), for creation of interactive and animated charts.
5252
* [Scala IO](http://jesseeichar.github.io/scala-io-doc/0.4.3/index.html#!/overview) (version 0.4.3 under [3-clause BSD license](http://www.scala-lang.org/license.html)), for an extensions of IO.

build.sbt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name := "powerapi"
22

33
version in ThisBuild := "3.1"
44

5-
scalaVersion in ThisBuild := "2.11.4"
5+
scalaVersion in ThisBuild := "2.11.6"
66

77
scalacOptions in ThisBuild ++= Seq(
88
"-language:reflectiveCalls",
@@ -13,10 +13,8 @@ scalacOptions in ThisBuild ++= Seq(
1313

1414
// Logging
1515
libraryDependencies in ThisBuild ++= Seq(
16-
"org.apache.logging.log4j" % "log4j-api" % "2.1",
17-
"org.apache.logging.log4j" % "log4j-core" % "2.1"
16+
"org.apache.logging.log4j" % "log4j-api" % "2.3",
17+
"org.apache.logging.log4j" % "log4j-core" % "2.3"
1818
)
1919

2020
parallelExecution in (ThisBuild, Test) := false
21-
22-
codacyProjectTokenFile := Some("./codacy-token.txt")

powerapi-cli/src/main/scala/org/powerapi/app/PowerAPI.scala

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import org.powerapi.core.target.{Application, All, Process, Target}
2828
import org.powerapi.module.rapl.RAPLModule
2929
import org.powerapi.module.sigar.SigarModule
3030
import org.powerapi.reporter.{FileDisplay, JFreeChartDisplay, ConsoleDisplay}
31-
import org.powerapi.{PowerMonitoring, PowerMeter, PowerModule}
31+
import org.powerapi.{PowerMonitoring, PowerMeter}
3232
import org.powerapi.core.power._
3333
import org.powerapi.module.cpu.dvfs.CpuDvfsModule
3434
import org.powerapi.module.cpu.simple.CpuSimpleModule
@@ -66,20 +66,6 @@ object PowerAPI extends App {
6666
case _ => false
6767
}
6868

69-
implicit def modulesStrToPowerModules(str: String): Seq[PowerModule] = {
70-
(for(module <- str.split(",")) yield {
71-
module match {
72-
case "cpu-simple" => CpuSimpleModule()
73-
case "cpu-dvfs" => CpuDvfsModule()
74-
case "libpfm-core" => LibpfmCoreModule()
75-
case "libpfm-core-process" => LibpfmCoreProcessModule()
76-
case "powerspy" => PowerSpyModule()
77-
case "rapl" => RAPLModule()
78-
case "sigar" => SigarModule()
79-
}
80-
}).toSeq
81-
}
82-
8369
def validateAgg(str: String): Boolean = str match {
8470
case aggR(_*) => true
8571
case _ => false
@@ -172,9 +158,27 @@ object PowerAPI extends App {
172158
if(!System.getProperty("os.name").startsWith("Windows")) Seq("bash", "scripts/system.bash").!
173159
val (configuration, duration) = cli(List(), "3600", args.toList)
174160

161+
var libpfmHelper: Option[LibpfmHelper] = None
162+
163+
if(configuration.count(powerMeterConf => powerMeterConf('modules).toString.contains("libpfm")) != 0) {
164+
libpfmHelper = Some(new LibpfmHelper)
165+
libpfmHelper.get.init()
166+
}
167+
175168
for(powerMeterConf <- configuration) {
176-
val modules = powerMeterConf('modules).toString
177-
if(modules.contains("libpfm-core") || modules.contains("libpfm-core-process")) LibpfmHelper.init()
169+
val modulesStr = powerMeterConf('modules).toString
170+
171+
val modules = (for(module <- modulesStr.split(",")) yield {
172+
module match {
173+
case "cpu-simple" => CpuSimpleModule()
174+
case "cpu-dvfs" => CpuDvfsModule()
175+
case "libpfm-core" => LibpfmCoreModule(libpfmHelper.get)
176+
case "libpfm-core-process" => LibpfmCoreProcessModule(libpfmHelper.get)
177+
case "powerspy" => PowerSpyModule()
178+
case "rapl" => RAPLModule()
179+
case "sigar" => SigarModule()
180+
}
181+
}).toSeq
178182

179183
val powerMeter = PowerMeter.loadModule(modules: _*)
180184
powerMeters :+= powerMeter
@@ -209,8 +213,10 @@ object PowerAPI extends App {
209213

210214
Thread.sleep(duration.toInt.seconds.toMillis)
211215

212-
val isLibpfmInit = configuration.count(powerMeterConf => powerMeterConf('modules).toString.contains("libpfm-core") || powerMeterConf('modules).toString.contains("libpfm-core-process")) != 0
213-
if(isLibpfmInit) LibpfmHelper.deinit()
216+
libpfmHelper match {
217+
case Some(helper) => helper.deinit()
218+
case _ => {}
219+
}
214220
}
215221

216222
shutdownHookThread.start()

powerapi-core/build.sbt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
import SonatypeKeys._
2-
3-
sonatypeSettings
4-
51
name := "powerapi-core"
62

73
organization := "org.powerapi"
@@ -12,10 +8,10 @@ resolvers ++= Seq(
128

139
// App
1410
libraryDependencies ++= Seq(
15-
"com.typesafe.akka" %% "akka-actor" % "2.3.6",
11+
"com.typesafe.akka" %% "akka-actor" % "2.3.11",
1612
"com.typesafe" % "config" % "1.2.1",
1713
"fr.inria.powerspy" % "powerspy-core_2.11" % "1.1",
18-
"com.nativelibs4java" % "bridj" % "0.6.2",
14+
"com.nativelibs4java" % "bridj" % "0.7.0",
1915
"com.github.scala-incubator.io" %% "scala-io-core" % "0.4.3",
2016
"com.github.scala-incubator.io" %% "scala-io-file" % "0.4.3",
2117
"org.jfree" % "jfreechart" % "1.0.19",
@@ -25,8 +21,9 @@ libraryDependencies ++= Seq(
2521

2622
// Tests
2723
libraryDependencies ++= Seq(
28-
"com.typesafe.akka" %% "akka-testkit" % "2.3.6" % "test",
29-
"org.scalatest" %% "scalatest" % "2.2.2" % "test"
24+
"com.typesafe.akka" %% "akka-testkit" % "2.3.11" % "test",
25+
"org.scalatest" %% "scalatest" % "2.2.5" % "test",
26+
"org.scalamock" %% "scalamock-scalatest-support" % "3.2.2" % "test"
3027
)
3128

3229
startYear := Some(2014)

powerapi-core/lib/libpfm.jar

-133 Bytes
Binary file not shown.

powerapi-core/src/main/java/org/powerapi/module/libpfm/CUtils.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import org.bridj.BridJ;
2929
import org.bridj.CRuntime;
3030
import org.bridj.Pointer;
31-
32-
import perfmon2.libpfm.LibpfmLibrary;
3331
import perfmon2.libpfm.perf_event_attr;
3432

3533
/**
@@ -47,10 +45,10 @@ public class CUtils {
4745
/**
4846
* perf_event_open maccro (not generated correctly).
4947
*/
50-
public static int perf_event_open(Pointer<perf_event_attr> __hw, int __pid, int __cpu, int __gr, @CLong long __flags) {
51-
return syscall(LibpfmLibrary.__NR_perf_event_open, Pointer.getPeer(__hw), __pid, __cpu, __gr, __flags);
48+
public static int perf_event_open(int __nrPerfEventOpen, Pointer<perf_event_attr> __hw, int __pid, int __cpu, int __gr, @CLong long __flags) {
49+
return syscall(__nrPerfEventOpen, Pointer.getPeer(__hw), __pid, __cpu, __gr, __flags);
5250
}
53-
private native static int syscall(int __cdde, Object... varArgs1);
51+
private native static int syscall(int __code, Object... varArgs1);
5452

5553
/**
5654
* Interact with a given file descriptor. In this case, we use it to enable, disable and reset a file descriptor (so, a counter).

powerapi-core/src/main/scala/org/powerapi/module/libpfm/LibpfmCoreModule.scala

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,46 @@ import org.powerapi.module.libpfm.cycles.{LibpfmCoreCyclesFormulaConfiguration,
2828
import scala.collection.BitSet
2929
import scala.concurrent.duration.FiniteDuration
3030

31-
class LibpfmCoreModule(timeout: Timeout, topology: Map[Int, Set[Int]], configuration: BitSet, events: Set[String],
31+
class LibpfmCoreModule(libpfmHelper: LibpfmHelper, timeout: Timeout, topology: Map[Int, Set[Int]], configuration: BitSet, events: Set[String],
3232
cyclesThreadName: String, cyclesRefName: String, formulae: Map[Double, List[Double]], samplingInterval: FiniteDuration) extends PowerModule {
3333

34-
lazy val underlyingSensorsClasses = Seq((classOf[LibpfmCoreSensor], Seq(timeout, topology, configuration, events)))
34+
lazy val underlyingSensorsClasses = Seq((classOf[LibpfmCoreSensor], Seq(libpfmHelper, timeout, topology, configuration, events)))
3535
lazy val underlyingFormulaeClasses = Seq((classOf[LibpfmCoreCyclesFormula], Seq(cyclesThreadName, cyclesRefName, formulae, samplingInterval)))
3636
}
3737

3838
object LibpfmCoreModule extends LibpfmCoreSensorConfiguration with LibpfmCoreCyclesFormulaConfiguration {
39+
lazy val libpfmHelper = new LibpfmHelper
40+
3941
def apply(): LibpfmCoreModule = {
40-
new LibpfmCoreModule(timeout, topology, configuration, events, cyclesThreadName, cyclesRefName, formulae, samplingInterval)
42+
new LibpfmCoreModule(libpfmHelper, timeout, topology, configuration, events, cyclesThreadName, cyclesRefName, formulae, samplingInterval)
43+
}
44+
45+
def apply(libpfmHelper: LibpfmHelper): LibpfmCoreModule = {
46+
new LibpfmCoreModule(libpfmHelper, timeout, topology, configuration, events, cyclesThreadName, cyclesRefName, formulae, samplingInterval)
4147
}
4248
}
4349

44-
class LibpfmCoreSensorModule(timeout: Timeout, topology: Map[Int, Set[Int]], configuration: BitSet, events: Set[String]) extends PowerModule {
45-
lazy val underlyingSensorsClasses = Seq((classOf[LibpfmCoreSensor], Seq(timeout, topology, configuration, events)))
50+
class LibpfmCoreSensorModule(libpfmHelper: LibpfmHelper, timeout: Timeout, topology: Map[Int, Set[Int]], configuration: BitSet, events: Set[String]) extends PowerModule {
51+
lazy val underlyingSensorsClasses = Seq((classOf[LibpfmCoreSensor], Seq(libpfmHelper, timeout, topology, configuration, events)))
4652
lazy val underlyingFormulaeClasses = Seq()
4753
}
4854

4955
object LibpfmCoreSensorModule extends LibpfmCoreSensorConfiguration {
56+
lazy val libpfmHelper = new LibpfmHelper
57+
5058
def apply(): LibpfmCoreSensorModule = {
51-
new LibpfmCoreSensorModule(timeout, topology, configuration, events)
59+
new LibpfmCoreSensorModule(libpfmHelper, timeout, topology, configuration, events)
60+
}
61+
62+
def apply(libpfmHelper: LibpfmHelper): LibpfmCoreSensorModule = {
63+
new LibpfmCoreSensorModule(libpfmHelper, timeout, topology, configuration, events)
5264
}
5365

5466
def apply(events: Set[String]): LibpfmCoreSensorModule = {
55-
new LibpfmCoreSensorModule(timeout, topology, configuration, events)
67+
new LibpfmCoreSensorModule(libpfmHelper, timeout, topology, configuration, events)
68+
}
69+
70+
def apply(libpfmHelper: LibpfmHelper, events: Set[String]): LibpfmCoreSensorModule = {
71+
new LibpfmCoreSensorModule(libpfmHelper, timeout, topology, configuration, events)
5672
}
5773
}

powerapi-core/src/main/scala/org/powerapi/module/libpfm/LibpfmCoreProcessModule.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,21 @@ import org.powerapi.module.libpfm.cycles.{LibpfmCoreCyclesFormulaConfiguration,
2929
import scala.collection.BitSet
3030
import scala.concurrent.duration.FiniteDuration
3131

32-
class LibpfmCoreProcessModule(timeout: Timeout, topology: Map[Int, Set[Int]], configuration: BitSet, events: Set[String], inDepth: Boolean,
32+
class LibpfmCoreProcessModule(libpfmHelper: LibpfmHelper, timeout: Timeout, topology: Map[Int, Set[Int]], configuration: BitSet, events: Set[String], inDepth: Boolean,
3333
cyclesThreadName: String, cyclesRefName: String, formulae: Map[Double, List[Double]], samplingInterval: FiniteDuration) extends PowerModule {
3434

35-
lazy val underlyingSensorsClasses = Seq((classOf[LibpfmCoreProcessSensor], Seq(new LinuxHelper, timeout, topology, configuration, events, inDepth)))
35+
lazy val underlyingSensorsClasses = Seq((classOf[LibpfmCoreProcessSensor], Seq(new LinuxHelper, libpfmHelper, timeout, topology, configuration, events, inDepth)))
3636
lazy val underlyingFormulaeClasses = Seq((classOf[LibpfmCoreCyclesFormula], Seq(cyclesThreadName, cyclesRefName, formulae, samplingInterval)))
3737
}
3838

3939
object LibpfmCoreProcessModule extends LibpfmCoreProcessSensorConfiguration with LibpfmCoreCyclesFormulaConfiguration {
40+
lazy val libpfmHelper = new LibpfmHelper
41+
4042
def apply(): LibpfmCoreProcessModule = {
41-
new LibpfmCoreProcessModule(timeout, topology, configuration, events, inDepth, cyclesThreadName, cyclesRefName, formulae, samplingInterval)
43+
new LibpfmCoreProcessModule(libpfmHelper, timeout, topology, configuration, events, inDepth, cyclesThreadName, cyclesRefName, formulae, samplingInterval)
44+
}
45+
46+
def apply(libpfmHelper: LibpfmHelper): LibpfmCoreProcessModule = {
47+
new LibpfmCoreProcessModule(libpfmHelper, timeout, topology, configuration, events, inDepth, cyclesThreadName, cyclesRefName, formulae, samplingInterval)
4248
}
4349
}

0 commit comments

Comments
 (0)