generated from sirlilpanda/kicad-project-template-actionless
Added the zig_main project to software for zig based implementation of code for robot
This commit is contained in:
233
software/zig_main/imports/pthread.zig
Normal file
233
software/zig_main/imports/pthread.zig
Normal file
@@ -0,0 +1,233 @@
|
||||
// Zig wrappers for ESP-IDF's POSIX pthread implementation (backed by FreeRTOS).
|
||||
//
|
||||
// Symbols come from idf-sys.zig (generated by `zig translate-c include/stubs.h`
|
||||
// with ESP_IDF_COMP_PTHREAD_ENABLED defined, which pulls in pthread.h and
|
||||
// esp_pthread.h).
|
||||
//
|
||||
// Error handling:
|
||||
// POSIX pthread_* functions return 0 on success, errno on failure → `check()`.
|
||||
// ESP-IDF esp_pthread_* functions return esp_err_t → `errors.espCheckError()`.
|
||||
|
||||
const sys = @import("sys");
|
||||
const errors = @import("error");
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Error helper for POSIX-style return codes
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Error = error{PthreadError};
|
||||
|
||||
fn check(rc: c_int) Error!void {
|
||||
if (rc != 0) return error.PthreadError;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Type aliases (from idf-sys)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Thread_t = sys.pthread_t;
|
||||
pub const Attr_t = sys.pthread_attr_t;
|
||||
pub const Mutex_t = sys.pthread_mutex_t;
|
||||
pub const MutexAttr_t = sys.pthread_mutexattr_t;
|
||||
pub const Cond_t = sys.pthread_cond_t;
|
||||
pub const CondAttr_t = sys.pthread_condattr_t;
|
||||
pub const Key_t = sys.pthread_key_t;
|
||||
pub const Once_t = sys.pthread_once_t;
|
||||
pub const SchedParam = sys.sched_param;
|
||||
pub const Timespec = sys.timespec;
|
||||
|
||||
/// ESP-IDF-specific pthread configuration (stack size, priority, core pinning, etc.).
|
||||
pub const EspCfg = sys.esp_pthread_cfg_t;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Thread — lifecycle & identity
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Thread = struct {
|
||||
/// Create a thread with optional attributes. Returns the thread ID.
|
||||
pub fn create(
|
||||
attr: ?*const Attr_t,
|
||||
start_fn: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,
|
||||
arg: ?*anyopaque,
|
||||
) !Thread_t {
|
||||
var tid: Thread_t = undefined;
|
||||
try check(sys.pthread_create(&tid, attr, start_fn, arg));
|
||||
return tid;
|
||||
}
|
||||
|
||||
/// Wait for a thread to terminate; returns its exit value.
|
||||
pub fn join(tid: Thread_t) !?*anyopaque {
|
||||
var value: ?*anyopaque = null;
|
||||
try check(sys.pthread_join(tid, &value));
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Detach a thread so its resources are freed automatically on exit.
|
||||
pub fn detach(tid: Thread_t) !void {
|
||||
try check(sys.pthread_detach(tid));
|
||||
}
|
||||
|
||||
/// Terminate the calling thread with `retval`.
|
||||
pub fn exit(retval: ?*anyopaque) noreturn {
|
||||
sys.pthread_exit(retval);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
/// Return the thread ID of the calling thread.
|
||||
pub fn self() Thread_t {
|
||||
return sys.pthread_self();
|
||||
}
|
||||
|
||||
/// Return `true` if two thread IDs refer to the same thread.
|
||||
pub fn equal(t1: Thread_t, t2: Thread_t) bool {
|
||||
return sys.pthread_equal(t1, t2) != 0;
|
||||
}
|
||||
|
||||
/// Yield the processor to another ready thread.
|
||||
pub fn yield() void {
|
||||
sys.pthread_yield();
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Thread attributes
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Attr = struct {
|
||||
pub fn init(attr: *Attr_t) !void {
|
||||
try check(sys.pthread_attr_init(attr));
|
||||
}
|
||||
pub fn deinit(attr: *Attr_t) !void {
|
||||
try check(sys.pthread_attr_destroy(attr));
|
||||
}
|
||||
pub fn setStackSize(attr: *Attr_t, size: usize) !void {
|
||||
try check(sys.pthread_attr_setstacksize(attr, size));
|
||||
}
|
||||
pub fn getStackSize(attr: *const Attr_t) !usize {
|
||||
var sz: usize = 0;
|
||||
try check(sys.pthread_attr_getstacksize(attr, &sz));
|
||||
return sz;
|
||||
}
|
||||
pub fn setDetachState(attr: *Attr_t, state: c_int) !void {
|
||||
try check(sys.pthread_attr_setdetachstate(attr, state));
|
||||
}
|
||||
pub fn getDetachState(attr: *const Attr_t) !c_int {
|
||||
var s: c_int = 0;
|
||||
try check(sys.pthread_attr_getdetachstate(attr, &s));
|
||||
return s;
|
||||
}
|
||||
pub fn setSchedParam(attr: *Attr_t, param: *const SchedParam) !void {
|
||||
try check(sys.pthread_attr_setschedparam(attr, param));
|
||||
}
|
||||
pub fn getSchedParam(attr: *const Attr_t) !SchedParam {
|
||||
var p: SchedParam = .{};
|
||||
try check(sys.pthread_attr_getschedparam(attr, &p));
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mutex
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Mutex = struct {
|
||||
pub fn init(mutex: *Mutex_t, attr: ?*const MutexAttr_t) !void {
|
||||
try check(sys.pthread_mutex_init(mutex, attr));
|
||||
}
|
||||
pub fn deinit(mutex: *Mutex_t) !void {
|
||||
try check(sys.pthread_mutex_destroy(mutex));
|
||||
}
|
||||
pub fn lock(mutex: *Mutex_t) !void {
|
||||
try check(sys.pthread_mutex_lock(mutex));
|
||||
}
|
||||
pub fn tryLock(mutex: *Mutex_t) !void {
|
||||
try check(sys.pthread_mutex_trylock(mutex));
|
||||
}
|
||||
pub fn unlock(mutex: *Mutex_t) !void {
|
||||
try check(sys.pthread_mutex_unlock(mutex));
|
||||
}
|
||||
pub fn timedLock(mutex: *Mutex_t, timeout: *const Timespec) !void {
|
||||
try check(sys.pthread_mutex_timedlock(mutex, timeout));
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Condition variable
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Cond = struct {
|
||||
pub fn init(cond: *Cond_t, attr: ?*const CondAttr_t) !void {
|
||||
try check(sys.pthread_cond_init(cond, attr));
|
||||
}
|
||||
pub fn deinit(cond: *Cond_t) !void {
|
||||
try check(sys.pthread_cond_destroy(cond));
|
||||
}
|
||||
pub fn wait(cond: *Cond_t, mutex: *Mutex_t) !void {
|
||||
try check(sys.pthread_cond_wait(cond, mutex));
|
||||
}
|
||||
pub fn timedWait(cond: *Cond_t, mutex: *Mutex_t, abstime: *const Timespec) !void {
|
||||
try check(sys.pthread_cond_timedwait(cond, mutex, abstime));
|
||||
}
|
||||
pub fn signal(cond: *Cond_t) !void {
|
||||
try check(sys.pthread_cond_signal(cond));
|
||||
}
|
||||
pub fn broadcast(cond: *Cond_t) !void {
|
||||
try check(sys.pthread_cond_broadcast(cond));
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Thread-local storage (TLS) keys
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const Key = struct {
|
||||
pub fn create(destructor: ?*const fn (?*anyopaque) callconv(.c) void) !Key_t {
|
||||
var key: Key_t = undefined;
|
||||
try check(sys.pthread_key_create(&key, destructor));
|
||||
return key;
|
||||
}
|
||||
pub fn delete(key: Key_t) !void {
|
||||
try check(sys.pthread_key_delete(key));
|
||||
}
|
||||
pub fn setSpecific(key: Key_t, value: ?*const anyopaque) !void {
|
||||
try check(sys.pthread_setspecific(key, value));
|
||||
}
|
||||
pub fn getSpecific(key: Key_t) ?*anyopaque {
|
||||
return sys.pthread_getspecific(key);
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Once-only initialisation
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub fn once(once_ctrl: *Once_t, init_fn: *const fn () callconv(.c) void) !void {
|
||||
try check(sys.pthread_once(once_ctrl, init_fn));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ESP-IDF pthread extensions (esp_pthread.h)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub const EspThread = struct {
|
||||
/// Return a default ESP pthread configuration populated from menuconfig values.
|
||||
pub fn getDefaultConfig() EspCfg {
|
||||
return sys.esp_pthread_get_default_config();
|
||||
}
|
||||
|
||||
/// Set per-thread creation parameters for the next `pthread_create()` call.
|
||||
/// Overrides stack size, priority, core affinity, and thread name.
|
||||
pub fn setConfig(cfg: *const EspCfg) !void {
|
||||
try errors.espCheckError(sys.esp_pthread_set_cfg(cfg));
|
||||
}
|
||||
|
||||
/// Retrieve the currently active ESP pthread configuration.
|
||||
pub fn getConfig(cfg: *EspCfg) !void {
|
||||
try errors.espCheckError(sys.esp_pthread_get_cfg(cfg));
|
||||
}
|
||||
|
||||
/// Initialise the ESP pthread library (called internally by ESP-IDF startup).
|
||||
pub fn init() !void {
|
||||
try errors.espCheckError(sys.esp_pthread_init());
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user