summaryrefslogtreecommitdiffstats
path: root/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c')
-rw-r--r--src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c b/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c
new file mode 100644
index 000000000..a89babf92
--- /dev/null
+++ b/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c
@@ -0,0 +1,138 @@
+/*
+ * Example memory allocator with machine parseable logging.
+ *
+ * Also sizes for reallocs and frees are logged so that the memory
+ * behavior can be essentially replayed to accurately determine e.g.
+ * optimal pool sizes for a pooled allocator.
+ *
+ * Allocation structure:
+ *
+ * [ alloc_hdr | user area ]
+ *
+ * ^ ^
+ * | `--- pointer returned to Duktape
+ * `--- underlying malloc ptr
+ */
+
+#include "duktape.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#define ALLOC_LOG_FILE "/tmp/duk-alloc-log.txt"
+
+typedef struct {
+ /* The double value in the union is there to ensure alignment is
+ * good for IEEE doubles too. In many 32-bit environments 4 bytes
+ * would be sufficiently aligned and the double value is unnecessary.
+ */
+ union {
+ size_t sz;
+ double d;
+ } u;
+} alloc_hdr;
+
+static FILE *log_file = NULL;
+
+static void write_log(const char *fmt, ...) {
+ va_list ap;
+
+ if (!log_file) {
+ log_file = fopen(ALLOC_LOG_FILE, "wb");
+ if (!log_file) {
+ return;
+ }
+ }
+
+ va_start(ap, fmt);
+ vfprintf(log_file, fmt, ap);
+ va_end(ap);
+}
+
+void *duk_alloc_logging(void *udata, duk_size_t size) {
+ alloc_hdr *hdr;
+ void *ret;
+
+ (void) udata; /* Suppress warning. */
+
+ if (size == 0) {
+ write_log("A NULL %ld\n", (long) size);
+ return NULL;
+ }
+
+ hdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr));
+ if (!hdr) {
+ write_log("A FAIL %ld\n", (long) size);
+ return NULL;
+ }
+ hdr->u.sz = size;
+ ret = (void *) (hdr + 1);
+ write_log("A %p %ld\n", ret, (long) size);
+ return ret;
+}
+
+void *duk_realloc_logging(void *udata, void *ptr, duk_size_t size) {
+ alloc_hdr *hdr;
+ size_t old_size;
+ void *t;
+ void *ret;
+
+ (void) udata; /* Suppress warning. */
+
+ /* Handle the ptr-NULL vs. size-zero cases explicitly to minimize
+ * platform assumptions. You can get away with much less in specific
+ * well-behaving environments.
+ */
+
+ if (ptr) {
+ hdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr));
+ old_size = hdr->u.sz;
+
+ if (size == 0) {
+ write_log("R %p %ld NULL 0\n", ptr, (long) old_size);
+ free((void *) hdr);
+ return NULL;
+ } else {
+ t = realloc((void *) hdr, size + sizeof(alloc_hdr));
+ if (!t) {
+ write_log("R %p %ld FAIL %ld\n", ptr, (long) old_size, (long) size);
+ return NULL;
+ }
+ hdr = (alloc_hdr *) t;
+ hdr->u.sz = size;
+ ret = (void *) (hdr + 1);
+ write_log("R %p %ld %p %ld\n", ptr, (long) old_size, ret, (long) size);
+ return ret;
+ }
+ } else {
+ if (size == 0) {
+ write_log("R NULL 0 NULL 0\n");
+ return NULL;
+ } else {
+ hdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr));
+ if (!hdr) {
+ write_log("R NULL 0 FAIL %ld\n", (long) size);
+ return NULL;
+ }
+ hdr->u.sz = size;
+ ret = (void *) (hdr + 1);
+ write_log("R NULL 0 %p %ld\n", ret, (long) size);
+ return ret;
+ }
+ }
+}
+
+void duk_free_logging(void *udata, void *ptr) {
+ alloc_hdr *hdr;
+
+ (void) udata; /* Suppress warning. */
+
+ if (!ptr) {
+ write_log("F NULL 0\n");
+ return;
+ }
+ hdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr));
+ write_log("F %p %ld\n", ptr, (long) hdr->u.sz);
+ free((void *) hdr);
+}