OEMCrypto Profiler - Merge of Widevine Updates
This change is a merge of the following changes: 1. Remove MultipleSessions (go/wvgerrit/16763) 2. Increase Memory Budget (go/wvgerrit/16764) 3. Fixing Possible Integer Overflow (go/wvgerrit/16765) 4. Creating Call Table (go/wvgerrit/16766) 5. Creating Call History (go/wvgerrit/16767) 6. Connecting Profiled Scope (go/wvgerrit/16768) 7. Adding Call Table Version Number (go/wvgerrit/16780) 8. Add Version Number to Call History (go/wvgerrit/16781) bug: 27157796 Change-Id: Ia3f088a1714f3f5b426fee6141daa4ea8d832cf4
This commit is contained in:
49
libwvdrmengine/cdm/profiler/include/call_history.h
Normal file
49
libwvdrmengine/cdm/profiler/include/call_history.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#ifndef WVCDM_CALL_HISTORY_H_
|
||||
#define WVCDM_CALL_HISTORY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "circular_buffer.h"
|
||||
#include "oem_functions.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
class CallHistory {
|
||||
|
||||
public:
|
||||
CallHistory();
|
||||
|
||||
void Write(
|
||||
OEM_FUNCTION fid,
|
||||
uint64_t start_time,
|
||||
uint64_t end_time,
|
||||
const uint8_t* meta_data,
|
||||
size_t meta_data_length);
|
||||
|
||||
void Read(std::vector<uint8_t>& output) const;
|
||||
|
||||
private:
|
||||
CircularBuffer buffer_;
|
||||
|
||||
uint64_t time_at_head_;
|
||||
uint64_t time_at_tail_;
|
||||
|
||||
bool RequestSpace(uint8_t num_bytes);
|
||||
|
||||
bool ReadNextEntryRealEndTime(uint64_t* output);
|
||||
|
||||
bool DropLastEntry();
|
||||
|
||||
// Read a variable length value. This is the read that matches
|
||||
// EntryWriter's WriteVLV.
|
||||
int ReadVLV(size_t offset, uint64_t* output) const;
|
||||
};
|
||||
|
||||
} // namespace oemprofiler
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif
|
||||
49
libwvdrmengine/cdm/profiler/include/call_table.h
Normal file
49
libwvdrmengine/cdm/profiler/include/call_table.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef WVCDM_PROFILER_CALL_TABLE_H_
|
||||
#define WVCDM_PROFILER_CALL_TABLE_H_
|
||||
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
class CallTable {
|
||||
public:
|
||||
class Row {
|
||||
public:
|
||||
Row();
|
||||
void Add(uint64_t sample);
|
||||
|
||||
uint64_t GetSampleSize() const;
|
||||
|
||||
uint64_t GetMin() const;
|
||||
uint64_t GetMax() const;
|
||||
|
||||
double GetMean() const;
|
||||
double GetVariance() const;
|
||||
|
||||
private:
|
||||
uint64_t min_;
|
||||
uint64_t max_;
|
||||
uint64_t sample_size_;
|
||||
double mean_;
|
||||
double variance_m_;
|
||||
double variance_s_;
|
||||
|
||||
};
|
||||
|
||||
const Row* LookUp(uint64_t row_id) const;
|
||||
|
||||
void Write(uint64_t row_id, uint64_t sample);
|
||||
|
||||
void Read(std::vector<uint8_t>& output) const;
|
||||
|
||||
private:
|
||||
std::map<uint64_t, Row> map_;
|
||||
};
|
||||
|
||||
} // namespace oemprofiler
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif
|
||||
@@ -14,26 +14,16 @@ namespace oemprofiler {
|
||||
class ProfiledScope {
|
||||
public:
|
||||
explicit ProfiledScope(OEM_FUNCTION fid);
|
||||
explicit ProfiledScope(uint32_t sid, OEM_FUNCTION fid);
|
||||
~ProfiledScope();
|
||||
|
||||
EntryWriter meta_data_;
|
||||
|
||||
// All profiling data must be assigned to a session but some oem
|
||||
// crypto calls are not associated with crypto sessions. To gather
|
||||
// those functions' data, the global session id is used. Crypto.Session
|
||||
// Ids are unsigned 32 bit integers. To use those as a profiling session
|
||||
// id but also allow for a global id that won't conflict with them,
|
||||
// we use a -1 as the a proifiling session id is a signed 64 bit integer.
|
||||
static const int64_t kGlobalSID = -1;
|
||||
|
||||
private:
|
||||
int64_t sid_;
|
||||
OEM_FUNCTION fid_;
|
||||
|
||||
uint64_t start_time_;
|
||||
|
||||
void Submit(int64_t sid, uint64_t end_time) const;
|
||||
void Submit(uint64_t end_time) const;
|
||||
uint64_t GetNowUS() const;
|
||||
|
||||
// disallow copy and assign
|
||||
|
||||
25
libwvdrmengine/cdm/profiler/include/profiler.h
Normal file
25
libwvdrmengine/cdm/profiler/include/profiler.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#ifndef WVCDM_PROFILER_H_
|
||||
#define WVCDM_PROFILER_H_
|
||||
|
||||
#include "call_table.h"
|
||||
#include "call_history.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
class Profiler {
|
||||
public:
|
||||
static CallTable& GetTable();
|
||||
static CallHistory& GetHistory();
|
||||
|
||||
private:
|
||||
static CallTable global_table_;
|
||||
static CallHistory global_history_;
|
||||
};
|
||||
|
||||
} // namespace oemprofiler
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif
|
||||
170
libwvdrmengine/cdm/profiler/src/call_history.cpp
Normal file
170
libwvdrmengine/cdm/profiler/src/call_history.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#include "call_history.h"
|
||||
|
||||
#include <log.h>
|
||||
|
||||
#include "entry_writer.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
namespace {
|
||||
const size_t kProfilingMemoryBudget = 64 * 1024; // 64 KB
|
||||
const uint8_t kOutputVersionNumber = 0x00;
|
||||
}
|
||||
|
||||
CallHistory::CallHistory() :
|
||||
buffer_(kProfilingMemoryBudget),
|
||||
time_at_head_(0),
|
||||
time_at_tail_(0) {
|
||||
|
||||
}
|
||||
|
||||
void CallHistory::Write(
|
||||
OEM_FUNCTION fid,
|
||||
uint64_t start_time,
|
||||
uint64_t end_time,
|
||||
const uint8_t* meta_data,
|
||||
size_t meta_data_length) {
|
||||
|
||||
// time_at_tail <= start_time <= end_time or else the subtraction
|
||||
// will be invalid
|
||||
if (start_time > end_time || start_time < time_at_tail_) {
|
||||
LOGE("Skipping submission. Submission has time travelled."
|
||||
"Start=%llu End=%llu Tail=%llu. Should be Tail<=Start<=End.",
|
||||
start_time, end_time, time_at_tail_);
|
||||
return;
|
||||
}
|
||||
|
||||
EntryWriter header;
|
||||
header.WriteU8(fid);
|
||||
header.WriteVLV(start_time - time_at_tail_);
|
||||
header.WriteVLV(end_time - start_time);
|
||||
|
||||
const size_t total_packet_size = header.GetSize() + meta_data_length;
|
||||
|
||||
// The max size for a VLV is 8 bytes and the max size for a entry
|
||||
// writer is 32 bytes. Normally the meta data will be packed using
|
||||
// an entry writer so the max packet size will be 64 bytes. Since the
|
||||
// packet size is encoded with a single byte, the packet must first
|
||||
// be checked to ensure it is not too large for the cast.
|
||||
if (total_packet_size <= 255 && RequestSpace(total_packet_size + 1)) {
|
||||
buffer_.AddU8(static_cast<uint8_t>(total_packet_size));
|
||||
buffer_.AddU8s(header.GetData(), header.GetSize());
|
||||
buffer_.AddU8s(meta_data, meta_data_length);
|
||||
|
||||
time_at_tail_ = end_time;
|
||||
}
|
||||
}
|
||||
|
||||
void CallHistory::Read(std::vector<uint8_t>& output) const {
|
||||
output.push_back(kOutputVersionNumber);
|
||||
|
||||
// write the starting time
|
||||
EntryWriter startingTimeWriter;
|
||||
if (-1 == startingTimeWriter.WriteVLV(time_at_head_)) {
|
||||
output.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < startingTimeWriter.GetSize(); i++) {
|
||||
output.push_back(startingTimeWriter.GetData()[i]);
|
||||
}
|
||||
|
||||
// write the whole circular buffer into the output buffer
|
||||
const size_t num_bytes = buffer_.GetUsedSpace();
|
||||
for (size_t i = 0; i < num_bytes; i++) {
|
||||
uint8_t b;
|
||||
if (buffer_.PeekU8(i, &b)) {
|
||||
output.push_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CallHistory::RequestSpace(uint8_t num_bytes) {
|
||||
// check if it is possible to make enough room
|
||||
const size_t buffer_size = buffer_.GetFreeSpace() +
|
||||
buffer_.GetUsedSpace();
|
||||
|
||||
if (num_bytes > buffer_size) {
|
||||
LOGE("Requesting more space than possible (requested = %u, max = %zu)",
|
||||
num_bytes, buffer_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
// drop entries until we have enough space
|
||||
while (num_bytes > buffer_.GetFreeSpace() && DropLastEntry());
|
||||
|
||||
return num_bytes <= buffer_.GetFreeSpace();
|
||||
}
|
||||
|
||||
bool CallHistory::ReadNextEntryRealEndTime(uint64_t* output) {
|
||||
if (output == NULL) {
|
||||
LOGE("Cannout output to null pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t initial_time_start_index = 2;
|
||||
|
||||
uint64_t initial_time;
|
||||
const int initial_time_length =
|
||||
ReadVLV(initial_time_start_index, &initial_time);
|
||||
if (initial_time_length == -1) {
|
||||
LOGE("Failed to read the start time for head entry");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t delta_time;
|
||||
const int delta_time_length = ReadVLV(
|
||||
initial_time_start_index + initial_time_length, &delta_time);
|
||||
|
||||
if (delta_time_length == -1) {
|
||||
LOGE("Failed to read the delta time for head entry");
|
||||
return false;
|
||||
}
|
||||
|
||||
*output = time_at_head_ + initial_time + delta_time;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallHistory::DropLastEntry() {
|
||||
uint8_t entry_size;
|
||||
uint64_t end_time;
|
||||
|
||||
if (buffer_.PeekU8(0, &entry_size) && ReadNextEntryRealEndTime(&end_time)) {
|
||||
// + 1 because the entry size byte needs to be removed too
|
||||
if (buffer_.Remove(entry_size + 1)) {
|
||||
time_at_head_ = end_time;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CallHistory::ReadVLV(size_t offset, uint64_t* output) const {
|
||||
uint8_t first_byte;
|
||||
if (buffer_.PeekU8(offset, &first_byte)) {
|
||||
const size_t num_bytes = (first_byte >> 5) + 1;
|
||||
|
||||
uint64_t value = first_byte & 0x1F;
|
||||
for (size_t i = 1; i < num_bytes; i++) {
|
||||
uint8_t next_byte;
|
||||
if (buffer_.PeekU8(offset + i, &next_byte)) {
|
||||
value = value << 8 | next_byte;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*output = value;
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
} // namespace oemprofiler
|
||||
|
||||
103
libwvdrmengine/cdm/profiler/src/call_table.cpp
Normal file
103
libwvdrmengine/cdm/profiler/src/call_table.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "call_table.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "entry_writer.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
namespace {
|
||||
const uint8_t kOutputVersionNumber = 0x00;
|
||||
}
|
||||
|
||||
CallTable::Row::Row() :
|
||||
min_(std::numeric_limits<uint64_t>::max()),
|
||||
max_(0),
|
||||
sample_size_(0),
|
||||
mean_(0),
|
||||
variance_m_(0),
|
||||
variance_s_(0) {
|
||||
|
||||
}
|
||||
|
||||
void CallTable::Row::Add(uint64_t value) {
|
||||
min_ = std::min(min_, value);
|
||||
max_ = std::max(max_, value);
|
||||
|
||||
mean_ = ((mean_ * sample_size_) + value) / (sample_size_ + 1.0);
|
||||
sample_size_ += 1;
|
||||
|
||||
// Welford's method for standard deviation and variance
|
||||
const double old_m = variance_m_;
|
||||
const double old_s = variance_s_;
|
||||
variance_m_ = old_m + (value - old_m) / sample_size_;
|
||||
variance_s_ = old_s + (value - variance_m_) * (value -old_m);
|
||||
}
|
||||
|
||||
uint64_t CallTable::Row::GetSampleSize() const {
|
||||
return sample_size_;
|
||||
}
|
||||
|
||||
uint64_t CallTable::Row::GetMin() const {
|
||||
return min_;
|
||||
}
|
||||
|
||||
uint64_t CallTable::Row::GetMax() const {
|
||||
return max_;
|
||||
}
|
||||
|
||||
double CallTable::Row::GetMean() const {
|
||||
return mean_;
|
||||
}
|
||||
|
||||
double CallTable::Row::GetVariance() const {
|
||||
return sample_size_ > 1 ? variance_s_ / (sample_size_ - 1) : 0;
|
||||
}
|
||||
|
||||
const CallTable::Row* CallTable::LookUp(uint64_t row_id) const {
|
||||
return map_.count(row_id) == 0 ? NULL : &map_.find(row_id)->second;
|
||||
}
|
||||
|
||||
void CallTable::Write(uint64_t row_id, uint64_t sample) {
|
||||
if (map_.count(row_id) == 0) {
|
||||
map_.insert(std::pair<uint64_t, Row>(row_id, Row()));
|
||||
}
|
||||
|
||||
map_[row_id].Add(sample);
|
||||
}
|
||||
|
||||
void CallTable::Read(std::vector<uint8_t>& output) const {
|
||||
output.push_back(kOutputVersionNumber);
|
||||
|
||||
for (std::map<uint64_t, Row>::const_iterator it = map_.begin();
|
||||
it != map_.end(); ++it) {
|
||||
|
||||
const uint64_t values_to_write[] = {
|
||||
it->first,
|
||||
it->second.GetSampleSize(),
|
||||
it->second.GetMin(),
|
||||
it->second.GetMax(),
|
||||
static_cast<uint64_t>(it->second.GetMean()),
|
||||
// get the decimal places to the one-hundredths
|
||||
static_cast<uint64_t>(it->second.GetMean() * 100) % 100,
|
||||
static_cast<uint64_t>(it->second.GetVariance()),
|
||||
// get the decimal places to the one-hundredths
|
||||
static_cast<uint64_t>(it->second.GetVariance() * 100) % 100
|
||||
};
|
||||
|
||||
const size_t kValuesToWriteSize = 8;
|
||||
|
||||
for (size_t i = 0; i < kValuesToWriteSize; i++) {
|
||||
EntryWriter writer;
|
||||
writer.WriteVLV(values_to_write[i]);
|
||||
|
||||
for (size_t w_i = 0; w_i < writer.GetSize(); w_i++) {
|
||||
output.push_back(writer.GetData()[w_i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace oemprofiler
|
||||
} // namespace wvcdm
|
||||
@@ -4,53 +4,31 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "profiler_session.h"
|
||||
#include "profiler.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
ProfiledScope::ProfiledScope(OEM_FUNCTION fid) :
|
||||
meta_data_(),
|
||||
sid_(kGlobalSID),
|
||||
fid_(fid),
|
||||
start_time_(GetNowUS()) {
|
||||
|
||||
}
|
||||
|
||||
// Only allow a user provided sid to be a positive integer
|
||||
// to prevent a user provided sid from conflicting with the
|
||||
// global sid
|
||||
ProfiledScope::ProfiledScope(uint32_t sid, OEM_FUNCTION fid) :
|
||||
meta_data_(),
|
||||
sid_(static_cast<int64_t>(sid)),
|
||||
fid_(fid),
|
||||
start_time_(GetNowUS()) {
|
||||
|
||||
}
|
||||
|
||||
ProfiledScope::~ProfiledScope() {
|
||||
const uint64_t end_time = GetNowUS();
|
||||
|
||||
if (sid_ != kGlobalSID) {
|
||||
Submit(sid_, end_time);
|
||||
}
|
||||
|
||||
// Always save a copy to the global session so that all other sessions
|
||||
// are subsets of the global session
|
||||
Submit(kGlobalSID, end_time);
|
||||
Submit(GetNowUS());
|
||||
}
|
||||
|
||||
void ProfiledScope::Submit(int64_t sid, uint64_t end_time) const {
|
||||
ProfilerSession* const session = ProfilerSession::Find(sid);
|
||||
void ProfiledScope::Submit(uint64_t end_time) const {
|
||||
Profiler::GetTable().Write(fid_, end_time - start_time_);
|
||||
|
||||
if (session != NULL) {
|
||||
session->Submit(
|
||||
Profiler::GetHistory().Write(
|
||||
fid_,
|
||||
start_time_,
|
||||
end_time,
|
||||
meta_data_.GetData(),
|
||||
meta_data_.GetSize());
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ProfiledScope::GetNowUS() const {
|
||||
|
||||
21
libwvdrmengine/cdm/profiler/src/profiler.cpp
Normal file
21
libwvdrmengine/cdm/profiler/src/profiler.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#include "profiler.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
CallTable Profiler::global_table_;
|
||||
CallHistory Profiler::global_history_;
|
||||
|
||||
CallTable& Profiler::GetTable() {
|
||||
return global_table_;
|
||||
}
|
||||
|
||||
CallHistory& Profiler::GetHistory() {
|
||||
return global_history_;
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
} // namespace oemprofiler
|
||||
|
||||
Reference in New Issue
Block a user