Skip to content

Module Contract

Every module in this repository must satisfy the following contract. This ensures consistency, testability, and integration readiness across all protocol implementations.

Required Files

Every module directory must contain:

src/category/module_name/
├── module_name.h     # Header-only implementation (public API)
├── module_name.c     # Demo program / test harness
└── Makefile          # Build rules

Header File Requirements

1. Protocol Documentation Block

The header must begin with a comprehensive comment block:

/**
 * =============================================================================
 * MODULE NAME (Brief Description)
 * =============================================================================
 *
 * PROTOCOL SPECIFICATION:
 *   What this module implements (1-3 paragraphs).
 *
 * MEMORY & CONCURRENCY MODEL:
 *   ┌───────────────────────────────────────────────────┐
 *   │  ASCII diagram of memory layout or architecture    │
 *   └───────────────────────────────────────────────────┘
 *
 * PERFORMANCE:
 *   - Key latency/throughput characteristics
 *   - Big-O complexity of operations
 *
 * COMPILATION:
 *   gcc -Wall -Wextra -Werror -O3 -std=c11 -o demo module.c [libs]
 *
 * RUNTIME PREREQUISITES:
 *   - Required capabilities, kernel modules, hardware
 *
 * =============================================================================
 */

2. Include Guard

#ifndef MODULE_NAME_H
#define MODULE_NAME_H
/* ... */
#endif /* MODULE_NAME_H */

3. C++ Compatibility

#ifdef __cplusplus
extern "C" {
#endif
/* ... all declarations ... */
#ifdef __cplusplus
}
#endif

4. Static Inline Functions

All API functions must be static inline:

static inline int module_open(module_t *ctx, const char *device)
{
    /* Full implementation in header */
}

5. Error Handling Convention

  • Return 0 on success
  • Return -errno on failure
  • For functions returning data size: positive = success, negative = error
  • Never set global errno (always capture and return)
/* Pattern: capture errno before any other call */
if (syscall(...) < 0) {
    int err = errno;   /* ← capture immediately */
    cleanup();         /* ← this might change errno */
    return -err;       /* ← return the original error */
}

Demo Program Requirements

The .c file must include:

1. Self-Contained Demo

int main(void)
{
    /* 1. Initialize the module */
    /* 2. Demonstrate core operations */
    /* 3. Print results with [module] prefix */
    /* 4. Clean up */
    /* 5. Print [PASS] or [FAIL] */
}

2. Output Format

[module_name] Operation description: result
[module_name] Another operation: value
[PASS] All module_name tests passed

3. No External Dependencies

The demo must compile with just the standard Makefile (GCC + POSIX libs). No third-party libraries.

4. Virtual Device Support

Where hardware is required, document how to create a virtual substitute:

/* For testing without hardware:
 *   socat -d -d pty,raw,echo=0 pty,raw,echo=0
 *   Use the reported /dev/pts/N paths
 */

Makefile Requirements

CC       = gcc
CFLAGS   = -Wall -Wextra -Werror -O3 -std=c11
LDFLAGS  =         # Add -lpthread if using pthreads
TARGET   = module_name_demo
SOURCES  = module_name.c

.PHONY: all clean

all: $(TARGET)

$(TARGET): $(SOURCES) module_name.h
    $(CC) $(CFLAGS) -o $@ $(SOURCES) $(LDFLAGS)

clean:
    rm -f $(TARGET)

API Design Checklist

  • Handle struct Opaque-ish struct holding all state (fd, config, stats)
  • Config struct Separate configuration with a module_default_config() initializer
  • Open/Close Resource acquisition and release with cleanup-on-error
  • Core operations The primary read/write/transfer functions
  • Utility helpers Convenience wrappers for common patterns
  • Statistics At minimum: operation count, error count

Integration Requirements

epoll Reactor Compatibility

If the module uses file descriptors, it must be compatible with the epoll reactor:

/* The module's FD must be accessible for reactor registration */
int fd = module_get_fd(ctx);  /* Or access ctx->fd directly */
reactor_add(&reactor, fd, EPOLLIN | EPOLLET, callback, ctx);

Memory Pool Compatibility

If the module needs dynamic-sized buffers, use the memory pool:

void *buf = memory_pool_alloc(&pool);
/* ... use buffer ... */
memory_pool_free(&pool, buf);

Zero Allocation in Hot Path

After initialization, no function in the hot path may call malloc(), calloc(), realloc(), or any allocating function. All buffers must be:

  1. Stack-allocated (for small, fixed-size)
  2. Pre-allocated at init time (for configurable-size)
  3. Provided by caller (for variable-size)

Performance Requirements

Latency Budget

Module Type Target Measurement
Network (raw_socket, epoll) < 5 µs Wire-to-callback
Embedded (UART, SPI, I2C) < 50 µs Syscall round-trip
Concurrency (ring, pool) < 20 ns Push/pop/alloc
Industrial (Modbus) < 1 ms Request-response

Benchmark Requirement

Every module must include a timing measurement in its demo:

struct timespec t0, t1;
clock_gettime(CLOCK_MONOTONIC, &t0);
/* ... operation ... */
clock_gettime(CLOCK_MONOTONIC, &t1);

double ns = (t1.tv_sec - t0.tv_sec) * 1e9 + (t1.tv_nsec - t0.tv_nsec);
printf("[module] Operation: %.1f ns\n", ns);

Documentation Requirements

Every module must have a corresponding documentation page in docs/:

docs/category/module-name.md

The documentation page must include: - [ ] Overview and status badge - [ ] Protocol specification with ASCII diagrams - [ ] Complete API reference with parameter tables - [ ] At least 2 usage examples - [ ] Build & run instructions - [ ] Prerequisites and permissions - [ ] Performance characteristics table - [ ] Test output showing expected results

Checklist for New Modules

Before submitting a PR for a new module:

  • Header compiles cleanly with -Wall -Wextra -Werror
  • Demo compiles and runs (on virtual device if no hardware)
  • All API functions have documentation comments
  • Memory: no malloc/free in operational functions
  • Errors: returns -errno, captures errno immediately
  • Integration: FD accessible for epoll reactor
  • Performance: timing measured in demo output
  • Docs: MkDocs page created in docs/
  • Tests: demo prints [PASS] on success