amiga-bootcamp/06_exec_os/tasks_processes.md
Ilia Sharin 21751c0025 docs(amiga): complete AmigaOS 3.1/3.2 developer reference — 172 files across 17 sections
Comprehensive technical documentation covering:
- Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives
- Boot sequence: cold boot through startup-sequence
- Binary format: HUNK executable spec, relocation, debug info
- Linking & ABI: .fd files, LVO tables, register calling conventions
- Exec kernel: tasks, interrupts, memory, signals, semaphores
- AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting
- Graphics: planar bitmaps, Copper programming, HAM/EHB modes
- Intuition: screens, windows, IDCMP, BOOPSI
- Devices: trackdisk, SCSI, serial, timer, audio, keyboard
- Libraries: utility, expansion, IFFParse, locale, ARexx
- Networking: bsdsocket API, SANA-II, TCP/IP stack comparison
- Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging
- Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies
- CPU & MMU: 68040/060 emulation libs, PMMU, cache management
- Driver development: SANA-II, Picasso96/RTG, AHI audio

All files include breadcrumb navigation. No local paths or proprietary content.
2026-04-23 12:17:35 -04:00

5 KiB
Raw Blame History

← Home · Exec Kernel

Tasks and Processes — Structures, States, Scheduling

Overview

AmigaOS uses cooperative/preemptive scheduling. Tasks are the fundamental unit of execution; Processes are Tasks with an additional DOS environment (message port, CLI, segment list). The scheduler runs at each quantum (50 Hz VBL interrupt) and after any Signal() or Wait() call.


struct Task

/* exec/tasks.h */
struct Task {
    struct Node  tc_Node;      /* ln_Type=NT_TASK or NT_PROCESS */
                               /* ln_Pri = scheduling priority */
                               /* ln_Name = task name string */
    UBYTE        tc_Flags;     /* TF_LAUNCH, TF_STRIKE, TF_EXCEPT */
    UBYTE        tc_State;     /* TS_RUN, TS_READY, TS_WAIT, TS_EXCEPT */
    BYTE         tc_IDNestCnt; /* interrupt disable nesting */
    BYTE         tc_TDNestCnt; /* task disable (Forbid) nesting */
    ULONG        tc_SigAlloc;  /* allocated signal bits mask */
    ULONG        tc_SigWait;   /* signals task is waiting for */
    ULONG        tc_SigRecvd;  /* signals received */
    ULONG        tc_SigExcept; /* exception signals */
    /* ... stack bounds, context, exception handler ... */
    APTR         tc_SPLower;   /* lowest valid stack address */
    APTR         tc_SPUpper;   /* highest valid stack address + 2 */
    APTR         tc_SPReg;     /* saved stack pointer (when not running) */
};

struct Process (extends Task)

/* dos/dosextens.h */
struct Process {
    struct Task  pr_Task;       /* embedded Task */
    struct MsgPort pr_MsgPort;  /* I/O message port */
    UWORD        pr_Pad;
    BPTR         pr_SegList;    /* BPTR to segment list */
    LONG         pr_StackSize;
    APTR         pr_GlobVec;    /* BCPL global vector */
    LONG         pr_TaskNum;    /* CLI task number */
    BPTR         pr_StackBase;  /* base of stack (BPTR) */
    LONG         pr_Result2;    /* secondary result */
    BPTR         pr_CurrentDir; /* current directory lock */
    BPTR         pr_CIS;        /* current input stream */
    BPTR         pr_COS;        /* current output stream */
    APTR         pr_ConsoleTask;
    APTR         pr_FileSystemTask;
    BPTR         pr_CLI;        /* CLI structure (NULL if WB) */
    ...
    struct MsgPort *pr_ReturnAddr; /* return address for CLI tasks */
    APTR         pr_PktWait;
    struct SaveMsg pr_ExitData;
    UBYTE        *pr_Arguments;  /* argument string */
    struct MinList pr_LocalVars; /* local shell variables */
    ULONG        pr_ShellPrivate;
    BPTR         pr_CES;         /* current error stream */
};

Task States

State Value Meaning
TS_INVALID 0 Not a valid task
TS_ADDED 1 Just added, not yet scheduled
TS_RUN 2 Currently running (only one task)
TS_READY 3 On the TaskReady list, waiting for CPU
TS_WAIT 4 Blocked on Wait() — on TaskWait list
TS_EXCEPT 5 Handling an exception
TS_REMOVED 6 Removed from scheduling

Scheduling: Priority-Based Round Robin

The scheduler (exec.library internal) picks the highest-priority task from SysBase→TaskReady. Among equal-priority tasks, they get equal time slices (round-robin).

  • Default priority: 0
  • Range: 128 to +127 (higher = more CPU)
  • OS tasks run at priority 1020
  • Input handler: priority 20
  • Disk tasks: priority 10
SetTaskPri(FindTask(NULL), 5);  /* raise current task to priority 5 */

Creating Tasks and Processes

/* Simple task (exec level): */
struct Task *t = AllocMem(sizeof(struct Task), MEMF_PUBLIC|MEMF_CLEAR);
t->tc_Node.ln_Name = "MyTask";
t->tc_Node.ln_Pri  = 0;
t->tc_SPLower = stack;
t->tc_SPUpper = stack + stacksize;
t->tc_SPReg   = (APTR)((ULONG)stack + stacksize);
AddTask(t, myTaskFunc, NULL);

/* DOS Process (with message port, filesystem access): */
struct Process *p = CreateNewProcTags(
    NP_Entry,     myFunc,
    NP_Name,      "MyProcess",
    NP_StackSize, 8192,
    NP_Priority,  0,
    TAG_DONE);

Task State Machine

stateDiagram-v2
    [*] --> READY : AddTask()
    READY --> RUN : Scheduler picks task
    RUN --> READY : Quantum expired or higher-priority task
    RUN --> WAIT : Wait(signal_mask)
    WAIT --> READY : Signal() delivers awaited signals
    RUN --> EXCEPT : Exception signal received
    EXCEPT --> RUN : Exception handler returns
    RUN --> [*] : Task function returns / RemTask()

FindTask and Task Identity

struct Task *me = FindTask(NULL);   /* NULL = current task */
printf("Running as: %s\n", me->tc_Node.ln_Name);

/* Check if we are a Process (vs plain Task): */
if (me->tc_Node.ln_Type == NT_PROCESS) {
    struct Process *pr = (struct Process *)me;
    /* access pr_CLI, pr_MsgPort, etc. */
}

References

  • NDK39: exec/tasks.h, dos/dosextens.h
  • ADCD 2.1: AddTask, RemTask, FindTask, SetTaskPri, CreateNewProc
  • Amiga ROM Kernel Reference Manual: Exec — tasks and scheduling chapter