Skip to content

Commit d84aff6

Browse files
committed
Add memory management example, o1heap flavor
1 parent b3b73f4 commit d84aff6

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
SOURCES = main.c mongoose.c # Source code files
2+
CFLAGS = -W -Wall -Wextra -g -I. # Build options
3+
4+
# O(1) Heap
5+
SOURCES += o1heap/o1heap/o1heap.c
6+
CFLAGS += -Io1heap/o1heap
7+
8+
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
9+
CFLAGS_MONGOOSE += -DMG_ENABLE_CUSTOM_CALLOC
10+
11+
ifeq ($(OS),Windows_NT)
12+
# Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD
13+
PROG ?= example.exe # Use .exe suffix for the binary
14+
CC = gcc # Use MinGW gcc compiler
15+
CFLAGS += -lws2_32 # Link against Winsock library
16+
DELETE = cmd /C del /f /q /s # Command prompt command to delete files
17+
else
18+
# Mac, Linux
19+
PROG ?= example
20+
DELETE = rm -rf
21+
endif
22+
23+
all: $(PROG)
24+
$(RUN) ./$(PROG) $(ARGS)
25+
26+
$(PROG): $(SOURCES)
27+
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) -o $@
28+
29+
o1heap/o1heap/o1heap.c: # O(1) Heap sources
30+
git clone --depth 1 -b 2.1.0 https://github.com/pavel-kirienko/o1heap.git
31+
32+
clean:
33+
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2025 Cesanta Software Limited
2+
// All rights reserved
3+
4+
#include "mongoose.h"
5+
#include "o1heap.h"
6+
7+
#define POOL_SIZE (5 * MG_IO_SIZE)
8+
9+
O1HeapInstance *s_mem;
10+
11+
// memory allocation
12+
void *mg_calloc(size_t count, size_t size) {
13+
size_t bytes = count * size;
14+
void *ptr = o1heapAllocate(s_mem, bytes);
15+
if (ptr != NULL) memset(ptr, 0, bytes);
16+
if (ptr != NULL) MG_DEBUG(("%lu bytes @%p", bytes, ptr));
17+
if (ptr == NULL) MG_ERROR(("Failed to allocate %lu bytes", bytes));
18+
return ptr;
19+
}
20+
21+
void mg_free(void *ptr) {
22+
o1heapFree(s_mem, ptr);
23+
if (ptr != NULL) MG_DEBUG(("block @%p", ptr));
24+
}
25+
26+
// HTTP request callback
27+
static void fn(struct mg_connection *c, int ev, void *ev_data) {
28+
if (ev == MG_EV_HTTP_MSG) {
29+
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
30+
if (mg_match(hm->uri, mg_str("/hi"), NULL)) {
31+
mg_http_reply(c, 200, "Host: foo.com\r\n", "hi\n");
32+
} else if (mg_match(hm->uri, mg_str("/echo"), NULL)) {
33+
mg_http_reply(c, 200, "", "%.*s", (int) hm->body.len, hm->body.buf);
34+
} else if (mg_match(hm->uri, mg_str("/stats"), NULL)) {
35+
struct mg_connection *t;
36+
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
37+
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
38+
for (t = c->mgr->conns; t != NULL; t = t->next) {
39+
mg_http_printf_chunk(c, "%-3lu %4s %s %M %M\n", t->id,
40+
t->is_udp ? "UDP" : "TCP",
41+
t->is_listening ? "LISTENING"
42+
: t->is_accepted ? "ACCEPTED "
43+
: "CONNECTED",
44+
mg_print_ip, &t->loc, mg_print_ip, &t->rem);
45+
}
46+
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
47+
} else {
48+
struct mg_http_serve_opts opts;
49+
memset(&opts, 0, sizeof(opts));
50+
opts.root_dir = ".";
51+
mg_http_serve_dir(c, ev_data, &opts);
52+
}
53+
}
54+
}
55+
56+
int main(void) {
57+
struct mg_mgr mgr;
58+
59+
void *pool = malloc(POOL_SIZE + O1HEAP_ALIGNMENT);
60+
void *aligned = (void *) (((uintptr_t) pool) & ~(O1HEAP_ALIGNMENT - 1));
61+
O1HeapDiagnostics d;
62+
s_mem = o1heapInit(aligned, POOL_SIZE);
63+
d = o1heapGetDiagnostics(s_mem);
64+
MG_INFO(
65+
("Created aligned %lu-byte pool @%p, out of a %lu-byte allocated system "
66+
"memory pool",
67+
d.capacity, s_mem, POOL_SIZE));
68+
69+
mg_mgr_init(&mgr); // Initialise event manager
70+
mg_log_set(MG_LL_DEBUG); // Set debug log level
71+
mg_http_listen(&mgr, "http://localhost:8000", fn, NULL); // Create listener
72+
for (;;) { // Event loop
73+
mg_mgr_poll(&mgr, 1000);
74+
}
75+
mg_mgr_free(&mgr);
76+
return 0;
77+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../mongoose.c
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../mongoose.h

0 commit comments

Comments
 (0)