blob: c4ced9f607f902587a53089ed2bf9846b7a51c82 [file] [log] [blame]
Jon Medhurstaaf37a32013-06-11 12:10:56 +01001/**
Jon Medhurstb1d07442015-05-08 12:04:18 +01002 * Copyright (C) ARM Limited 2013-2015. All rights reserved.
Jon Medhurstaaf37a32013-06-11 12:10:56 +01003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include "Buffer.h"
10
11#include "Logging.h"
12#include "Sender.h"
13#include "SessionData.h"
14
Jon Medhurst15ce78d2014-04-10 09:02:02 +010015#define mask (mSize - 1)
Jon Medhurstb1d07442015-05-08 12:04:18 +010016#define FRAME_HEADER_SIZE 3
Jon Medhurstaaf37a32013-06-11 12:10:56 +010017
Jon Medhurst15ce78d2014-04-10 09:02:02 +010018enum {
Jon Medhurstb1d07442015-05-08 12:04:18 +010019 CODE_PEA = 1,
20 CODE_KEYS = 2,
21 CODE_FORMAT = 3,
22 CODE_MAPS = 4,
23 CODE_COMM = 5,
24 CODE_KEYS_OLD = 6,
25 CODE_ONLINE_CPU = 7,
26 CODE_OFFLINE_CPU = 8,
27 CODE_KALLSYMS = 9,
28 CODE_COUNTERS = 10,
Jon Medhurst15ce78d2014-04-10 09:02:02 +010029};
30
31// Summary Frame Messages
32enum {
33 MESSAGE_SUMMARY = 1,
34 MESSAGE_CORE_NAME = 3,
35};
36
37// From gator_marshaling.c
38#define NEWLINE_CANARY \
39 /* Unix */ \
40 "1\n" \
41 /* Windows */ \
42 "2\r\n" \
43 /* Mac OS */ \
44 "3\r" \
45 /* RISC OS */ \
46 "4\n\r" \
47 /* Add another character so the length isn't 0x0a bytes */ \
48 "5"
49
Jon Medhurst96b56152014-10-30 18:01:15 +000050Buffer::Buffer(const int32_t core, const int32_t buftype, const int size, sem_t *const readerSem) : mBuf(new char[size]), mReaderSem(readerSem), mCommitTime(gSessionData->mLiveRate), mSize(size), mReadPos(0), mWritePos(0), mCommitPos(0), mAvailable(true), mIsDone(false), mCore(core), mBufType(buftype) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +010051 if ((mSize & mask) != 0) {
Jon Medhurstb1d07442015-05-08 12:04:18 +010052 logg->logError("Buffer size is not a power of 2");
Jon Medhurstaaf37a32013-06-11 12:10:56 +010053 handleException();
54 }
Jon Medhurst96b56152014-10-30 18:01:15 +000055 sem_init(&mWriterSem, 0, 0);
Jon Medhurstaaf37a32013-06-11 12:10:56 +010056 frame();
57}
58
Jon Medhurst15ce78d2014-04-10 09:02:02 +010059Buffer::~Buffer() {
60 delete [] mBuf;
Jon Medhurst96b56152014-10-30 18:01:15 +000061 sem_destroy(&mWriterSem);
Jon Medhurstaaf37a32013-06-11 12:10:56 +010062}
63
Jon Medhurst15ce78d2014-04-10 09:02:02 +010064void Buffer::write(Sender *const sender) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +010065 if (!commitReady()) {
66 return;
67 }
68
Jon Medhurst96b56152014-10-30 18:01:15 +000069 // commit and read are updated by the writer, only read them once
70 int commitPos = mCommitPos;
71 int readPos = mReadPos;
72
Jon Medhurstaaf37a32013-06-11 12:10:56 +010073 // determine the size of two halves
Jon Medhurst96b56152014-10-30 18:01:15 +000074 int length1 = commitPos - readPos;
75 char *buffer1 = mBuf + readPos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +010076 int length2 = 0;
Jon Medhurst15ce78d2014-04-10 09:02:02 +010077 char *buffer2 = mBuf;
Jon Medhurstaaf37a32013-06-11 12:10:56 +010078 if (length1 < 0) {
Jon Medhurst96b56152014-10-30 18:01:15 +000079 length1 = mSize - readPos;
80 length2 = commitPos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +010081 }
82
83 logg->logMessage("Sending data length1: %i length2: %i", length1, length2);
84
85 // start, middle or end
86 if (length1 > 0) {
87 sender->writeData(buffer1, length1, RESPONSE_APC_DATA);
88 }
89
90 // possible wrap around
91 if (length2 > 0) {
92 sender->writeData(buffer2, length2, RESPONSE_APC_DATA);
93 }
94
Jon Medhurst96b56152014-10-30 18:01:15 +000095 mReadPos = commitPos;
96
97 // send a notification that space is available
98 sem_post(&mWriterSem);
Jon Medhurstaaf37a32013-06-11 12:10:56 +010099}
100
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100101bool Buffer::commitReady() const {
102 return mCommitPos != mReadPos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100103}
104
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100105int Buffer::bytesAvailable() const {
106 int filled = mWritePos - mReadPos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100107 if (filled < 0) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100108 filled += mSize;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100109 }
110
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100111 int remaining = mSize - filled;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100112
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100113 if (mAvailable) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100114 // Give some extra room; also allows space to insert the overflow error packet
115 remaining -= 200;
116 } else {
117 // Hysteresis, prevents multiple overflow messages
118 remaining -= 2000;
119 }
120
121 return remaining;
122}
123
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100124bool Buffer::checkSpace(const int bytes) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100125 const int remaining = bytesAvailable();
126
127 if (remaining < bytes) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100128 mAvailable = false;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100129 } else {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100130 mAvailable = true;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100131 }
132
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100133 return mAvailable;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100134}
135
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100136int Buffer::contiguousSpaceAvailable() const {
137 int remaining = bytesAvailable();
138 int contiguous = mSize - mWritePos;
139 if (remaining < contiguous) {
140 return remaining;
141 } else {
142 return contiguous;
143 }
144}
145
Jon Medhurstb1d07442015-05-08 12:04:18 +0100146void Buffer::commit(const uint64_t time, const bool force) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100147 // post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload
148 const int typeLength = gSessionData->mLocalCapture ? 0 : 1;
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100149 int length = mWritePos - mCommitPos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100150 if (length < 0) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100151 length += mSize;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100152 }
153 length = length - typeLength - sizeof(int32_t);
Jon Medhurstb1d07442015-05-08 12:04:18 +0100154 if (!force && !mIsDone && length <= FRAME_HEADER_SIZE) {
155 // Nothing to write, only the frame header is present
156 return;
157 }
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100158 for (size_t byte = 0; byte < sizeof(int32_t); byte++) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100159 mBuf[(mCommitPos + typeLength + byte) & mask] = (length >> byte * 8) & 0xFF;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100160 }
161
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100162 logg->logMessage("Committing data mReadPos: %i mWritePos: %i mCommitPos: %i", mReadPos, mWritePos, mCommitPos);
163 mCommitPos = mWritePos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100164
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100165 if (gSessionData->mLiveRate > 0) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100166 while (time > mCommitTime) {
167 mCommitTime += gSessionData->mLiveRate;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100168 }
169 }
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100170
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100171 if (!mIsDone) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100172 frame();
173 }
174
175 // send a notification that data is ready
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100176 sem_post(mReaderSem);
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100177}
178
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100179void Buffer::check(const uint64_t time) {
180 int filled = mWritePos - mCommitPos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100181 if (filled < 0) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100182 filled += mSize;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100183 }
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100184 if (filled >= ((mSize * 3) / 4) || (gSessionData->mLiveRate > 0 && time >= mCommitTime)) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100185 commit(time);
186 }
187}
188
Jon Medhurste31266f2014-08-04 15:47:44 +0100189void Buffer::packInt(char *const buf, const int size, int &writePos, int32_t x) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100190 int packedBytes = 0;
191 int more = true;
192 while (more) {
193 // low order 7 bits of x
194 char b = x & 0x7f;
195 x >>= 7;
196
197 if ((x == 0 && (b & 0x40) == 0) || (x == -1 && (b & 0x40) != 0)) {
198 more = false;
199 } else {
200 b |= 0x80;
201 }
202
Jon Medhurste31266f2014-08-04 15:47:44 +0100203 buf[(writePos + packedBytes) & /*mask*/(size - 1)] = b;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100204 packedBytes++;
205 }
206
Jon Medhurste31266f2014-08-04 15:47:44 +0100207 writePos = (writePos + packedBytes) & /*mask*/(size - 1);
208}
209
210void Buffer::packInt(int32_t x) {
211 packInt(mBuf, mSize, mWritePos, x);
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100212}
213
Jon Medhurst96b56152014-10-30 18:01:15 +0000214void Buffer::packInt64(char *const buf, const int size, int &writePos, int64_t x) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100215 int packedBytes = 0;
216 int more = true;
217 while (more) {
218 // low order 7 bits of x
219 char b = x & 0x7f;
220 x >>= 7;
221
222 if ((x == 0 && (b & 0x40) == 0) || (x == -1 && (b & 0x40) != 0)) {
223 more = false;
224 } else {
225 b |= 0x80;
226 }
227
Jon Medhurst96b56152014-10-30 18:01:15 +0000228 buf[(writePos + packedBytes) & /*mask*/(size - 1)] = b;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100229 packedBytes++;
230 }
231
Jon Medhurst96b56152014-10-30 18:01:15 +0000232 writePos = (writePos + packedBytes) & /*mask*/(size - 1);
233}
234
235void Buffer::packInt64(int64_t x) {
236 packInt64(mBuf, mSize, mWritePos, x);
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100237}
238
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100239void Buffer::writeBytes(const void *const data, size_t count) {
240 size_t i;
241 for (i = 0; i < count; ++i) {
242 mBuf[(mWritePos + i) & mask] = static_cast<const char *>(data)[i];
243 }
244
245 mWritePos = (mWritePos + i) & mask;
246}
247
248void Buffer::writeString(const char *const str) {
249 const int len = strlen(str);
250 packInt(len);
251 writeBytes(str, len);
252}
253
254void Buffer::frame() {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100255 if (!gSessionData->mLocalCapture) {
256 packInt(RESPONSE_APC_DATA);
257 }
258 // Reserve space for the length
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100259 mWritePos += sizeof(int32_t);
260 packInt(mBufType);
Jon Medhurst96b56152014-10-30 18:01:15 +0000261 if ((mBufType == FRAME_BLOCK_COUNTER) || (mBufType == FRAME_PERF_ATTRS) || (mBufType == FRAME_PERF)) {
262 packInt(mCore);
263 }
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100264}
265
Jon Medhurst96b56152014-10-30 18:01:15 +0000266void Buffer::summary(const uint64_t currTime, const int64_t timestamp, const int64_t uptime, const int64_t monotonicDelta, const char *const uname) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100267 packInt(MESSAGE_SUMMARY);
268 writeString(NEWLINE_CANARY);
269 packInt64(timestamp);
270 packInt64(uptime);
271 packInt64(monotonicDelta);
272 writeString("uname");
273 writeString(uname);
274 writeString("");
Jon Medhurst96b56152014-10-30 18:01:15 +0000275 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100276}
277
Jon Medhurst96b56152014-10-30 18:01:15 +0000278void Buffer::coreName(const uint64_t currTime, const int core, const int cpuid, const char *const name) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100279 if (checkSpace(3 * MAXSIZE_PACK32 + 0x100)) {
280 packInt(MESSAGE_CORE_NAME);
281 packInt(core);
282 packInt(cpuid);
283 writeString(name);
284 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000285 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100286}
287
288bool Buffer::eventHeader(const uint64_t curr_time) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100289 bool retval = false;
290 if (checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000291 // key of zero indicates a timestamp
292 packInt(0);
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100293 packInt64(curr_time);
294 retval = true;
295 }
296
297 return retval;
298}
299
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100300bool Buffer::eventTid(const int tid) {
Jon Medhurst34d97692013-12-19 09:23:06 +0000301 bool retval = false;
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100302 if (checkSpace(2 * MAXSIZE_PACK32)) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000303 // key of 1 indicates a tid
304 packInt(1);
Jon Medhurst34d97692013-12-19 09:23:06 +0000305 packInt(tid);
306 retval = true;
307 }
308
309 return retval;
310}
311
Jon Medhurst96b56152014-10-30 18:01:15 +0000312void Buffer::event(const int key, const int32_t value) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100313 if (checkSpace(2 * MAXSIZE_PACK32)) {
314 packInt(key);
315 packInt(value);
316 }
317}
318
Jon Medhurst96b56152014-10-30 18:01:15 +0000319void Buffer::event64(const int key, const int64_t value) {
320 if (checkSpace(MAXSIZE_PACK64 + MAXSIZE_PACK32)) {
321 packInt(key);
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100322 packInt64(value);
323 }
324}
325
Jon Medhurstb1d07442015-05-08 12:04:18 +0100326void Buffer::marshalPea(const uint64_t currTime, const struct perf_event_attr *const pea, int key) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000327 while (!checkSpace(2 * MAXSIZE_PACK32 + pea->size)) {
328 sem_wait(&mWriterSem);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100329 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000330 packInt(CODE_PEA);
331 writeBytes(pea, pea->size);
332 packInt(key);
333 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100334}
335
Jon Medhurstb1d07442015-05-08 12:04:18 +0100336void Buffer::marshalKeys(const uint64_t currTime, const int count, const __u64 *const ids, const int *const keys) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000337 while (!checkSpace(2 * MAXSIZE_PACK32 + count * (MAXSIZE_PACK32 + MAXSIZE_PACK64))) {
338 sem_wait(&mWriterSem);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100339 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000340 packInt(CODE_KEYS);
341 packInt(count);
342 for (int i = 0; i < count; ++i) {
343 packInt64(ids[i]);
344 packInt(keys[i]);
345 }
346 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100347}
348
Jon Medhurstb1d07442015-05-08 12:04:18 +0100349void Buffer::marshalKeysOld(const uint64_t currTime, const int keyCount, const int *const keys, const int bytes, const char *const buf) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000350 while (!checkSpace((2 + keyCount) * MAXSIZE_PACK32 + bytes)) {
351 sem_wait(&mWriterSem);
Jon Medhurste31266f2014-08-04 15:47:44 +0100352 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000353 packInt(CODE_KEYS_OLD);
354 packInt(keyCount);
355 for (int i = 0; i < keyCount; ++i) {
356 packInt(keys[i]);
357 }
358 writeBytes(buf, bytes);
359 check(currTime);
Jon Medhurste31266f2014-08-04 15:47:44 +0100360}
361
Jon Medhurstb1d07442015-05-08 12:04:18 +0100362void Buffer::marshalFormat(const uint64_t currTime, const int length, const char *const format) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000363 while (!checkSpace(MAXSIZE_PACK32 + length + 1)) {
364 sem_wait(&mWriterSem);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100365 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000366 packInt(CODE_FORMAT);
367 writeBytes(format, length + 1);
368 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100369}
370
Jon Medhurstb1d07442015-05-08 12:04:18 +0100371void Buffer::marshalMaps(const uint64_t currTime, const int pid, const int tid, const char *const maps) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100372 const int mapsLen = strlen(maps) + 1;
Jon Medhurst96b56152014-10-30 18:01:15 +0000373 while (!checkSpace(3 * MAXSIZE_PACK32 + mapsLen)) {
374 sem_wait(&mWriterSem);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100375 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000376 packInt(CODE_MAPS);
377 packInt(pid);
378 packInt(tid);
379 writeBytes(maps, mapsLen);
380 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100381}
382
Jon Medhurstb1d07442015-05-08 12:04:18 +0100383void Buffer::marshalComm(const uint64_t currTime, const int pid, const int tid, const char *const image, const char *const comm) {
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100384 const int imageLen = strlen(image) + 1;
385 const int commLen = strlen(comm) + 1;
Jon Medhurst96b56152014-10-30 18:01:15 +0000386 while (!checkSpace(3 * MAXSIZE_PACK32 + imageLen + commLen)) {
387 sem_wait(&mWriterSem);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100388 }
Jon Medhurst96b56152014-10-30 18:01:15 +0000389 packInt(CODE_COMM);
390 packInt(pid);
391 packInt(tid);
392 writeBytes(image, imageLen);
393 writeBytes(comm, commLen);
394 check(currTime);
395}
396
Jon Medhurstb1d07442015-05-08 12:04:18 +0100397void Buffer::onlineCPU(const uint64_t currTime, const int cpu) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000398 while (!checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
399 sem_wait(&mWriterSem);
400 }
401 packInt(CODE_ONLINE_CPU);
Jon Medhurstb1d07442015-05-08 12:04:18 +0100402 packInt64(currTime);
Jon Medhurst96b56152014-10-30 18:01:15 +0000403 packInt(cpu);
404 check(currTime);
405}
406
Jon Medhurstb1d07442015-05-08 12:04:18 +0100407void Buffer::offlineCPU(const uint64_t currTime, const int cpu) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000408 while (!checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
409 sem_wait(&mWriterSem);
410 }
411 packInt(CODE_OFFLINE_CPU);
Jon Medhurstb1d07442015-05-08 12:04:18 +0100412 packInt64(currTime);
Jon Medhurst96b56152014-10-30 18:01:15 +0000413 packInt(cpu);
414 check(currTime);
415}
416
Jon Medhurstb1d07442015-05-08 12:04:18 +0100417void Buffer::marshalKallsyms(const uint64_t currTime, const char *const kallsyms) {
Jon Medhurst96b56152014-10-30 18:01:15 +0000418 const int kallsymsLen = strlen(kallsyms) + 1;
419 while (!checkSpace(3 * MAXSIZE_PACK32 + kallsymsLen)) {
420 sem_wait(&mWriterSem);
421 }
422 packInt(CODE_KALLSYMS);
423 writeBytes(kallsyms, kallsymsLen);
424 check(currTime);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100425}
426
Jon Medhurstb1d07442015-05-08 12:04:18 +0100427void Buffer::perfCounterHeader(const uint64_t time) {
428 while (!checkSpace(MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
429 sem_wait(&mWriterSem);
430 }
431 packInt(CODE_COUNTERS);
432 packInt64(time);
433}
434
435void Buffer::perfCounter(const int core, const int key, const int64_t value) {
436 while (!checkSpace(2*MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
437 sem_wait(&mWriterSem);
438 }
439 packInt(core);
440 packInt(key);
441 packInt64(value);
442}
443
444void Buffer::perfCounterFooter(const uint64_t currTime) {
445 while (!checkSpace(MAXSIZE_PACK32)) {
446 sem_wait(&mWriterSem);
447 }
448 packInt(-1);
449 check(currTime);
450}
451
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100452void Buffer::setDone() {
453 mIsDone = true;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100454 commit(0);
455}
456
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100457bool Buffer::isDone() const {
458 return mIsDone && mReadPos == mCommitPos && mCommitPos == mWritePos;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100459}