PTQueueInit Layer
The PTQueueInit.c file manages thread queues in mCertiKOS. The queues enable controlled scheduling and management of thread states. mCertiKOS employs a doubly linked list structure for thread queues, with each thread control block (TCB) linked to the next and previous threads in the queue. The primary functions in this file are:
tqueue_init: Initializes all thread queues.tqueue_enqueue: Adds a thread to the end of a specified queue.tqueue_dequeue: Removes and returns the first thread from a specified queue.tqueue_remove: Removes a specified thread from any position in the queue.
These functions are essential for managing threads as they enter, wait, or exit scheduling queues.
Function: tqueue_init
tqueue_initvoid tqueue_init(unsigned int mbi_addr)
{
tcb_init(mbi_addr);
unsigned int id;
for (id = 0; id < NUM_IDS; id++) {
//* NumIds + 1 queue in total
tqueue_init_at_id(id);
}
}Purpose: Initializes each thread queue, setting up a clear starting state where all queues are empty. It first initializes TCBs, then initializes each thread queue using
tqueue_init_at_id.Mechanism:
Initialize TCBs:
Calls
tcb_init(mbi_addr)to initialize all thread control blocks withTSTATE_DEADstate and set up initial properties for each TCB.
Initialize Each Queue:
Loops through each queue ID (
0toNUM_IDS - 1) and callstqueue_init_at_id(id)to set bothheadandtailof the queue toNUM_IDS, indicating that the queue is empty.
Use Case: Called at system startup to set up a clean, empty state for all thread queues. This step is essential for ensuring proper management of thread queues when the system begins to operate.
Function: tqueue_enqueue
tqueue_enqueuevoid tqueue_enqueue(unsigned int chid, unsigned int pid)
{
unsigned int tail_pid;
tail_pid = tqueue_get_tail(chid);
if (tail_pid != NUM_IDS)
{
//* queue is not empty, link the current tail to pid
tcb_set_next(tail_pid, pid);
}
else
{
//* queue is empty, set head to pid
tqueue_set_head(chid, pid);
}
//* link pid to the previous tail and set as the new tail
tcb_set_prev(pid, tail_pid);
tqueue_set_tail(chid, pid);
}Purpose: Adds a thread (TCB) with ID
pidto the end of the specified queue (chid). This function ensures that each thread enters the queue in the correct position and updates the queue’s tail pointer to maintain the linked list structure.Mechanism:
Get the Current Tail:
Calls
tqueue_get_tail(chid)to retrieve the current tail of the queue.
Check if Queue is Empty:
If
tail_pidisNUM_IDS, the queue is empty. In this case, the new thread (pid) becomes theheadof the queue, sotqueue_set_head(chid, pid)is called to setpidas the head.If the queue is not empty, it links the current tail to the new thread by calling
tcb_set_next(tail_pid, pid).
Update the Tail:
tcb_set_prev(pid, tail_pid)sets the previous pointer of the new thread (pid) to the former tail.tqueue_set_tail(chid, pid)sets the new thread as the tail of the queue, completing the enqueue operation.
Use Case: Used whenever a new thread becomes ready for scheduling or needs to be added to any queue (such as the ready queue). This function allows the system to maintain a linked list of threads waiting in each queue.
Function: tqueue_dequeue
tqueue_dequeueunsigned int tqueue_dequeue(unsigned int chid)
{
unsigned int head_id, head_next_id;
head_id = tqueue_get_head(chid);
if (head_id == NUM_IDS)
{
//* queue is empty
return NUM_IDS;
}
head_next_id = tcb_get_next(head_id);
if (head_next_id != NUM_IDS)
{
//* head has a next element, unlink the previous pointer
tcb_set_prev(head_next_id, NUM_IDS);
}
else
{
//* no next element, set tail to NUM_IDS (empty queue)
tqueue_set_tail(chid, NUM_IDS);
}
tcb_set_next(head_id, NUM_IDS);
tqueue_set_head(chid, head_next_id);
return head_id;
}Purpose: Removes the thread at the head of the specified queue (
chid) and returns its ID. This operation supports removing the next thread that is ready to run or has completed its task.Mechanism:
Get the Head of the Queue:
Calls
tqueue_get_head(chid)to retrieve the ID of the current head of the queue.If the queue is empty (i.e.,
head_id == NUM_IDS), it returnsNUM_IDS, indicating no thread to dequeue.
Update the Queue Head:
Retrieves the ID of the thread following the head by calling
tcb_get_next(head_id).If there is a next thread (
head_next_id != NUM_IDS), it sets itsprevpointer toNUM_IDS, effectively removing the head.If there is no next thread, it sets the queue’s tail to
NUM_IDS, indicating an empty queue.
Detach Head and Update:
Sets the
nextpointer of the removed head toNUM_IDSto clear its link.Updates the queue’s head to
head_next_id, completing the dequeue process.
Use Case: Used to remove and return the next thread ready to run, typically by the scheduler when selecting the next thread to execute. This function manages the linked list structure and ensures a clean head removal.
Function: tqueue_remove
tqueue_removevoid tqueue_remove(unsigned int chid, unsigned int pid)
{
unsigned int head_pid, tail_pid, prev_pid, next_pid;
head_pid = tqueue_get_head(chid);
tail_pid = tqueue_get_tail(chid);
prev_pid = tcb_get_prev(pid);
next_pid = tcb_get_next(pid);
if (head_pid == pid)
{
//* removing the head, move head to next
tqueue_set_head(chid, next_pid);
}
if (tail_pid == pid)
{
//* removing the tail, move tail to prev
tqueue_set_tail(chid, prev_pid);
}
if (prev_pid != NUM_IDS)
{
//* unlink previous node from pid
tcb_set_next(prev_pid, next_pid);
}
if (next_pid != NUM_IDS)
{
//* unlink next node from pid
tcb_set_prev(next_pid, prev_pid);
}
tcb_set_prev(pid, NUM_IDS);
tcb_set_next(pid, NUM_IDS);
}Purpose: Removes a specified thread (
pid) from any position in the specified queue (chid). This function handles all possible cases: removing from the head, tail, or a middle position within the queue.Mechanism:
Identify Queue Position:
Retrieves
head_pidandtail_pidto identify if the thread to be removed is at the head, tail, or a middle position.Retrieves
prev_pidandnext_pidpointers for the thread being removed to manage its links.
Remove from Head or Tail:
If
pidis the head,tqueue_set_head(chid, next_pid)updates the queue’s head to the next thread.If
pidis the tail,tqueue_set_tail(chid, prev_pid)updates the queue’s tail to the previous thread.
Update Adjacent Links:
If
pidhas a previous thread (prev_pid != NUM_IDS), it updatesprev_pidto link directly tonext_pid, bypassingpid.If
pidhas a next thread (next_pid != NUM_IDS), it updatesnext_pidto link directly toprev_pid, bypassingpid.
Clear Links of Removed Thread:
Sets
tcb_set_prev(pid, NUM_IDS)andtcb_set_next(pid, NUM_IDS), effectively detaching the removed thread from the queue.
Last updated