mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-01 14:02:40 +07:00
Merge pull request #3328 from cesanta/memory
Add memory management example, o1heap flavor
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
SOURCES = main.c mongoose.c # Source code files
|
||||
CFLAGS = -W -Wall -Wextra -g -I. # Build options
|
||||
|
||||
# O(1) Heap
|
||||
SOURCES += o1heap/o1heap/o1heap.c
|
||||
CFLAGS += -Io1heap/o1heap
|
||||
|
||||
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
||||
CFLAGS_MONGOOSE += -DMG_ENABLE_CUSTOM_CALLOC
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD
|
||||
PROG ?= example.exe # Use .exe suffix for the binary
|
||||
CC = gcc # Use MinGW gcc compiler
|
||||
CFLAGS += -lws2_32 # Link against Winsock library
|
||||
DELETE = cmd /C del /f /q /s # Command prompt command to delete files
|
||||
else
|
||||
# Mac, Linux
|
||||
PROG ?= example
|
||||
DELETE = rm -rf
|
||||
endif
|
||||
|
||||
all: $(PROG)
|
||||
$(RUN) ./$(PROG) $(ARGS)
|
||||
|
||||
$(PROG): $(SOURCES)
|
||||
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) -o $@
|
||||
|
||||
o1heap/o1heap/o1heap.c: # O(1) Heap sources
|
||||
git clone --depth 1 -b 2.1.0 https://github.com/pavel-kirienko/o1heap.git
|
||||
|
||||
clean:
|
||||
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2025 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
#include "mongoose.h"
|
||||
#include "o1heap.h"
|
||||
|
||||
#define POOL_SIZE (5 * MG_IO_SIZE)
|
||||
|
||||
O1HeapInstance *s_mem;
|
||||
|
||||
// memory allocation
|
||||
void *mg_calloc(size_t count, size_t size) {
|
||||
size_t bytes = count * size;
|
||||
void *ptr = o1heapAllocate(s_mem, bytes);
|
||||
if (ptr != NULL) memset(ptr, 0, bytes);
|
||||
if (ptr != NULL) MG_DEBUG(("%lu bytes @%p", bytes, ptr));
|
||||
if (ptr == NULL) MG_ERROR(("Failed to allocate %lu bytes", bytes));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void mg_free(void *ptr) {
|
||||
o1heapFree(s_mem, ptr);
|
||||
if (ptr != NULL) MG_DEBUG(("block @%p", ptr));
|
||||
}
|
||||
|
||||
// HTTP request callback
|
||||
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
if (mg_match(hm->uri, mg_str("/hi"), NULL)) {
|
||||
mg_http_reply(c, 200, "Host: foo.com\r\n", "hi\n");
|
||||
} else if (mg_match(hm->uri, mg_str("/echo"), NULL)) {
|
||||
mg_http_reply(c, 200, "", "%.*s", (int) hm->body.len, hm->body.buf);
|
||||
} else if (mg_match(hm->uri, mg_str("/stats"), NULL)) {
|
||||
struct mg_connection *t;
|
||||
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
|
||||
for (t = c->mgr->conns; t != NULL; t = t->next) {
|
||||
mg_http_printf_chunk(c, "%-3lu %4s %s %M %M\n", t->id,
|
||||
t->is_udp ? "UDP" : "TCP",
|
||||
t->is_listening ? "LISTENING"
|
||||
: t->is_accepted ? "ACCEPTED "
|
||||
: "CONNECTED",
|
||||
mg_print_ip, &t->loc, mg_print_ip, &t->rem);
|
||||
}
|
||||
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
|
||||
} else {
|
||||
struct mg_http_serve_opts opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.root_dir = ".";
|
||||
mg_http_serve_dir(c, ev_data, &opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
|
||||
void *pool = malloc(POOL_SIZE + O1HEAP_ALIGNMENT);
|
||||
void *aligned = (void *) (((uintptr_t) pool) & ~(O1HEAP_ALIGNMENT - 1));
|
||||
O1HeapDiagnostics d;
|
||||
s_mem = o1heapInit(aligned, POOL_SIZE);
|
||||
d = o1heapGetDiagnostics(s_mem);
|
||||
MG_INFO(
|
||||
("Created aligned %lu-byte pool @%p, out of a %lu-byte allocated system "
|
||||
"memory pool",
|
||||
d.capacity, s_mem, POOL_SIZE));
|
||||
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
||||
mg_http_listen(&mgr, "http://localhost:8000", fn, NULL); // Create listener
|
||||
for (;;) { // Event loop
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
return 0;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../../mongoose.c
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../../mongoose.h
|
||||
Reference in New Issue
Block a user