Threads are linked in structures call Priority Queues or PriQs.
Priority queues are a double-linked list of thread priority groups. Each group is a double-linked list of threads of the same priority.
Six chain pointers are used for the links of a PriQ:
TCBpTCBPriHigher (TCB + 0x178)
TCBpTCBPriLower (TCB + 0x17c)
TCBpTCBPriNext (TCB + 0x180)
TCBpTCBPriPrev (TCB + 0x184)
By default these chain pointers are set to point to their own TCB.
TCBpTCBPriHigher and TCBpTCBPriLower link the heads of each priority group.
TCBpTCBNext and TCBpTCBPrev link the TCBs within each priority group.
A number of PriQs are defined. Each is anchored from a global symbol pointer:
Notes:
For the current process ptda_pTCBPriQCritSec (PTDA +0x2e4) is a also a global symbol. Out of current context it can be located relative to the process' PTDA address.
The TCB address of the thread that has entered critical section is saved in ptda_pTCBCritSec (PTDA +0x2e0)
Sleeping threads are queued on priority queues but in a manner to favour wake-up processing. The Block-Id is hashed to form an index into a table of PriQ anchors. The table is located at global symbol:
_aptcbSleep
Each anchor points to a chain of PriQs of threads sleeping on the same Block-Id. The head TCB of each PriQ within a hashed chain is doubly linked from:
TCBpTCBPriNextQ (TCB + 0x170)
TCBpTCBPriPrevQ (TCB + 0x174)
Threads that happen to sleep on the same Block-Id as a multi-wake-up block-id are guaranteed not to be put in the same chain as the multi-wake-up threads.
When multi-wake-up threads wake their entire sleeping PriQ is moved to a chain of PriQs for threads in dly state. The delayed thread PriQ is anchored from global symbol:
_ptcbPriQDelayed
Since ptcbPriQDelayed anchors a chain of PriQs, the head of each PriQ is doubly-linked using TCBpTCBPriQNextQ and TCBpTCBPriQPrevQ.