Skip to content

Commit 5d21545

Browse files
authored
Merge pull request #235 from pscollins/counter-metric2
Export a counter event for block allocations.
2 parents ee5133a + 6bd4474 commit 5d21545

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

mltrace/tracetr.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* See the file MLton-LICENSE for details.
55
*/
66

7+
#include <assert.h>
78
#include <inttypes.h>
89
#include <stdbool.h>
910
#include <stdio.h>
@@ -83,6 +84,8 @@ static const char *EventKindStrings[] = {
8384

8485
[EVENT_SCHED_SLEEP_ENTER] = "SCHED_SLEEP_ENTER",
8586
[EVENT_SCHED_SLEEP_LEAVE] = "SCHED_SLEEP_LEAVE",
87+
88+
[EVENT_LIVE_BLOCK_COUNTER] = "LIVE_BLOCKS",
8689
};
8790

8891
void processFiles(size_t filecount, FILE **files, void (*func)(struct Event *));
@@ -247,8 +250,9 @@ void printEventKindStripEnterLeave(int kind) {
247250
buf[99] = '\0';
248251

249252
const char *str = EventKindStrings[kind];
253+
strncpy(buf, str, 99);
250254
size_t len = strlen(str);
251-
strncpy(buf, str, len-6);
255+
assert(len < 100);
252256
buf[len-6] = '\0';
253257

254258
printf("%s", buf);
@@ -261,18 +265,33 @@ void printEventKindStripEnterLeave(int kind) {
261265
* see chrome-tracing-docs.txt
262266
*/
263267
enum ChromeTracingPhaseType {
264-
CT_Begin, // "B"
265-
CT_End, // "E"
266-
CT_Instant // "i"
268+
CT_Begin, // "B"
269+
CT_End, // "E"
270+
CT_Instant, // "i"
271+
CT_Counter // "C"
267272
};
268273

274+
bool isCounterEvent(int kind) {
275+
switch (kind) {
276+
case EVENT_LIVE_BLOCK_COUNTER:
277+
return true;
278+
default:
279+
return false;
280+
}
281+
}
282+
269283
enum ChromeTracingPhaseType
270284
EventKindChromeTracingPhaseType(int kind)
271285
{
272286
// default to "instant" event; most general.
273287
if (!(kind > 0 && (size_t)kind < EventKindCount))
274288
return CT_Instant;
275289

290+
// we explicitly enumerate counter events here
291+
if (isCounterEvent(kind)) {
292+
return CT_Counter;
293+
}
294+
276295
// check for "_ENTER" or "_LEAVE", which is the mltrace convention
277296
const char *str = EventKindStrings[kind];
278297
size_t len = strlen(str);
@@ -309,6 +328,18 @@ void printEventTimeNanoseconds(struct Event *event) {
309328
printf("%llu", ns);
310329
}
311330

331+
void printEventArgs(struct Event *event) {
332+
switch (event->kind) {
333+
case EVENT_LIVE_BLOCK_COUNTER:
334+
printf("\"args\": { \"count\": %lld } ", event->arg1);
335+
break;
336+
default:
337+
printf("\"args\": { \"1\": %lld, \"2\": %lld, \"3\": %lld }",
338+
event->arg1, event->arg2, event->arg3);
339+
break;
340+
}
341+
}
342+
312343
void printEventChromeTracingJSON(struct Event *event) {
313344
printf("{ ");
314345

@@ -328,6 +359,11 @@ void printEventChromeTracingJSON(struct Event *event) {
328359
printf("\"ph\": \"E\", ");
329360
break;
330361

362+
case CT_Counter:
363+
printf("\"name\": \""); printEventKind(event->kind); printf("\", ");
364+
printf("\"ph\": \"C\", ");
365+
break;
366+
331367
default:
332368
printf("\"name\": \""); printEventKind(event->kind); printf("\", ");
333369
printf("\"ph\": \"i\", ");
@@ -338,8 +374,7 @@ void printEventChromeTracingJSON(struct Event *event) {
338374
printf("\"pid\": 0, ");
339375
printf("\"tid\": %"PRIdPTR", ", event->argptr);
340376
printf("\"ts\": "); printEventTimeMicroseconds(event); printf(", ");
341-
printf("\"args\": { \"1\": %lld, \"2\": %lld, \"3\": %lld }",
342-
event->arg1, event->arg2, event->arg3);
377+
printEventArgs(event);
343378

344379
printf("}");
345380
}
@@ -436,6 +471,11 @@ void printEventText(struct Event *event) {
436471
event->arg1, event->arg2, event->arg3);
437472
break;
438473

474+
case EVENT_LIVE_BLOCK_COUNTER:
475+
printf("live_blocks = %lld",
476+
event->arg1);
477+
break;
478+
439479
default:
440480
printf("?1 = %llx, ?2 = %llx, ?3 = %llx",
441481
event->arg1, event->arg2, event->arg3);

runtime/gc/block-allocator.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,27 @@
33
* MLton is released under a HPND-style license.
44
* See the file MLton-LICENSE for details.
55
*/
6+
#include <stdatomic.h>
7+
#include <stdint.h>
68

79
#if (defined (MLTON_GC_INTERNAL_FUNCS))
810

911
#define INFO_BUFFER_LEN 256
1012

13+
#ifdef ENABLE_TRACING
14+
static atomic_int_least64_t live_blocks = 0;
15+
16+
// Track the live block count in a separate atomic so that we can easily export
17+
// it as a counter.
18+
static int64_t incLiveBlocks(int numBlocks) {
19+
return atomic_fetch_add(&live_blocks, numBlocks);
20+
}
21+
22+
static int64_t decLiveBlocks(int numBlocks) {
23+
return atomic_fetch_sub(&live_blocks, numBlocks);
24+
}
25+
#endif // ENABLE_TRACING
26+
1127
static inline size_t SUPERBLOCK_SIZE(GC_state s) {
1228
return (1 << s->controls->superblockThreshold);
1329
}
@@ -519,6 +535,7 @@ static MegaBlock mmapNewMegaBlock(GC_state s, size_t numBlocks, enum BlockPurpos
519535

520536

521537
Blocks allocateBlocksWithPurpose(GC_state s, size_t numBlocks, enum BlockPurpose purpose) {
538+
Trace1(EVENT_LIVE_BLOCK_COUNTER, incLiveBlocks(numBlocks));
522539
BlockAllocator local = s->blockAllocatorLocal;
523540
assertBlockAllocatorOkay(s, local);
524541

@@ -585,6 +602,7 @@ void freeBlocks(GC_state s, Blocks bs, writeFreedBlockInfoFnClosure f) {
585602
SuperBlock sb = bs->container;
586603
enum BlockPurpose purpose = bs->purpose;
587604
pointer blockStart = (pointer)bs;
605+
Trace1(EVENT_LIVE_BLOCK_COUNTER, decLiveBlocks(numBlocks));
588606

589607
#if ASSERT
590608
if (!s->controls->debugKeepFreeBlocks) {

runtime/trace.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ enum EventKind {
8181
EVENT_MANAGE_ENTANGLED_LEAVE = 47,
8282

8383
EVENT_SCHED_SLEEP_ENTER = 48,
84-
EVENT_SCHED_SLEEP_LEAVE = 49
84+
EVENT_SCHED_SLEEP_LEAVE = 49,
85+
86+
EVENT_LIVE_BLOCK_COUNTER = 50,
8587
};
8688

8789
#define EventKindCount (sizeof EventKindStrings / sizeof *EventKindStrings)

0 commit comments

Comments
 (0)