diff options
Diffstat (limited to 'tools/gator/daemon/PerfBuffer.cpp')
-rw-r--r-- | tools/gator/daemon/PerfBuffer.cpp | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/tools/gator/daemon/PerfBuffer.cpp b/tools/gator/daemon/PerfBuffer.cpp index 5fad583f7bd0..f127c996d43b 100644 --- a/tools/gator/daemon/PerfBuffer.cpp +++ b/tools/gator/daemon/PerfBuffer.cpp @@ -20,6 +20,7 @@ PerfBuffer::PerfBuffer() { for (int cpu = 0; cpu < ARRAY_LENGTH(mBuf); ++cpu) { mBuf[cpu] = MAP_FAILED; mDiscard[cpu] = false; + mFds[cpu] = -1; } } @@ -31,8 +32,8 @@ PerfBuffer::~PerfBuffer() { } } -bool PerfBuffer::useFd(const int cpu, const int fd, const int groupFd) { - if (fd == groupFd) { +bool PerfBuffer::useFd(const int cpu, const int fd) { + if (mFds[cpu] < 0) { if (mBuf[cpu] != MAP_FAILED) { logg->logMessage("%s(%s:%i): cpu %i already online or not correctly cleaned up", __FUNCTION__, __FILE__, __LINE__, cpu); return false; @@ -44,6 +45,7 @@ bool PerfBuffer::useFd(const int cpu, const int fd, const int groupFd) { logg->logMessage("%s(%s:%i): mmap failed", __FUNCTION__, __FILE__, __LINE__); return false; } + mFds[cpu] = fd; // Check the version struct perf_event_mmap_page *pemp = static_cast<struct perf_event_mmap_page *>(mBuf[cpu]); @@ -57,7 +59,7 @@ bool PerfBuffer::useFd(const int cpu, const int fd, const int groupFd) { return false; } - if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, groupFd) < 0) { + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, mFds[cpu]) < 0) { logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__); return false; } @@ -89,6 +91,41 @@ bool PerfBuffer::isEmpty() { return true; } +static void compressAndSend(const int cpu, const __u64 head, __u64 tail, const uint8_t *const b, Sender *const sender) { + // Pick a big size but something smaller than the chunkSize in Sender::writeData which is 100k + char buf[1<<16]; + int writePos = 0; + const int typeLength = gSessionData->mLocalCapture ? 0 : 1; + + while (head > tail) { + writePos = 0; + if (!gSessionData->mLocalCapture) { + buf[writePos++] = RESPONSE_APC_DATA; + } + // Reserve space for size + writePos += sizeof(uint32_t); + Buffer::packInt(buf, sizeof(buf), writePos, FRAME_PERF); + Buffer::packInt(buf, sizeof(buf), writePos, cpu); + + while (head > tail) { + const int count = reinterpret_cast<const struct perf_event_header *>(b + (tail & BUF_MASK))->size/sizeof(uint64_t); + // Can this whole message be written as Streamline assumes events are not split between frames + if (sizeof(buf) <= writePos + count*Buffer::MAXSIZE_PACK64) { + break; + } + for (int i = 0; i < count; ++i) { + // Must account for message size + Buffer::packInt64(buf, sizeof(buf), writePos, *reinterpret_cast<const uint64_t *>(b + (tail & BUF_MASK))); + tail += sizeof(uint64_t); + } + } + + // Write size + Buffer::writeLEInt(reinterpret_cast<unsigned char *>(buf + typeLength), writePos - typeLength - sizeof(uint32_t)); + sender->writeData(buf, writePos, RESPONSE_APC_DATA); + } +} + bool PerfBuffer::send(Sender *const sender) { for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) { if (mBuf[cpu] == MAP_FAILED) { @@ -102,26 +139,7 @@ bool PerfBuffer::send(Sender *const sender) { if (head > tail) { const uint8_t *const b = static_cast<uint8_t *>(mBuf[cpu]) + gSessionData->mPageSize; - const int offset = gSessionData->mLocalCapture ? 1 : 0; - unsigned char header[7]; - header[0] = RESPONSE_APC_DATA; - Buffer::writeLEInt(header + 1, head - tail + sizeof(header) - 5); - // Should use real packing functions - header[5] = FRAME_PERF; - header[6] = cpu; - - // Write header - sender->writeData(reinterpret_cast<const char *>(&header) + offset, sizeof(header) - offset, RESPONSE_APC_DATA); - - // Write data - if ((head & ~BUF_MASK) == (tail & ~BUF_MASK)) { - // Not wrapped - sender->writeData(reinterpret_cast<const char *>(b + (tail & BUF_MASK)), head - tail, RESPONSE_APC_DATA); - } else { - // Wrapped - sender->writeData(reinterpret_cast<const char *>(b + (tail & BUF_MASK)), BUF_SIZE - (tail & BUF_MASK), RESPONSE_APC_DATA); - sender->writeData(reinterpret_cast<const char *>(b), head & BUF_MASK, RESPONSE_APC_DATA); - } + compressAndSend(cpu, head, tail, b, sender); // Update tail with the data read pemp->data_tail = head; @@ -131,6 +149,7 @@ bool PerfBuffer::send(Sender *const sender) { munmap(mBuf[cpu], gSessionData->mPageSize + BUF_SIZE); mBuf[cpu] = MAP_FAILED; mDiscard[cpu] = false; + mFds[cpu] = -1; logg->logMessage("%s(%s:%i): Unmaped cpu %i", __FUNCTION__, __FILE__, __LINE__, cpu); } } |