Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions frameworks/libioma/Dockerfile

This file was deleted.

34 changes: 0 additions & 34 deletions frameworks/libioma/README.md

This file was deleted.

44 changes: 0 additions & 44 deletions frameworks/libioma/main.c

This file was deleted.

17 changes: 0 additions & 17 deletions frameworks/libioma/meta.json

This file was deleted.

29 changes: 29 additions & 0 deletions frameworks/libioxd/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM ubuntu:24.04 AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc-14 make curl ca-certificates libc6-dev libssl-dev libcjson-dev libbrotli-dev zlib1g-dev pkg-config \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app

# Build libioxd from its own repo, pinned to a commit (the h2o pattern: fetch upstream at a fixed
# SHA and build it here, tuned for this CPU). No liburing: libioxd issues the io_uring syscalls
# directly; OpenSSL does the TLS handshake and the kernel the records (kTLS). Only the handlers
# live in this entry. Fat LTO objects for the library and -flto on the handler link, so the
# handlers inline into the engine. cJSON parses the dataset once at startup; brotli and zlib are
# the codings of the library's compression middleware (json-comp).
ARG LIBIOXD_VERSION=3e435f30b6d75b98586ea9e4d35be8c7b75ad6ec
RUN mkdir -p /tmp/libioxd && \
curl -LSs "https://github.com/MDA2AV/libioxd/archive/${LIBIOXD_VERSION}.tar.gz" \
| tar --strip-components=1 -xz -C /tmp/libioxd && \
make -C /tmp/libioxd libioxd.a CC=gcc-14 CFLAGS="-O3 -march=native -flto -ffat-lto-objects"

COPY main.c .
RUN gcc-14 -O3 -march=native -flto -Wall -Wextra -std=gnu23 -pthread \
-I/tmp/libioxd/include \
main.c /tmp/libioxd/libioxd.a -o server -pthread -lssl -lcrypto -lbrotlienc -lz -lcjson

FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends libcjson1 libbrotli1 zlib1g \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /app/server /server
EXPOSE 8080 8081
CMD ["/server"]
56 changes: 56 additions & 0 deletions frameworks/libioxd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# libioxd

[libioxd](https://github.com/MDA2AV/libioxd) is an HTTP/1.1 server library in C23 on a
thread-per-core `io_uring` runtime. Each connection runs as a stackful coroutine: the library
parses, routes and frames, and anything that has to wait - a body read, a timer, a send - parks
the connection on the ring and hands the worker to its other connections. A handler reads as
linear code with no state machine. Manual: https://mda2av.github.io/libioxd/

## Stack

- **Language:** C23 (gcc 14, `-O3 -march=native -flto`)
- **Engine:** raw `io_uring` syscalls, no liburing. Multishot accept and multishot recv over
per-worker provided buffer rings; `SINGLE_ISSUER | DEFER_TASKRUN | NO_SQARRAY`; sockets in the
registered file table.
- **Architecture:** thread-per-core, shared-nothing. One ring, one `SO_REUSEPORT` listener per port
and one buffer ring per worker; workers pin to the CPUs in the process affinity mask.
- **Parser:** [picohttpparser](https://github.com/h2o/picohttpparser) for the request line and
headers; the library decodes Content-Length and chunked bodies on demand.
- **TLS:** TLS 1.3 only. OpenSSL runs the handshake over the connection; the record layer is the
kernel's (kTLS, transmit and receive), so a handler writes plaintext and the ring sends it.
- **JSON:** the dataset is parsed once at startup with [cJSON](https://github.com/DaveGamble/cJSON);
each reply is serialized by the library's forward-only JSON writer straight into the reply slab.
- **Compression:** the library's `ioxd_compress` middleware on the `/json` route: brotli (quality 1)
or gzip by the request's `Accept-Encoding`, applied at the reply's first flush - a body that fit
the slab is one encoder call and one message with the exact coded length. No header, no coding.
- **Timer:** `/delay` waits on the ring's own timeout (`IORING_OP_TIMEOUT`), one entry per request.
- **Static files:** the library's static module (`ioxd_static`): what a worker served it keeps in
memory and checks against the disk - inode, size, modification time - on every request, so a
file replaced on disk is served new at once. A `.br` or `.gz` twin beside the file is served
when `Accept-Encoding` takes the coding, with the base type and the matching `Content-Encoding`.
A body larger than the reply slab goes out from memory in one message behind the head.

## Build

The Dockerfile fetches libioxd from its repo at a pinned commit (`LIBIOXD_VERSION`), builds the
static library in-container tuned for the benchmark CPU, and links the handlers below against it -
so this entry holds only the handlers, not the library source. To move to a newer libioxd, bump
`LIBIOXD_VERSION` in the Dockerfile.

Ports: `8080` plain, `8081` TLS. The certificate pair comes from `/certs/server.crt` and
`/certs/server.key` (or `TLS_CERT` / `TLS_KEY`); kTLS needs the `tls` kernel module on the host
(`modprobe tls`) - without it the TLS port refuses every handshake and `8080` still serves.
The dataset is `/data/dataset.json` (`DATASET_PATH`), the static root `/data/static` (`STATIC_ROOT`).

## Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/baseline11` | GET | Sums the query parameter values |
| `/baseline11` | POST | Sums the query parameters plus the request body (Content-Length and chunked) |
| `/delay/{ms}` | GET | Waits `ms` milliseconds on the ring, answers `ms` as `text/plain` |
| `/json/{count}?m=N` | GET | The first `count` dataset items with `total = price × quantity × N`, as `{items, count}`; brotli or gzip when `Accept-Encoding` takes it |
| `/echo` | POST | The request body back, byte for byte (`:8081`) |
| `/static/{file}` | GET | A file from `/data/static`, or its pre-compressed twin (`:8081`) |

Library: https://github.com/MDA2AV/libioxd
Loading