Merge "logd: enhance multiple blocking readers performance"

am: 6740b9697e

Change-Id: Iedd4096dd37d30a605fc8e92b89e5715fc0c4300
This commit is contained in:
Hao Wang 2017-12-05 19:54:23 +00:00 committed by android-build-merger
commit da620dff5f
9 changed files with 57 additions and 39 deletions

16
logd/FlushCommand.cpp Normal file → Executable file
View File

@ -26,18 +26,6 @@
#include "LogTimes.h"
#include "LogUtils.h"
FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail,
unsigned int logMask, pid_t pid, log_time start,
uint64_t timeout)
: mReader(reader),
mNonBlock(nonBlock),
mTail(tail),
mLogMask(logMask),
mPid(pid),
mStart(start),
mTimeout((start != log_time::EPOCH) ? timeout : 0) {
}
// runSocketCommand is called once for every open client on the
// log reader socket. Here we manage and associated the reader
// client tracking and log region locks LastLogTimes list of
@ -56,6 +44,10 @@ void FlushCommand::runSocketCommand(SocketClient* client) {
while (it != times.end()) {
entry = (*it);
if (entry->mClient == client) {
if (!entry->isWatchingMultiple(mLogMask)) {
LogTimeEntry::unlock();
return;
}
if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) {
if (mReader.logbuf().isMonotonic()) {
LogTimeEntry::unlock();

30
logd/FlushCommand.h Normal file → Executable file
View File

@ -29,16 +29,36 @@ class FlushCommand : public SocketClientCommand {
LogReader& mReader;
bool mNonBlock;
unsigned long mTail;
unsigned int mLogMask;
log_mask_t mLogMask;
pid_t mPid;
log_time mStart;
uint64_t mTimeout;
public:
explicit FlushCommand(LogReader& mReader, bool nonBlock = false,
unsigned long tail = -1, unsigned int logMask = -1,
pid_t pid = 0, log_time start = log_time::EPOCH,
uint64_t timeout = 0);
// for opening a reader
explicit FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail,
log_mask_t logMask, pid_t pid, log_time start,
uint64_t timeout)
: mReader(reader),
mNonBlock(nonBlock),
mTail(tail),
mLogMask(logMask),
mPid(pid),
mStart(start),
mTimeout((start != log_time::EPOCH) ? timeout : 0) {
}
// for notification of an update
explicit FlushCommand(LogReader& reader, log_mask_t logMask)
: mReader(reader),
mNonBlock(false),
mTail(-1),
mLogMask(logMask),
mPid(0),
mStart(log_time::EPOCH),
mTimeout(0) {
}
virtual void runSocketCommand(SocketClient* client);
static bool hasReadLogs(SocketClient* client);

8
logd/LogAudit.cpp Normal file → Executable file
View File

@ -365,7 +365,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
: LOGGER_ENTRY_MAX_PAYLOAD;
size_t message_len = str_len + sizeof(android_log_event_string_t);
bool notify = false;
log_mask_t notify = 0;
if (events) { // begin scope for event buffer
uint32_t buffer[(message_len + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
@ -384,7 +384,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
(message_len <= USHRT_MAX) ? (unsigned short)message_len
: USHRT_MAX);
if (rc >= 0) {
notify = true;
notify |= 1 << LOG_ID_EVENTS;
}
// end scope for event buffer
}
@ -440,7 +440,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
: USHRT_MAX);
if (rc >= 0) {
notify = true;
notify |= 1 << LOG_ID_MAIN;
}
// end scope for main buffer
}
@ -449,7 +449,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
free(str);
if (notify) {
reader->notifyNewLog();
reader->notifyNewLog(notify);
if (rc < 0) {
rc = message_len;
}

2
logd/LogKlog.cpp Normal file → Executable file
View File

@ -826,7 +826,7 @@ int LogKlog::log(const char* buf, ssize_t len) {
// notify readers
if (!rc) {
reader->notifyNewLog();
reader->notifyNewLog(static_cast<log_mask_t>(1 << LOG_ID_KERNEL));
}
return rc;

12
logd/LogListener.cpp Normal file → Executable file
View File

@ -94,12 +94,13 @@ bool LogListener::onDataAvailable(SocketClient* cli) {
android_log_header_t* header =
reinterpret_cast<android_log_header_t*>(buffer);
if (/* header->id < LOG_ID_MIN || */ header->id >= LOG_ID_MAX ||
header->id == LOG_ID_KERNEL) {
log_id_t logId = static_cast<log_id_t>(header->id);
if (/* logId < LOG_ID_MIN || */ logId >= LOG_ID_MAX ||
logId == LOG_ID_KERNEL) {
return false;
}
if ((header->id == LOG_ID_SECURITY) &&
if ((logId == LOG_ID_SECURITY) &&
(!__android_log_security() ||
!clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) {
return false;
@ -134,11 +135,10 @@ bool LogListener::onDataAvailable(SocketClient* cli) {
if (logbuf != nullptr) {
int res = logbuf->log(
(log_id_t)header->id, header->realtime, cred->uid, cred->pid,
header->tid, msg,
logId, header->realtime, cred->uid, cred->pid, header->tid, msg,
((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
if (res > 0 && reader != nullptr) {
reader->notifyNewLog();
reader->notifyNewLog(static_cast<log_mask_t>(1 << logId));
}
}

6
logd/LogReader.cpp Normal file → Executable file
View File

@ -35,9 +35,9 @@ LogReader::LogReader(LogBuffer* logbuf)
}
// When we are notified a new log entry is available, inform
// all of our listening sockets.
void LogReader::notifyNewLog() {
FlushCommand command(*this);
// listening sockets who are watching this entry's log id.
void LogReader::notifyNewLog(log_mask_t logMask) {
FlushCommand command(*this, logMask);
runOnEachSocket(&command);
}

4
logd/LogReader.h Normal file → Executable file
View File

@ -19,6 +19,8 @@
#include <sysutils/SocketListener.h>
#include "LogTimes.h"
#define LOGD_SNDTIMEO 32
class LogBuffer;
@ -28,7 +30,7 @@ class LogReader : public SocketListener {
public:
explicit LogReader(LogBuffer* logbuf);
void notifyNewLog();
void notifyNewLog(log_mask_t logMask);
LogBuffer& logbuf(void) const {
return mLogbuf;

5
logd/LogTimes.cpp Normal file → Executable file
View File

@ -28,9 +28,8 @@
pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER;
LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
bool nonBlock, unsigned long tail,
unsigned int logMask, pid_t pid, log_time start,
uint64_t timeout)
bool nonBlock, unsigned long tail, log_mask_t logMask,
pid_t pid, log_time start, uint64_t timeout)
: mRefCount(1),
mRelease(false),
mError(false),

13
logd/LogTimes.h Normal file → Executable file
View File

@ -26,6 +26,8 @@
#include <log/log.h>
#include <sysutils/SocketClient.h>
typedef unsigned int log_mask_t;
class LogReader;
class LogBufferElement;
@ -41,7 +43,7 @@ class LogTimeEntry {
LogReader& mReader;
static void* threadStart(void* me);
static void threadStop(void* me);
const unsigned int mLogMask;
const log_mask_t mLogMask;
const pid_t mPid;
unsigned int skipAhead[LOG_ID_MAX];
pid_t mLastTid[LOG_ID_MAX];
@ -51,7 +53,7 @@ class LogTimeEntry {
public:
LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
unsigned long tail, unsigned int logMask, pid_t pid,
unsigned long tail, log_mask_t logMask, pid_t pid,
log_time start, uint64_t timeout);
SocketClient* mClient;
@ -133,8 +135,11 @@ class LogTimeEntry {
// No one else is holding a reference to this
delete this;
}
bool isWatching(log_id_t id) {
return (mLogMask & (1 << id)) != 0;
bool isWatching(log_id_t id) const {
return mLogMask & (1 << id);
}
bool isWatchingMultiple(log_mask_t logMask) const {
return mLogMask & logMask;
}
// flushTo filter callbacks
static int FilterFirstPass(const LogBufferElement* element, void* me);