mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-30 12:50:58 +00:00
Merge pull request #3328 from cesanta/memory
Add memory management example, o1heap flavor
This commit is contained in:
4 files changed
+112
No files matched your search
@@ -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