Skip to content

Latest commit

 

History

History
352 lines (276 loc) · 6.47 KB

File metadata and controls

352 lines (276 loc) · 6.47 KB

PromptOS Coding Style Guide

Version 1.0 - Mandatory for all contributions


1. General Rules

Language

  • Code and comments: English
  • Documentation: German or English
  • Commit Messages: English

Formatting

  • Indentation: 4 Spaces (no tabs)
  • Line length: Max. 100 characters
  • Line ending: LF (Unix-style)
  • End of file: Single empty line

2. Naming Conventions

Functions and Variables

// snake_case for functions
void memory_allocate_page(void);
int scheduler_get_current_pid(void);

// snake_case for variables
int page_count;
struct Process *current_process;

Types and Structs

// PascalCase for types
typedef struct Process Process;
typedef struct MemoryRegion MemoryRegion;
typedef enum ProcessState ProcessState;

// Struct definition
struct Process {
    pid_t pid;
    char name[PROCESS_NAME_MAX];
    ProcessState state;
};

Macros and Constants

// SCREAMING_SNAKE_CASE
#define PAGE_SIZE           4096
#define MAX_PROCESSES       256
#define KERNEL_STACK_SIZE   (PAGE_SIZE * 4)

// Macros with parameters
#define ALIGN_UP(x, align)  (((x) + (align) - 1) & ~((align) - 1))
#define MIN(a, b)           ((a) < (b) ? (a) : (b))

Prefixes by Module

// Every module has a prefix
void mm_init(void);           // Memory Management
void sched_yield(void);       // Scheduler
void vfs_open(void);          // Virtual Filesystem
void pci_enumerate(void);     // PCI Subsystem
void ipc_send(void);          // IPC

3. Files and Headers

Header Guards

#ifndef KERNEL_MM_PMM_H
#define KERNEL_MM_PMM_H

// ... Content ...

#endif // KERNEL_MM_PMM_H

Header Structure

#ifndef KERNEL_SCHED_PROCESS_H
#define KERNEL_SCHED_PROCESS_H

// 1. System Includes
#include <stdint.h>
#include <stdbool.h>

// 2. Project Includes
#include <kernel/types.h>
#include <kernel/list.h>

// 3. Forward Declarations
struct Thread;

// 4. Macros and Constants
#define PROCESS_NAME_MAX 64

// 5. Types and Enums
typedef enum {
    PROCESS_STATE_RUNNING,
    PROCESS_STATE_READY,
    PROCESS_STATE_BLOCKED,
    PROCESS_STATE_ZOMBIE
} ProcessState;

// 6. Structs
struct Process {
    pid_t pid;
    ProcessState state;
    // ...
};

// 7. Function Prototypes
Process *process_create(const char *name);
void process_destroy(Process *proc);

#endif // KERNEL_SCHED_PROCESS_H

4. Functions

Documentation (Doxygen)

/**
 * @brief Allocates a physical memory page.
 *
 * This function allocates a single 4KB page from the physical
 * memory allocator. The page is zeroed before return.
 *
 * @return Physical address of the allocated page, or 0 on failure.
 *
 * @note This function may be called from interrupt context.
 * @warning The caller must hold the mm_lock spinlock.
 */
phys_addr_t pmm_alloc_page(void);

Function Length

  • Max. 50 lines (excluding comments)
  • Outsource complex logic to helper functions

Parameters

// Pointer parameters: Input = const, Output = non-const
int vfs_read(const char *path, void *buffer, size_t size);

// Return on errors: 0 = OK, negative values = error
int syscall_open(const char *path, int flags) {
    if (!path)
        return -EINVAL;
    // ...
    return fd;  // >= 0 on success
}

5. Control Structures

Braces

// Always use braces, even for single-line statements
if (condition) {
    do_something();
}

// Multi-line conditions
if (very_long_condition_name &&
    another_condition &&
    yet_another_condition) {
    do_something();
}

// Switch
switch (state) {
    case STATE_INIT:
        init();
        break;
    case STATE_RUN:
        run();
        break;
    default:
        panic("Invalid state");
}

Goto for Cleanup

int complex_function(void) {
    int ret = -ENOMEM;
    void *buf1 = NULL;
    void *buf2 = NULL;

    buf1 = kmalloc(SIZE1);
    if (!buf1)
        goto err;

    buf2 = kmalloc(SIZE2);
    if (!buf2)
        goto err_free_buf1;

    // ... Work ...
    ret = 0;

err_free_buf1:
    kfree(buf1);
err:
    return ret;
}

6. Comments

Inline Comments

// Single-line comments for short explanations
x = y + z;  // Trailing comment if needed

/*
 * Multi-line block comment for longer
 * explanations that span multiple lines.
 */

TODO/FIXME/HACK

// TODO(author): Description of what needs to be done
// FIXME(author): Description of the bug
// HACK(author): Why this hack exists and when to remove it

7. Error Handling

Assertions

#include <kernel/assert.h>

void process_switch(Process *next) {
    KASSERT(next != NULL, "Cannot switch to NULL process");
    KASSERT(next->state == PROCESS_STATE_READY,
            "Process not ready: %d", next->state);
    // ...
}

Error Codes

// Use standard error codes from <errno.h>
#define EOK         0       // No error
#define ENOMEM      12      // Out of memory
#define EINVAL      22      // Invalid argument
#define ENOENT      2       // No such file or directory
// ...

8. Kernel-Specific

Spinlocks

// Always disable IRQs for shared data
spinlock_t lock = SPINLOCK_INIT;

void critical_section(void) {
    irq_flags_t flags;
    spin_lock_irqsave(&lock, &flags);
    
    // Critical section
    
    spin_unlock_irqrestore(&lock, flags);
}

Memory Barriers

// Document explicit barriers
wmb();  // Write memory barrier
rmb();  // Read memory barrier
mb();   // Full memory barrier

Logging

// Use log levels
klog(LOG_DEBUG, "Entering function %s", __func__);
klog(LOG_INFO, "Initialized %d CPUs", cpu_count);
klog(LOG_WARN, "Low memory condition");
klog(LOG_ERROR, "Failed to allocate page: %d", err);
// LOG_PANIC automatically calls panic()

9. Git Commits

Format

<type>(<scope>): <subject>

<body>

<footer>

Types

  • feat: New feature
  • fix: Bugfix
  • refactor: Code refactoring
  • docs: Documentation
  • style: Formatting
  • test: Tests
  • chore: Build/Tooling

Example

feat(mm): implement slab allocator

Added a slab allocator for efficient allocation of
fixed-size kernel objects. Uses per-CPU caches for
lock-free fast path.

Closes #42

10. Review Checklist

  • Code compiles without warnings (-Wall -Wextra -Werror)
  • No memory leaks (all allocations paired with free)
  • All error paths handled
  • Spinlocks used correctly (IRQ-safe if needed)
  • Documentation updated
  • Tests added/updated

"Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live."