diff options
author | Jon Medhurst <tixy@linaro.org> | 2014-04-10 09:02:02 +0100 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2014-04-10 12:11:17 +0100 |
commit | 15ce78dafc08b1c5c3ec8f42070ae37160b5154c (patch) | |
tree | cdb25c6758ac3fe5ac6f9e151642a4779e2fc742 /tools/gator/daemon/Buffer.cpp | |
parent | 34d9769988397a1edf93ad1966c167591ab29e79 (diff) |
gator: Version 5.18
Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'tools/gator/daemon/Buffer.cpp')
-rw-r--r-- | tools/gator/daemon/Buffer.cpp | 259 |
1 files changed, 201 insertions, 58 deletions
diff --git a/tools/gator/daemon/Buffer.cpp b/tools/gator/daemon/Buffer.cpp index 090a71553277..93557dabed9f 100644 --- a/tools/gator/daemon/Buffer.cpp +++ b/tools/gator/daemon/Buffer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) ARM Limited 2013. All rights reserved. + * Copyright (C) ARM Limited 2013-2014. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,33 +12,60 @@ #include "Sender.h" #include "SessionData.h" -#define mask (size - 1) - -Buffer::Buffer (const int32_t core, const int32_t buftype, const int size, sem_t *const readerSem) : core(core), buftype(buftype), size(size), readPos(0), writePos(0), commitPos(0), available(true), done(false), buf(new char[size]), commitTime(gSessionData->mLiveRate), readerSem(readerSem) { - if ((size & mask) != 0) { +#define mask (mSize - 1) + +enum { + CODE_PEA = 1, + CODE_KEYS = 2, + CODE_FORMAT = 3, + CODE_MAPS = 4, + CODE_COMM = 5, +}; + +// Summary Frame Messages +enum { + MESSAGE_SUMMARY = 1, + MESSAGE_CORE_NAME = 3, +}; + +// From gator_marshaling.c +#define NEWLINE_CANARY \ + /* Unix */ \ + "1\n" \ + /* Windows */ \ + "2\r\n" \ + /* Mac OS */ \ + "3\r" \ + /* RISC OS */ \ + "4\n\r" \ + /* Add another character so the length isn't 0x0a bytes */ \ + "5" + +Buffer::Buffer(const int32_t core, const int32_t buftype, const int size, sem_t *const readerSem) : mCore(core), mBufType(buftype), mSize(size), mReadPos(0), mWritePos(0), mCommitPos(0), mAvailable(true), mIsDone(false), mBuf(new char[mSize]), mCommitTime(gSessionData->mLiveRate), mReaderSem(readerSem) { + if ((mSize & mask) != 0) { logg->logError(__FILE__, __LINE__, "Buffer size is not a power of 2"); handleException(); } frame(); } -Buffer::~Buffer () { - delete [] buf; +Buffer::~Buffer() { + delete [] mBuf; } -void Buffer::write (Sender * const sender) { +void Buffer::write(Sender *const sender) { if (!commitReady()) { return; } // determine the size of two halves - int length1 = commitPos - readPos; - char * buffer1 = buf + readPos; + int length1 = mCommitPos - mReadPos; + char *buffer1 = mBuf + mReadPos; int length2 = 0; - char * buffer2 = buf; + char *buffer2 = mBuf; if (length1 < 0) { - length1 = size - readPos; - length2 = commitPos; + length1 = mSize - mReadPos; + length2 = mCommitPos; } logg->logMessage("Sending data length1: %i length2: %i", length1, length2); @@ -53,22 +80,22 @@ void Buffer::write (Sender * const sender) { sender->writeData(buffer2, length2, RESPONSE_APC_DATA); } - readPos = commitPos; + mReadPos = mCommitPos; } -bool Buffer::commitReady () const { - return commitPos != readPos; +bool Buffer::commitReady() const { + return mCommitPos != mReadPos; } -int Buffer::bytesAvailable () const { - int filled = writePos - readPos; +int Buffer::bytesAvailable() const { + int filled = mWritePos - mReadPos; if (filled < 0) { - filled += size; + filled += mSize; } - int remaining = size - filled; + int remaining = mSize - filled; - if (available) { + if (mAvailable) { // Give some extra room; also allows space to insert the overflow error packet remaining -= 200; } else { @@ -79,58 +106,68 @@ int Buffer::bytesAvailable () const { return remaining; } -bool Buffer::checkSpace (const int bytes) { +bool Buffer::checkSpace(const int bytes) { const int remaining = bytesAvailable(); if (remaining < bytes) { - available = false; + mAvailable = false; } else { - available = true; + mAvailable = true; } - return available; + return mAvailable; +} + +int Buffer::contiguousSpaceAvailable() const { + int remaining = bytesAvailable(); + int contiguous = mSize - mWritePos; + if (remaining < contiguous) { + return remaining; + } else { + return contiguous; + } } -void Buffer::commit (const uint64_t time) { +void Buffer::commit(const uint64_t time) { // post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload const int typeLength = gSessionData->mLocalCapture ? 0 : 1; - int length = writePos - commitPos; + int length = mWritePos - mCommitPos; if (length < 0) { - length += size; + length += mSize; } length = length - typeLength - sizeof(int32_t); for (size_t byte = 0; byte < sizeof(int32_t); byte++) { - buf[(commitPos + typeLength + byte) & mask] = (length >> byte * 8) & 0xFF; + mBuf[(mCommitPos + typeLength + byte) & mask] = (length >> byte * 8) & 0xFF; } - logg->logMessage("Committing data readPos: %i writePos: %i commitPos: %i", readPos, writePos, commitPos); - commitPos = writePos; + logg->logMessage("Committing data mReadPos: %i mWritePos: %i mCommitPos: %i", mReadPos, mWritePos, mCommitPos); + mCommitPos = mWritePos; if (gSessionData->mLiveRate > 0) { - while (time > commitTime) { - commitTime += gSessionData->mLiveRate; + while (time > mCommitTime) { + mCommitTime += gSessionData->mLiveRate; } } - if (!done) { + if (!mIsDone) { frame(); } // send a notification that data is ready - sem_post(readerSem); + sem_post(mReaderSem); } -void Buffer::check (const uint64_t time) { - int filled = writePos - commitPos; +void Buffer::check(const uint64_t time) { + int filled = mWritePos - mCommitPos; if (filled < 0) { - filled += size; + filled += mSize; } - if (filled >= ((size * 3) / 4) || (gSessionData->mLiveRate > 0 && time >= commitTime)) { + if (filled >= ((mSize * 3) / 4) || (gSessionData->mLiveRate > 0 && time >= mCommitTime)) { commit(time); } } -void Buffer::packInt (int32_t x) { +void Buffer::packInt(int32_t x) { int packedBytes = 0; int more = true; while (more) { @@ -144,14 +181,14 @@ void Buffer::packInt (int32_t x) { b |= 0x80; } - buf[(writePos + packedBytes) & mask] = b; + mBuf[(mWritePos + packedBytes) & mask] = b; packedBytes++; } - writePos = (writePos + packedBytes) & mask; + mWritePos = (mWritePos + packedBytes) & mask; } -void Buffer::packInt64 (int64_t x) { +void Buffer::packInt64(int64_t x) { int packedBytes = 0; int more = true; while (more) { @@ -165,24 +202,61 @@ void Buffer::packInt64 (int64_t x) { b |= 0x80; } - buf[(writePos + packedBytes) & mask] = b; + mBuf[(mWritePos + packedBytes) & mask] = b; packedBytes++; } - writePos = (writePos + packedBytes) & mask; + mWritePos = (mWritePos + packedBytes) & mask; +} + +void Buffer::writeBytes(const void *const data, size_t count) { + size_t i; + for (i = 0; i < count; ++i) { + mBuf[(mWritePos + i) & mask] = static_cast<const char *>(data)[i]; + } + + mWritePos = (mWritePos + i) & mask; } -void Buffer::frame () { +void Buffer::writeString(const char *const str) { + const int len = strlen(str); + packInt(len); + writeBytes(str, len); +} + +void Buffer::frame() { if (!gSessionData->mLocalCapture) { packInt(RESPONSE_APC_DATA); } // Reserve space for the length - writePos += sizeof(int32_t); - packInt(buftype); - packInt(core); + mWritePos += sizeof(int32_t); + packInt(mBufType); + packInt(mCore); } -bool Buffer::eventHeader (const uint64_t curr_time) { +void Buffer::summary(const int64_t timestamp, const int64_t uptime, const int64_t monotonicDelta, const char *const uname) { + packInt(MESSAGE_SUMMARY); + writeString(NEWLINE_CANARY); + packInt64(timestamp); + packInt64(uptime); + packInt64(monotonicDelta); + writeString("uname"); + writeString(uname); + writeString(""); + check(1); +} + +void Buffer::coreName(const int core, const int cpuid, const char *const name) { + if (checkSpace(3 * MAXSIZE_PACK32 + 0x100)) { + packInt(MESSAGE_CORE_NAME); + packInt(core); + packInt(cpuid); + writeString(name); + } + check(1); +} + +bool Buffer::eventHeader(const uint64_t curr_time) { bool retval = false; if (checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) { packInt(0); // key of zero indicates a timestamp @@ -193,9 +267,9 @@ bool Buffer::eventHeader (const uint64_t curr_time) { return retval; } -bool Buffer::eventTid (const int tid) { +bool Buffer::eventTid(const int tid) { bool retval = false; - if (checkSpace(2*MAXSIZE_PACK32)) { + if (checkSpace(2 * MAXSIZE_PACK32)) { packInt(1); // key of 1 indicates a tid packInt(tid); retval = true; @@ -204,25 +278,94 @@ bool Buffer::eventTid (const int tid) { return retval; } -void Buffer::event (const int32_t key, const int32_t value) { +void Buffer::event(const int32_t key, const int32_t value) { if (checkSpace(2 * MAXSIZE_PACK32)) { packInt(key); packInt(value); } } -void Buffer::event64 (const int64_t key, const int64_t value) { +void Buffer::event64(const int64_t key, const int64_t value) { if (checkSpace(2 * MAXSIZE_PACK64)) { packInt64(key); packInt64(value); } } -void Buffer::setDone () { - done = true; +void Buffer::pea(const struct perf_event_attr *const pea, int key) { + if (checkSpace(2 * MAXSIZE_PACK32 + pea->size)) { + packInt(CODE_PEA); + writeBytes(pea, pea->size); + packInt(key); + } else { + logg->logError(__FILE__, __LINE__, "Ran out of buffer space for perf attrs"); + handleException(); + } + // Don't know the real perf time so use 1 as it will work for now + check(1); +} + +void Buffer::keys(const int count, const __u64 *const ids, const int *const keys) { + if (checkSpace(2 * MAXSIZE_PACK32 + count * (MAXSIZE_PACK32 + MAXSIZE_PACK64))) { + packInt(CODE_KEYS); + packInt(count); + for (int i = 0; i < count; ++i) { + packInt64(ids[i]); + packInt(keys[i]); + } + } else { + logg->logError(__FILE__, __LINE__, "Ran out of buffer space for perf attrs"); + handleException(); + } + check(1); +} + +void Buffer::format(const int length, const char *const format) { + if (checkSpace(MAXSIZE_PACK32 + length + 1)) { + packInt(CODE_FORMAT); + writeBytes(format, length + 1); + } else { + logg->logError(__FILE__, __LINE__, "Ran out of buffer space for perf attrs"); + handleException(); + } + check(1); +} + +void Buffer::maps(const int pid, const int tid, const char *const maps) { + const int mapsLen = strlen(maps) + 1; + if (checkSpace(3 * MAXSIZE_PACK32 + mapsLen)) { + packInt(CODE_MAPS); + packInt(pid); + packInt(tid); + writeBytes(maps, mapsLen); + } else { + logg->logError(__FILE__, __LINE__, "Ran out of buffer space for perf attrs"); + handleException(); + } + check(1); +} + +void Buffer::comm(const int pid, const int tid, const char *const image, const char *const comm) { + const int imageLen = strlen(image) + 1; + const int commLen = strlen(comm) + 1; + if (checkSpace(3 * MAXSIZE_PACK32 + imageLen + commLen)) { + packInt(CODE_COMM); + packInt(pid); + packInt(tid); + writeBytes(image, imageLen); + writeBytes(comm, commLen); + } else { + logg->logError(__FILE__, __LINE__, "Ran out of buffer space for perf attrs"); + handleException(); + } + check(1); +} + +void Buffer::setDone() { + mIsDone = true; commit(0); } -bool Buffer::isDone () const { - return done && readPos == commitPos && commitPos == writePos; +bool Buffer::isDone() const { + return mIsDone && mReadPos == mCommitPos && mCommitPos == mWritePos; } |