diff --git a/mrbgems/mruby-task/include/task.h b/mrbgems/mruby-task/include/task.h index bebb00375..7278cac55 100644 --- a/mrbgems/mruby-task/include/task.h +++ b/mrbgems/mruby-task/include/task.h @@ -34,17 +34,18 @@ enum { * Task structure - represents a single task in the scheduler * * Memory-optimized layout: - * - Removed priority_preemption (always equals priority) - * - Removed started flag (inferred from c.status != MRB_FIBER_CREATED) - * - Unified wakeup_tick/join/mutex into single union (mutually exclusive) - * Total savings: ~8 bytes per task + * - 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) */ - volatile uint8_t timeslice; /* Remaining time slice ticks */ mrb_value name; /* Optional task name */ /* Wait-specific data - mutually exclusive based on reason field */ @@ -55,8 +56,13 @@ typedef struct mrb_task { } wait; mrb_value self; /* Ruby Task object reference */ - mrb_value result; /* Task return value */ - mrb_value proc; /* Proc containing task code */ + + /* 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; diff --git a/mrbgems/mruby-task/src/task.c b/mrbgems/mruby-task/src/task.c index 48b3f68fb..19d731e2e 100644 --- a/mrbgems/mruby-task/src/task.c +++ b/mrbgems/mruby-task/src/task.c @@ -126,9 +126,10 @@ mrb_task_mark_all(mrb_state *mrb) /* Mark task-specific values */ mrb_gc_mark_value(mrb, t->self); - mrb_gc_mark_value(mrb, t->result); + if (t->status == MRB_TASK_STATUS_DORMANT) { + mrb_gc_mark_value(mrb, t->state.result); + } mrb_gc_mark_value(mrb, t->name); - mrb_gc_mark_value(mrb, t->proc); t = t->next; } @@ -314,7 +315,7 @@ execute_task(mrb_state *mrb, mrb_task *t) /* Set task as running */ t->status = MRB_TASK_STATUS_RUNNING; - t->timeslice = MRB_TIMESLICE_TICK_COUNT; + t->state.timeslice = MRB_TIMESLICE_TICK_COUNT; /* Switch to task context */ prev_c = mrb->c; @@ -343,7 +344,7 @@ execute_task(mrb_state *mrb, mrb_task *t) t->c.vmexec = TRUE; /* Execute task - PC is saved in ci->pc from previous run */ - t->result = mrb_vm_exec(mrb, proc, pc); + t->state.result = mrb_vm_exec(mrb, proc, pc); /* Clear vmexec flag */ t->c.vmexec = FALSE; @@ -386,9 +387,9 @@ mrb_tick(mrb_state *mrb) /* Decrease timeslice for running task */ t = q_ready_; - if (t && t->status == MRB_TASK_STATUS_RUNNING && t->timeslice > 0) { - t->timeslice--; - if (t->timeslice == 0) { + if (t && t->status == MRB_TASK_STATUS_RUNNING && t->state.timeslice > 0) { + t->state.timeslice--; + if (t->state.timeslice == 0) { switching_ = TRUE; /* Trigger context switch */ } } @@ -652,7 +653,7 @@ mrb_task_s_new(mrb_state *mrb, mrb_value self) t->status = MRB_TASK_STATUS_READY; t->reason = MRB_TASK_REASON_NONE; t->name = name_val; - t->proc = blk; /* Store proc to keep it from being GC'd */ + /* Note: proc is stored in t->c.ci->proc and marked via callinfo GC */ /* Create Ruby object to hold task */ task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_get(mrb, "Task"), @@ -1094,7 +1095,7 @@ mrb_task_join(mrb_state *mrb, mrb_value self) /* If task is already dormant, return immediately */ if (t->status == MRB_TASK_STATUS_DORMANT) { - return t->result; + return t->state.result; } /* Wait for task to complete */ @@ -1109,7 +1110,7 @@ mrb_task_join(mrb_state *mrb, mrb_value self) /* Trigger context switch */ switching_ = TRUE; - return t->result; + return t->state.result; } /*