Skip to content

Instantly share code, notes, and snippets.

@leiradel
Created July 27, 2018 14:48
Show Gist options
  • Save leiradel/b0835c0d4a9ac37517cf1ae9ae5c0e46 to your computer and use it in GitHub Desktop.
Save leiradel/b0835c0d4a9ac37517cf1ae9ae5c0e46 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>
#include <wren.h>
#ifdef __APPLE__
#include <mach/mach_time.h>
#else
#include <time.h>
#endif
typedef struct {
uint64_t time;
uint64_t bytes;
}
tracking_t;
typedef struct {
union {
uint64_t size;
char padding[16];
}
info;
char block[0];
}
header_t;
static tracking_t s_tracking[128 * 1024 * 1024];
static int s_count;
static uint64_t s_bytes;
#ifdef __APPLE__
// Apple's high-performance counter needs this
static mach_timebase_info_data_t s_tb = {0, 0};
#endif
uint64_t get_time() {
#ifdef __APPLE__
uint64_t time = mach_absolute_time();
return time * s_tb.numer / s_tb.denom;
#else
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return (uint64_t)now.tv_sec * 1000000000ULL + now.tv_nsec;
#endif
}
static void* customAlloc(void* ptr, size_t newSize) {
tracking_t* t;
header_t* h;
header_t* p;
if (s_count == sizeof(s_tracking) / sizeof(s_tracking[0])) {
fprintf(stderr, "s_tracking is too small\n");
exit(1);
}
t = s_tracking + s_count++;
t->time = get_time();
if (newSize == 0) {
if (ptr == NULL) {
/* Uhhh... */
}
else {
h = (header_t*)ptr - 1;
s_bytes -= h->info.size;
free(h);
ptr = NULL;
}
}
else {
if (ptr == NULL) {
h = (header_t*)malloc(newSize + sizeof(header_t));
h->info.size = newSize;
s_bytes += newSize;
ptr = h->block;
}
else {
h = (header_t*)malloc(newSize + sizeof(header_t));
h->info.size = newSize;
s_bytes += newSize;
p = (header_t*)ptr - 1;
s_bytes -= p->info.size;
memmove(h->block, p->block, p->info.size < newSize ? p->info.size : newSize);
free(p);
ptr = h->block;
}
}
t->bytes = s_bytes;
return ptr;
}
static void dumpTracking(void) {
tracking_t* t = s_tracking;
FILE* log;
int i;
log = fopen("wren.log", "w");
for (i = 0; i < s_count; i++, t++) {
fprintf(log, "%f\t%f\n", (t->time - s_tracking[0].time) / 1000000.0, t->bytes / (1024.0 * 1024.0));
}
fclose(log);
}
static const char* readFile(const char* path) {
static char buffer[1024 * 1024];
FILE* file = fopen(path, "rb");
int read = fread(buffer, 1, sizeof(buffer), file);
fclose(file);
buffer[read] = 0;
return buffer;
}
int main(int argc, const char* argv[]) {
WrenVM* W;
if (argc != 2) {
fprintf(stderr, "USAGE: luamem filename.lua");
return 1;
}
s_count = 0;
#ifdef __APPLE__
mach_timebase_info(&s_tb);
#endif
WrenConfiguration config;
wrenInitConfiguration(&config);
config.reallocateFn = customAlloc;
W = wrenNewVM(&config);
const char* source = readFile(argv[1]);
if (wrenInterpret(W, "main", source) != WREN_RESULT_SUCCESS) {
fprintf(stderr, "Error loading file\n");
wrenFreeVM(W);
return 1;
}
wrenFreeVM(W);
dumpTracking();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment