#include "thread_tree.h"
#include "utils.h"
+class ReportLib;
+
extern "C" {
#define EXPORT __attribute__((visibility("default")))
CallChainEntry* entries;
};
+// Create a new instance,
+// pass the instance to the other functions below.
+ReportLib* CreateReportLib() EXPORT;
+void DestroyReportLib(ReportLib* report_lib) EXPORT;
+
// Set log severity, different levels are:
// verbose, debug, info, warning, error, fatal.
-bool SetLogSeverity(const char* log_level) EXPORT;
-bool SetSymfs(const char* symfs_dir) EXPORT;
-bool SetRecordFile(const char* record_file) EXPORT;
-void ShowIpForUnknownSymbol() EXPORT;
-
-Sample* GetNextSample() EXPORT;
-Event* GetEventOfCurrentSample() EXPORT;
-SymbolEntry* GetSymbolOfCurrentSample() EXPORT;
-CallChain* GetCallChainOfCurrentSample() EXPORT;
+bool SetLogSeverity(ReportLib* report_lib, const char* log_level) EXPORT;
+bool SetSymfs(ReportLib* report_lib, const char* symfs_dir) EXPORT;
+bool SetRecordFile(ReportLib* report_lib, const char* record_file) EXPORT;
+void ShowIpForUnknownSymbol(ReportLib* report_lib) EXPORT;
+
+Sample* GetNextSample(ReportLib* report_lib) EXPORT;
+Event* GetEventOfCurrentSample(ReportLib* report_lib) EXPORT;
+SymbolEntry* GetSymbolOfCurrentSample(ReportLib* report_lib) EXPORT;
+CallChain* GetCallChainOfCurrentSample(ReportLib* report_lib) EXPORT;
}
struct EventAttrWithName {
: log_severity_(
new android::base::ScopedLogSeverity(android::base::INFO)),
record_filename_("perf.data"),
- update_flag_(0) {}
-
- static ReportLib& GetInstance() {
- static ReportLib lib;
- return lib;
- }
+ current_thread_(nullptr),
+ update_flag_(0)
+ {}
bool SetLogSeverity(const char* log_level);
return ¤t_callchain_;
}
-bool SetLogSeverity(const char* log_level) {
- return ReportLib::GetInstance().SetLogSeverity(log_level);
+// Exported methods working with a client created instance
+ReportLib* CreateReportLib() {
+ return new ReportLib();
}
-bool SetSymfs(const char* symfs_dir) {
- return ReportLib::GetInstance().SetSymfs(symfs_dir);
+void DestroyReportLib(ReportLib* report_lib) {
+ delete report_lib;
}
-bool SetRecordFile(const char* record_file) {
- return ReportLib::GetInstance().SetRecordFile(record_file);
+bool SetLogSeverity(ReportLib* report_lib, const char* log_level) {
+ return report_lib->SetLogSeverity(log_level);
}
-void ShowIpForUnknownSymbol() {
- return ReportLib::GetInstance().ShowIpForUnknownSymbol();
+bool SetSymfs(ReportLib* report_lib, const char* symfs_dir) {
+ return report_lib->SetSymfs(symfs_dir);
}
-Sample* GetNextSample() { return ReportLib::GetInstance().GetNextSample(); }
+bool SetRecordFile(ReportLib* report_lib, const char* record_file) {
+ return report_lib->SetRecordFile(record_file);
+}
+
+void ShowIpForUnknownSymbol(ReportLib* report_lib) {
+ return report_lib->ShowIpForUnknownSymbol();
+}
+
+Sample* GetNextSample(ReportLib* report_lib) {
+ return report_lib->GetNextSample();
+}
-Event* GetEventOfCurrentSample() {
- return ReportLib::GetInstance().GetEventOfCurrentSample();
+Event* GetEventOfCurrentSample(ReportLib* report_lib) {
+ return report_lib->GetEventOfCurrentSample();
}
-SymbolEntry* GetSymbolOfCurrentSample() {
- return ReportLib::GetInstance().GetSymbolOfCurrentSample();
+SymbolEntry* GetSymbolOfCurrentSample(ReportLib* report_lib) {
+ return report_lib->GetSymbolOfCurrentSample();
}
-CallChain* GetCallChainOfCurrentSample() {
- return ReportLib::GetInstance().GetCallChainOfCurrentSample();
+CallChain* GetCallChainOfCurrentSample(ReportLib* report_lib) {
+ return report_lib->GetCallChainOfCurrentSample();
}
_fields_ = [('nr', ct.c_uint32),
('entries', ct.POINTER(CallChainEntryStructure))]
+class ReportLibStructure(ct.Structure):
+ _fields_ = []
class ReportLib(object):
if native_lib_path is None:
native_lib_path = _get_script_path() + "/libsimpleperf_report.so"
self._lib = ct.CDLL(native_lib_path)
+ self._CreateReportLibFunc = self._lib.CreateReportLib
+ self._CreateReportLibFunc.restype = ct.POINTER(ReportLibStructure)
+ self._DestroyReportLibFunc = self._lib.DestroyReportLib
self._SetLogSeverityFunc = self._lib.SetLogSeverity
self._SetSymfsFunc = self._lib.SetSymfs
self._SetRecordFileFunc = self._lib.SetRecordFile
self._GetCallChainOfCurrentSampleFunc = self._lib.GetCallChainOfCurrentSample
self._GetCallChainOfCurrentSampleFunc.restype = ct.POINTER(
CallChainStructure)
+ self._instance = self._CreateReportLibFunc()
+ assert(not _is_null(self._instance))
+
+ def Close(self):
+ if self._instance is None:
+ return
+ self._DestroyReportLibFunc(self._instance)
+ self._instance = None
def SetLogSeverity(self, log_level='info'):
""" Set log severity of native lib, can be verbose,debug,info,error,fatal."""
- assert(self._SetLogSeverityFunc(log_level))
+ cond = self._SetLogSeverityFunc(self.getInstance(), log_level)
+ assert(cond)
def SetSymfs(self, symfs_dir):
""" Set directory used to find symbols."""
- assert(self._SetSymfsFunc(symfs_dir))
+ cond = self._SetSymfsFunc(self.getInstance(), symfs_dir)
+ assert(cond)
def SetRecordFile(self, record_file):
""" Set the path of record file, like perf.data."""
- assert(self._SetRecordFileFunc(record_file))
+ cond = self._SetRecordFileFunc(self.getInstance(), record_file)
+ assert(cond)
def ShowIpForUnknownSymbol(self):
- self._ShowIpForUnknownSymbolFunc()
+ self._ShowIpForUnknownSymbolFunc(self.getInstance())
def GetNextSample(self):
- sample = self._GetNextSampleFunc()
+ sample = self._GetNextSampleFunc(self.getInstance())
if _is_null(sample):
return None
return sample
def GetEventOfCurrentSample(self):
- event = self._GetEventOfCurrentSampleFunc()
+ event = self._GetEventOfCurrentSampleFunc(self.getInstance())
assert(not _is_null(event))
return event
def GetSymbolOfCurrentSample(self):
- symbol = self._GetSymbolOfCurrentSampleFunc()
+ symbol = self._GetSymbolOfCurrentSampleFunc(self.getInstance())
assert(not _is_null(symbol))
return symbol
def GetCallChainOfCurrentSample(self):
- callchain = self._GetCallChainOfCurrentSampleFunc()
+ callchain = self._GetCallChainOfCurrentSampleFunc(self.getInstance())
assert(not _is_null(callchain))
return callchain
+
+ def getInstance(self):
+ if self._instance is None:
+ raise Exception("Instance is Closed")
+ return self._instance