Merge "logd: enhance multiple blocking readers performance" am: 6740b9697e
am: da620dff5f
Change-Id: Iedb0d69053f553befbba411e967e3c664bd00dc0
This commit is contained in:
commit
ee56d405de
9 changed files with 57 additions and 39 deletions
16
logd/FlushCommand.cpp
Normal file → Executable file
16
logd/FlushCommand.cpp
Normal file → Executable file
|
|
@ -26,18 +26,6 @@
|
||||||
#include "LogTimes.h"
|
#include "LogTimes.h"
|
||||||
#include "LogUtils.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
|
// runSocketCommand is called once for every open client on the
|
||||||
// log reader socket. Here we manage and associated the reader
|
// log reader socket. Here we manage and associated the reader
|
||||||
// client tracking and log region locks LastLogTimes list of
|
// client tracking and log region locks LastLogTimes list of
|
||||||
|
|
@ -56,6 +44,10 @@ void FlushCommand::runSocketCommand(SocketClient* client) {
|
||||||
while (it != times.end()) {
|
while (it != times.end()) {
|
||||||
entry = (*it);
|
entry = (*it);
|
||||||
if (entry->mClient == client) {
|
if (entry->mClient == client) {
|
||||||
|
if (!entry->isWatchingMultiple(mLogMask)) {
|
||||||
|
LogTimeEntry::unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) {
|
if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) {
|
||||||
if (mReader.logbuf().isMonotonic()) {
|
if (mReader.logbuf().isMonotonic()) {
|
||||||
LogTimeEntry::unlock();
|
LogTimeEntry::unlock();
|
||||||
|
|
|
||||||
30
logd/FlushCommand.h
Normal file → Executable file
30
logd/FlushCommand.h
Normal file → Executable file
|
|
@ -29,16 +29,36 @@ class FlushCommand : public SocketClientCommand {
|
||||||
LogReader& mReader;
|
LogReader& mReader;
|
||||||
bool mNonBlock;
|
bool mNonBlock;
|
||||||
unsigned long mTail;
|
unsigned long mTail;
|
||||||
unsigned int mLogMask;
|
log_mask_t mLogMask;
|
||||||
pid_t mPid;
|
pid_t mPid;
|
||||||
log_time mStart;
|
log_time mStart;
|
||||||
uint64_t mTimeout;
|
uint64_t mTimeout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FlushCommand(LogReader& mReader, bool nonBlock = false,
|
// for opening a reader
|
||||||
unsigned long tail = -1, unsigned int logMask = -1,
|
explicit FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail,
|
||||||
pid_t pid = 0, log_time start = log_time::EPOCH,
|
log_mask_t logMask, pid_t pid, log_time start,
|
||||||
uint64_t timeout = 0);
|
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);
|
virtual void runSocketCommand(SocketClient* client);
|
||||||
|
|
||||||
static bool hasReadLogs(SocketClient* client);
|
static bool hasReadLogs(SocketClient* client);
|
||||||
|
|
|
||||||
8
logd/LogAudit.cpp
Normal file → Executable file
8
logd/LogAudit.cpp
Normal file → Executable file
|
|
@ -365,7 +365,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
|
||||||
: LOGGER_ENTRY_MAX_PAYLOAD;
|
: LOGGER_ENTRY_MAX_PAYLOAD;
|
||||||
size_t message_len = str_len + sizeof(android_log_event_string_t);
|
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
|
if (events) { // begin scope for event buffer
|
||||||
uint32_t buffer[(message_len + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
|
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
|
(message_len <= USHRT_MAX) ? (unsigned short)message_len
|
||||||
: USHRT_MAX);
|
: USHRT_MAX);
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
notify = true;
|
notify |= 1 << LOG_ID_EVENTS;
|
||||||
}
|
}
|
||||||
// end scope for event buffer
|
// end scope for event buffer
|
||||||
}
|
}
|
||||||
|
|
@ -440,7 +440,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
|
||||||
: USHRT_MAX);
|
: USHRT_MAX);
|
||||||
|
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
notify = true;
|
notify |= 1 << LOG_ID_MAIN;
|
||||||
}
|
}
|
||||||
// end scope for main buffer
|
// end scope for main buffer
|
||||||
}
|
}
|
||||||
|
|
@ -449,7 +449,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
|
||||||
free(str);
|
free(str);
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
reader->notifyNewLog();
|
reader->notifyNewLog(notify);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
rc = message_len;
|
rc = message_len;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
logd/LogKlog.cpp
Normal file → Executable file
2
logd/LogKlog.cpp
Normal file → Executable file
|
|
@ -826,7 +826,7 @@ int LogKlog::log(const char* buf, ssize_t len) {
|
||||||
|
|
||||||
// notify readers
|
// notify readers
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
reader->notifyNewLog();
|
reader->notifyNewLog(static_cast<log_mask_t>(1 << LOG_ID_KERNEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
||||||
12
logd/LogListener.cpp
Normal file → Executable file
12
logd/LogListener.cpp
Normal file → Executable file
|
|
@ -94,12 +94,13 @@ bool LogListener::onDataAvailable(SocketClient* cli) {
|
||||||
|
|
||||||
android_log_header_t* header =
|
android_log_header_t* header =
|
||||||
reinterpret_cast<android_log_header_t*>(buffer);
|
reinterpret_cast<android_log_header_t*>(buffer);
|
||||||
if (/* header->id < LOG_ID_MIN || */ header->id >= LOG_ID_MAX ||
|
log_id_t logId = static_cast<log_id_t>(header->id);
|
||||||
header->id == LOG_ID_KERNEL) {
|
if (/* logId < LOG_ID_MIN || */ logId >= LOG_ID_MAX ||
|
||||||
|
logId == LOG_ID_KERNEL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((header->id == LOG_ID_SECURITY) &&
|
if ((logId == LOG_ID_SECURITY) &&
|
||||||
(!__android_log_security() ||
|
(!__android_log_security() ||
|
||||||
!clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) {
|
!clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -134,11 +135,10 @@ bool LogListener::onDataAvailable(SocketClient* cli) {
|
||||||
|
|
||||||
if (logbuf != nullptr) {
|
if (logbuf != nullptr) {
|
||||||
int res = logbuf->log(
|
int res = logbuf->log(
|
||||||
(log_id_t)header->id, header->realtime, cred->uid, cred->pid,
|
logId, header->realtime, cred->uid, cred->pid, header->tid, msg,
|
||||||
header->tid, msg,
|
|
||||||
((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
|
((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
|
||||||
if (res > 0 && reader != nullptr) {
|
if (res > 0 && reader != nullptr) {
|
||||||
reader->notifyNewLog();
|
reader->notifyNewLog(static_cast<log_mask_t>(1 << logId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
6
logd/LogReader.cpp
Normal file → Executable file
6
logd/LogReader.cpp
Normal file → Executable file
|
|
@ -35,9 +35,9 @@ LogReader::LogReader(LogBuffer* logbuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we are notified a new log entry is available, inform
|
// When we are notified a new log entry is available, inform
|
||||||
// all of our listening sockets.
|
// listening sockets who are watching this entry's log id.
|
||||||
void LogReader::notifyNewLog() {
|
void LogReader::notifyNewLog(log_mask_t logMask) {
|
||||||
FlushCommand command(*this);
|
FlushCommand command(*this, logMask);
|
||||||
runOnEachSocket(&command);
|
runOnEachSocket(&command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
logd/LogReader.h
Normal file → Executable file
4
logd/LogReader.h
Normal file → Executable file
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include <sysutils/SocketListener.h>
|
#include <sysutils/SocketListener.h>
|
||||||
|
|
||||||
|
#include "LogTimes.h"
|
||||||
|
|
||||||
#define LOGD_SNDTIMEO 32
|
#define LOGD_SNDTIMEO 32
|
||||||
|
|
||||||
class LogBuffer;
|
class LogBuffer;
|
||||||
|
|
@ -28,7 +30,7 @@ class LogReader : public SocketListener {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LogReader(LogBuffer* logbuf);
|
explicit LogReader(LogBuffer* logbuf);
|
||||||
void notifyNewLog();
|
void notifyNewLog(log_mask_t logMask);
|
||||||
|
|
||||||
LogBuffer& logbuf(void) const {
|
LogBuffer& logbuf(void) const {
|
||||||
return mLogbuf;
|
return mLogbuf;
|
||||||
|
|
|
||||||
5
logd/LogTimes.cpp
Normal file → Executable file
5
logd/LogTimes.cpp
Normal file → Executable file
|
|
@ -28,9 +28,8 @@
|
||||||
pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
|
LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
|
||||||
bool nonBlock, unsigned long tail,
|
bool nonBlock, unsigned long tail, log_mask_t logMask,
|
||||||
unsigned int logMask, pid_t pid, log_time start,
|
pid_t pid, log_time start, uint64_t timeout)
|
||||||
uint64_t timeout)
|
|
||||||
: mRefCount(1),
|
: mRefCount(1),
|
||||||
mRelease(false),
|
mRelease(false),
|
||||||
mError(false),
|
mError(false),
|
||||||
|
|
|
||||||
13
logd/LogTimes.h
Normal file → Executable file
13
logd/LogTimes.h
Normal file → Executable file
|
|
@ -26,6 +26,8 @@
|
||||||
#include <log/log.h>
|
#include <log/log.h>
|
||||||
#include <sysutils/SocketClient.h>
|
#include <sysutils/SocketClient.h>
|
||||||
|
|
||||||
|
typedef unsigned int log_mask_t;
|
||||||
|
|
||||||
class LogReader;
|
class LogReader;
|
||||||
class LogBufferElement;
|
class LogBufferElement;
|
||||||
|
|
||||||
|
|
@ -41,7 +43,7 @@ class LogTimeEntry {
|
||||||
LogReader& mReader;
|
LogReader& mReader;
|
||||||
static void* threadStart(void* me);
|
static void* threadStart(void* me);
|
||||||
static void threadStop(void* me);
|
static void threadStop(void* me);
|
||||||
const unsigned int mLogMask;
|
const log_mask_t mLogMask;
|
||||||
const pid_t mPid;
|
const pid_t mPid;
|
||||||
unsigned int skipAhead[LOG_ID_MAX];
|
unsigned int skipAhead[LOG_ID_MAX];
|
||||||
pid_t mLastTid[LOG_ID_MAX];
|
pid_t mLastTid[LOG_ID_MAX];
|
||||||
|
|
@ -51,7 +53,7 @@ class LogTimeEntry {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
|
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);
|
log_time start, uint64_t timeout);
|
||||||
|
|
||||||
SocketClient* mClient;
|
SocketClient* mClient;
|
||||||
|
|
@ -133,8 +135,11 @@ class LogTimeEntry {
|
||||||
// No one else is holding a reference to this
|
// No one else is holding a reference to this
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
bool isWatching(log_id_t id) {
|
bool isWatching(log_id_t id) const {
|
||||||
return (mLogMask & (1 << id)) != 0;
|
return mLogMask & (1 << id);
|
||||||
|
}
|
||||||
|
bool isWatchingMultiple(log_mask_t logMask) const {
|
||||||
|
return mLogMask & logMask;
|
||||||
}
|
}
|
||||||
// flushTo filter callbacks
|
// flushTo filter callbacks
|
||||||
static int FilterFirstPass(const LogBufferElement* element, void* me);
|
static int FilterFirstPass(const LogBufferElement* element, void* me);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue