Files

90 lines
2.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# K07 — `TaskHandle_t`, explicit `start()` and static trampoline
K07 isolates the exact C/C++ task-entry boundary. A local `CounterTask` object
is constructed without touching the FreeRTOS heap. Only an explicit `start()`
calls `xTaskCreate()` and passes the stable object address as `void*` context.
The kernel later calls a static, non-virtual trampoline, which recovers the
typed object and invokes its private `run()` member.
```text
CounterTask object
-> start()
-> xTaskCreate(static trampoline, context=&object)
-> kernel chooses task
-> trampoline(void*)
-> static_cast<CounterTask*>(context)
-> object.run()
-> state=completed, handle=nullptr, vTaskDelete(nullptr)
```
The wrapper is non-copyable and non-movable because a live kernel task retains
its object address. The destructor does not attempt asynchronous task deletion.
## Three distinct address domains
The checked Hazard3 run records:
```text
C++ object = 0x800fffcc (local object on the retained main stack)
TCB/handle = 0x800038b0 (dynamic kernel object in ucHeap)
task stack = 0x800034a0..0x80003890
result = 500500
```
The object address remains identical before start, in `xTaskCreate` context,
inside the trampoline, inside `run()` and at completion. The numeric handle is
the TCB address and is deliberately different from the C++ object.
## Lifecycle evidence
| Point | Evidence |
| --- | --- |
| 1 | object constructed; heap unchanged; handle null |
| 2 | state `starting` inside explicit start |
| 3 | state `ready`; typed object passed as raw context |
| 4 | `xTaskCreate` returned; handle now identifies the TCB |
| 5 | scheduler not yet started; object still at same address |
| 6 | static trampoline receives the original object address |
| 7 | state `running` before member body |
| 8 | body records current handle, stack bounds and result |
| 10 | state `completed`, handle cleared, current task self-deletes |
| 1112 | raw verifier checks identity/lifecycle and emits PASS |
## Build
```sh
make check
```
Expected summary:
```text
PASS host: explicit start, stable context, duplicate/failure states
PASS ABI: static trampoline; no vtable, RTTI or hosted runtime
PASS task01: explicit start + stable context + trampoline
```
## Debug
```gdb
b explicit_task_debug_checkpoint
p g_checkpoint_trace
p/x g_object_before_start
p/x g_trampoline_context
p/x g_run_this
p/x g_handle_after_start
p/x g_tcb_address
p/x g_stack_low
p/x g_stack_high
p/x g_stack_local
p g_counter_result
p g_task_wrapper_pass
```
## Scope boundary
K07 uses dynamic kernel storage only to study entry and identity. K08 compares
dynamic and caller-supplied static TCB/stack policies and the timing of idle-task
cleanup. A `Task` destructor still does not force-delete a running task.