Viewing: sync.h
📄 sync.h (Read Only) ⬅ To go back
#ifndef SYNC_H
#define SYNC_H

#include <stdint.h>
#include "spinlock.h"

/* ------------------------------------------------------------------ */
/* Kernel counting semaphore (blocking, sleep/wake — NOT spin-wait)   */
/* ------------------------------------------------------------------ */

#define KSEM_MAX_WAITERS 16

struct process; /* forward */

typedef struct ksem {
    spinlock_t    lock;
    int32_t       count;
    struct process* waiters[KSEM_MAX_WAITERS];
    uint32_t      nwaiters;
} ksem_t;

void ksem_init(ksem_t* s, int32_t initial_count);
void ksem_wait(ksem_t* s);

/* Wait with timeout (milliseconds). 0 = wait forever.
 * Returns 0 on success, 1 on timeout. */
int  ksem_wait_timeout(ksem_t* s, uint32_t timeout_ms);

void ksem_signal(ksem_t* s);

/* ------------------------------------------------------------------ */
/* Kernel mutex (binary semaphore)                                    */
/* ------------------------------------------------------------------ */

typedef struct kmutex {
    ksem_t sem;
} kmutex_t;

void kmutex_init(kmutex_t* m);
void kmutex_lock(kmutex_t* m);
void kmutex_unlock(kmutex_t* m);

/* ------------------------------------------------------------------ */
/* Kernel mailbox (fixed-size circular queue + semaphores)             */
/* ------------------------------------------------------------------ */

#define KMBOX_MAX_MSGS 32

typedef struct kmbox {
    void*    msgs[KMBOX_MAX_MSGS];
    uint32_t head;
    uint32_t tail;
    uint32_t count;
    uint32_t capacity;
    ksem_t   not_empty;
    ksem_t   not_full;
    spinlock_t lock;
} kmbox_t;

int  kmbox_init(kmbox_t* mb, uint32_t size);
void kmbox_free(kmbox_t* mb);
void kmbox_post(kmbox_t* mb, void* msg);
int  kmbox_trypost(kmbox_t* mb, void* msg);

/* Fetch with timeout (ms). 0 = wait forever.
 * Returns 0 on success, 1 on timeout. */
int  kmbox_fetch(kmbox_t* mb, void** msg, uint32_t timeout_ms);
int  kmbox_tryfetch(kmbox_t* mb, void** msg);

/* ------------------------------------------------------------------ */
/* Kernel condition variable (paired with kmutex_t)                    */
/* ------------------------------------------------------------------ */

#define KCOND_MAX_WAITERS 16

typedef struct kcond {
    spinlock_t      lock;
    struct process* waiters[KCOND_MAX_WAITERS];
    uint32_t        nwaiters;
} kcond_t;

void kcond_init(kcond_t* cv);

/* Release mutex, sleep until signaled, re-acquire mutex.
 * Returns 0 on success, 1 on timeout (timeout_ms == 0 means wait forever). */
int  kcond_wait(kcond_t* cv, kmutex_t* mtx, uint32_t timeout_ms);

/* Wake one waiter. */
void kcond_signal(kcond_t* cv);

/* Wake all waiters. */
void kcond_broadcast(kcond_t* cv);

#endif /* SYNC_H */