/* ** task.h - Task scheduler ** ** See Copyright Notice in mruby.h */ #ifndef MRUBY_TASK_H #define MRUBY_TASK_H #include /* * Task status values (bit-mapped) */ enum { MRB_TASK_STATUS_DORMANT = 0x00, /* Not started or finished */ MRB_TASK_STATUS_READY = 0x02, /* Ready to run */ MRB_TASK_STATUS_RUNNING = 0x03, /* Currently executing */ MRB_TASK_STATUS_WAITING = 0x04, /* Waiting for condition */ MRB_TASK_STATUS_SUSPENDED = 0x08, /* Manually suspended */ }; /* * Task wait reason */ enum { MRB_TASK_REASON_NONE = 0x00, /* No specific reason */ MRB_TASK_REASON_SLEEP = 0x01, /* Sleeping for time */ MRB_TASK_REASON_MUTEX = 0x02, /* Waiting for mutex (reserved) */ MRB_TASK_REASON_JOIN = 0x04, /* Waiting for another task */ }; /* * Task structure - represents a single task in the scheduler * * Memory-optimized layout: * - Removed priority_preemption (always equals priority): 1 byte * - Removed started flag (inferred from c.status): 1 byte * - Unified wakeup_tick/join/mutex into single union: 4 bytes * - Removed redundant proc field (stored in c.ci->proc): 8 bytes * - Unified timeslice/result into state union: ~4 bytes * Total savings: ~18 bytes per task (14% reduction) */ typedef struct mrb_task { struct mrb_task *next; /* Linked list pointer */ uint8_t priority; /* Priority (0-255, 0=highest) */ uint8_t status; /* Current status (TASKSTATUS enum) */ uint8_t reason; /* Wait reason (TASKREASON enum) */ mrb_value name; /* Optional task name */ /* Wait-specific data - mutually exclusive based on reason field */ union { uint32_t wakeup_tick; /* Tick count to wake up (REASON_SLEEP) */ const struct mrb_task *join; /* Task being waited on (REASON_JOIN) */ void *mutex; /* Mutex pointer (REASON_MUTEX, reserved) */ } wait; mrb_value self; /* Ruby Task object reference */ /* State-specific data - mutually exclusive based on status */ union { volatile uint8_t timeslice; /* Remaining ticks (RUNNING only) */ mrb_value result; /* Task return value (DORMANT only) */ } state; struct mrb_context c; /* Execution context (stack, callinfo, etc) */ } mrb_task; /* * Task queue configuration * (mrb_task_state is defined in mruby.h) */ #define MRB_NUM_TASK_QUEUE 4 /* Queue indices */ #define MRB_TASK_QUEUE_DORMANT 0 #define MRB_TASK_QUEUE_READY 1 #define MRB_TASK_QUEUE_WAITING 2 #define MRB_TASK_QUEUE_SUSPENDED 3 /* Configuration */ #ifndef MRB_TICK_UNIT #define MRB_TICK_UNIT 4 /* Tick period in milliseconds */ #endif #ifndef MRB_TIMESLICE_TICK_COUNT #define MRB_TIMESLICE_TICK_COUNT 3 /* Number of ticks per timeslice */ #endif #define TASK_STACK_INIT_SIZE 64 /* Initial task stack size */ #define TASK_CI_INIT_SIZE 4 /* Initial task callinfo size */ /* * HAL (Hardware Abstraction Layer) functions * Platform-specific implementations must provide these */ void mrb_task_hal_init(mrb_state *mrb); void mrb_task_hal_final(mrb_state *mrb); void mrb_task_enable_irq(void); void mrb_task_disable_irq(void); void mrb_task_hal_idle_cpu(mrb_state *mrb); /* * GC integration */ void mrb_task_mark_all(mrb_state *mrb); /* * Core task scheduler API */ MRB_API void mrb_tick(mrb_state *mrb); MRB_API mrb_value mrb_task_run(mrb_state *mrb); MRB_API mrb_value mrb_task_run_once(mrb_state *mrb); /* * Task creation API */ MRB_API mrb_value mrb_create_task(mrb_state *mrb, struct RProc *proc, mrb_value name, mrb_value priority, mrb_value top_self); /* * Synchronous execution API (for picoruby-wasm) */ MRB_API mrb_value mrb_execute_proc_synchronously(mrb_state *mrb, mrb_value proc, mrb_int argc, const mrb_value *argv); /* * Task control API * Note: mrb_task_run is the main scheduler loop (for picoruby-sandbox and picoruby-wasm) */ MRB_API void mrb_suspend_task(mrb_state *mrb, mrb_value task); MRB_API void mrb_resume_task(mrb_state *mrb, mrb_value task); MRB_API void mrb_terminate_task(mrb_state *mrb, mrb_value task); MRB_API mrb_bool mrb_stop_task(mrb_state *mrb, mrb_value task); MRB_API mrb_value mrb_task_value(mrb_state *mrb, mrb_value task); MRB_API mrb_value mrb_task_status(mrb_state *mrb, mrb_value self); /* * Task context management API (for picoruby-sandbox) */ MRB_API void mrb_task_init_context(mrb_state *mrb, mrb_value task, struct RProc *proc); MRB_API void mrb_task_reset_context(mrb_state *mrb, mrb_value task); MRB_API void mrb_task_proc_set(mrb_state *mrb, mrb_value task, struct RProc *proc); #endif /* MRUBY_TASK_H */