# K08 — dynamic/static task storage, deletion and lifetime K08 gives identical worker behavior two storage policies: - `DynamicTask` calls `xTaskCreate`; FreeRTOS allocates TCB and stack from `heap_4` and the idle task later reclaims them after self-deletion; - `StaticTask` calls `xTaskCreateStatic` with caller-owned `StaticTask_t` and `StackType_t[]` located in `.bss`; task deletion never transfers ownership of those buffers to the kernel. Both wrappers remain non-copyable, non-movable and non-virtual. The static storage is a separate `StaticTaskStorage` object so its TCB/stack are visibly caller supplied and their lifetime is independent from the wrapper's handle. ## Measured Hazard3 result ```text dynamic heap cost = 0x470 = 1136 bytes free before idle cleanup = 0x3b80 free after idle cleanup = 0x3ff0 (baseline) static stack words = 0x100 = 256 static stack bytes = 0x400 = 1024 ``` The dynamic worker sets `completed` and clears its wrapper handle before `vTaskDelete(nullptr)`, but its kernel storage is only placed on the termination list at that point. A static verifier first captures the reduced heap, blocks for two ticks to let idle run, then observes full recovery. ## Evidence | Stage | Heap relation | | --- | --- | | baseline | initialized `heap_4`, no worker kernel object | | dynamic start | free decreases by 1136 B | | static start | free unchanged from dynamic-start value | | static verifier create | free unchanged again | | workers completed/self-deleted | dynamic 1136 B still not reclaimed | | verifier blocks, idle cleans | free increases by 1136 B to baseline | Addresses prove dynamic TCB/stack lie in `ucHeap`, while the static TCB and stack equal the caller storage addresses in `.bss`. Both workers compute 500500. ## Build ```sh make check ``` Expected: ```text PASS host: dynamic/static policies, stable caller storage and units PASS ABI: dynamic/static trampolines; caller storage in .bss; no vtable PASS task01: dynamic/static task storage + idle cleanup ``` ## Debug ```gdb b task_storage_debug_checkpoint p g_heap_baseline p g_heap_after_dynamic_start p g_heap_after_static_start p g_heap_before_idle_cleanup p g_heap_after_idle_cleanup p/x g_dynamic_tcb p/x g_dynamic_stack_low p/x g_static_tcb p/x g_static_tcb_storage p/x g_static_stack_low p/x g_static_stack_storage p g_static_stack_words p g_static_stack_bytes p g_task_storage_pass ``` ## Scope boundary Task deletion does not safely unwind arbitrary application resources on its stack. The workers arrange normal member completion before self-deletion. Static storage must outlive the task and must not be reused merely because a stop was requested; completion/deletion must be established first.