Docs / Task Deletion

Task Deletion

Overview

bedrock[RTOS] supports task deletion via br_task_delete(), which allows tasks to be removed from the system and their TCB (Task Control Block) slots to be returned to the pool for reuse.

TCB Pool Architecture

Previous Design (Pre-deletion)

Originally, TCB slots were allocated sequentially using a simple counter (tcb_used):

Current Design (With deletion support)

The TCB pool now uses state-based allocation:

API: br_task_delete()

br_err_t br_task_delete(br_tid_t tid);

Parameters

Return Values

ReturnCondition
BR_OKTask successfully deleted
BR_ERR_INVALIDTask ID out of range, task already inactive, or attempting to delete the currently running task

Behavior

  1. Validation: Checks if the task ID is valid and the task exists
  2. Self-deletion prevention: Cannot delete the currently running task
  3. Queue removal: Removes the task from ready queue if present
  4. Cleanup: Clears all TCB fields
  5. Slot return: Marks the slot as BR_TASK_INACTIVE for reuse
Note: A task cannot delete itself. To implement task self-termination, use a supervisor task pattern — see examples below.

Examples

Basic Task Deletion

br_tid_t worker_tid;
static uint8_t worker_stack[512];

void worker_task(void *arg) {
    /* Do work */
    br_sleep_ms(100);
    /* Task completes, but stays in system until deleted */
}

void main_task(void *arg) {
    /* Create worker */
    br_task_create(&worker_tid, "worker", worker_task, NULL,
                   5, worker_stack, sizeof(worker_stack));

    /* Wait for worker to complete */
    br_sleep_ms(200);

    /* Delete worker task - slot can be reused */
    br_task_delete(worker_tid);

    /* Can create new task in the same slot */
    br_task_create(&worker_tid, "new_worker", another_task, NULL,
                   5, worker_stack, sizeof(worker_stack));
}

Deleting Suspended Tasks

/* Suspend a task */
br_task_suspend(worker_tid);

/* Delete while suspended */
br_task_delete(worker_tid);  /* OK - task is not running */

Deleting Blocked Tasks

/* Task is blocked on semaphore/mutex/sleep */
br_task_delete(blocked_tid);  /* OK - task is not running */

Implementation Details

Slot Allocation in br_task_create()

/* Find first free TCB slot */
br_tcb_t *tcb = NULL;
for (int i = 0; i < CONFIG_MAX_TASKS; i++) {
    if (tcb_pool[i].state == BR_TASK_INACTIVE) {
        tcb = &tcb_pool[i];
        break;
    }
}

Task Cleanup Process

/* Remove from ready queue if present */
if (tcb->state == BR_TASK_READY) {
    br_sched_unready(tcb);
}

/* Clear all fields */
tcb->state = BR_TASK_INACTIVE;
tcb->name = NULL;
tcb->entry = NULL;
tcb->arg = NULL;
tcb->stack_base = NULL;
tcb->stack_size = 0;
tcb->stack_canary = NULL;
tcb->sp = NULL;
tcb->next = NULL;

Best Practices

Memory Management

Safe Deletion Patterns

Pattern 1: Supervisor-managed workers

void supervisor(void *arg) {
    while (1) {
        br_tid_t worker;
        create_worker(&worker);
        wait_for_worker_completion(worker);
        br_task_delete(worker);  /* Clean up when done */
    }
}

Pattern 2: Task pool

#define POOL_SIZE 4
br_tid_t task_pool[POOL_SIZE];
uint8_t task_stacks[POOL_SIZE][TASK_STACK_SIZE];

void spawn_task(int slot, br_task_entry_t entry) {
    /* Delete old task if exists */
    if (task_pool[slot] != 0) {
        br_task_delete(task_pool[slot]);
    }

    /* Create new task in slot */
    br_task_create(&task_pool[slot], "pooled", entry, NULL,
                   5, task_stacks[slot], TASK_STACK_SIZE);
}

Limitations