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.
This commit is contained in:
Ilia Sharin 2026-04-23 12:16:52 -04:00
parent f07a368bf1
commit 21751c0025
172 changed files with 19701 additions and 0 deletions

113
06_exec_os/semaphores.md Normal file
View file

@ -0,0 +1,113 @@
[← Home](../README.md) · [Exec Kernel](README.md)
# Semaphores — SignalSemaphore, ObtainSemaphore, Shared/Exclusive
## Overview
Semaphores are the AmigaOS mechanism for **mutual exclusion and shared-read access** to resources. Unlike `Forbid()` (which blocks all scheduling), semaphores allow other tasks to run while waiting — the waiting task simply sleeps until the resource is available.
---
## struct SignalSemaphore
```c
/* exec/semaphores.h — NDK39 */
struct SignalSemaphore {
struct Node ss_Link; /* ln_Type = NT_SIGNALSEM */
/* ln_Name = semaphore name (public) */
WORD ss_NestCount; /* how many times THIS task has obtained it */
struct MinList ss_WaitQueue;/* tasks waiting for exclusive access */
struct SemaphoreRequest ss_MultipleLink; /* shared-reader slot */
struct Task *ss_Owner; /* task holding exclusive lock (or NULL) */
WORD ss_QueueCount; /* number of waiters */
};
```
---
## Initialising a Semaphore
```c
/* Stack or AllocMem — always initialise before use: */
struct SignalSemaphore sem;
InitSemaphore(&sem); /* LVO -558 */
/* Public (named) semaphore — so other tasks can find it: */
sem.ss_Link.ln_Name = "myapp.lock";
AddSemaphore(&sem); /* LVO -564 */
/* Later: */
RemSemaphore(&sem); /* LVO -570 */
```
---
## Exclusive (Write) Lock
```c
/* Block until this task holds the semaphore exclusively: */
ObtainSemaphore(&sem); /* LVO -534 */
/* --- critical section: only one task in here at a time --- */
ReleaseSemaphore(&sem); /* LVO -546 */
```
### Non-Blocking Try
```c
/* Returns TRUE if obtained, FALSE if someone else holds it: */
if (AttemptSemaphore(&sem)) { /* LVO -540 */
/* got it */
ReleaseSemaphore(&sem);
} else {
/* resource busy — do something else */
}
```
---
## Shared (Read) Lock
Multiple tasks may hold a shared lock simultaneously. An exclusive lock blocks until all shared holders release.
```c
ObtainSemaphoreShared(&sem); /* LVO -768 */
/* --- read-only access: multiple tasks may be here at once --- */
ReleaseSemaphore(&sem); /* same release for both modes */
```
---
## Nesting
Semaphores are **reentrant** — the same task can call `ObtainSemaphore` multiple times. The `ss_NestCount` tracks how many times the current owner has obtained it. `ReleaseSemaphore` must be called the same number of times.
```c
ObtainSemaphore(&sem); /* NestCount = 1 */
ObtainSemaphore(&sem); /* NestCount = 2 — safe, same task */
ReleaseSemaphore(&sem); /* NestCount = 1 */
ReleaseSemaphore(&sem); /* NestCount = 0 — fully released, waiters wake */
```
---
## Semaphore vs Forbid/Disable
| Mechanism | Blocks | Other tasks run while waiting? | Interrupt safe? |
|---|---|---|---|
| `Forbid()` | All task switching | ❌ No | ✅ (interrupts still run) |
| `Disable()` | All task switching + interrupts | ❌ No | ✅ |
| `ObtainSemaphore()` | Only contending tasks | ✅ Yes | ❌ Not from interrupt context |
Use semaphores for anything that may take more than a few microseconds. Use `Forbid()` only for very short list manipulations.
---
## References
- NDK39: `exec/semaphores.h`
- ADCD 2.1: `InitSemaphore`, `ObtainSemaphore`, `ObtainSemaphoreShared`, `ReleaseSemaphore`, `AttemptSemaphore`
- *Amiga ROM Kernel Reference Manual: Exec* — semaphores chapter