Sys_select () System Call implemented by linux0.12 is used to manage whether the specified file handle (that is, the file I node, that is, the file) is ready. If there is a prepared file handle, return the number of prepared file handles to the process that calls the select () function and continue executing the blocked command. If not, return-1 (indicating an error) or 0, indicates that files not ready under normal conditions can be used. In this case, you only need to judge the value returned by the SELECT statement to see if any file is ready.
In linux0.12, only the select () blocking functions of TTY and pipe are implemented. tty blocking is implemented when the input data of the keyboard needs to be read and the data queue is empty at this time, the blocking of pipe is when the read end needs to read data but the pipeline is empty, or the write end needs to write data, and the pipeline is full.
Each file handle corresponds to a file I node, that is, a file, each file's memory I node has an I _wait pointer to record the process control block waiting for this file. When a process is waiting for this I node, its Process Control Block is recorded in the I _wait pointer of this I node. Because the waiting process pointer can only store the address of one process control block, when multiple processes are waiting for the same resource, a mechanism must be used to manage these processes. When the select () function is called to block processes, multiple processes are simultaneously blocked on one resource for management. sleep_on () is used for management, the blocked process is recorded on the resource wait pointer, And the blocked process records the process control block of the previously blocked process, and then the last blocked process, the process of the last blocking was recorded ...... In this way, the loop is recorded.
Sys_select () uses an array of waiting lists to manage processes that are blocked on the same resource. The method is the same as the usual blocking management, however, it is difficult to understand because it manages data using arrays and its assignment syntax is strange.
Static void add_wait (struct task_struct ** wait_address, select_table * P)
{
Int I;
If (! Wait_address)
Return;
For (I = 0; I <p-> NR; I ++)
If (p-> entry [I]. wait_address = wait_address)
Return;
P-> entry [p-> Nr]. wait_address = wait_address;
P-> entry [p-> Nr]. old_task = * wait_address;
* Wait_address = current;
P-> Nr ++;
}
Wait_address is the address of the pointer to the wait Process Control Block of the I node, instead of the process control block itself. To obtain the process control block by obtaining the address of the process control block, you must use the value statement, * wait_address. Then p-> entry [p-> Nr]. wait_address = wait_address; indicates that the address of the I _wait wait queue pointer in stage I of the process to be blocked & I _wait is given to the list of management process blocking. Note, at this time, it only gives the address of the pointer to the resource wait queue, and the value in this address can be changed, only to assign a value to this address again. Next, p-> entry [p-> Nr]. old_task = * wait_address; the statement is to assign the process waiting on the I node to the position where the previous process waits for the pointer in the process management table, that is, this location records the control block of the previous blocked process. Only when the * wait_address = current statement is executed will the resource blocking process pointer be assigned again, that is to say, the process on the wait queue pointer of the I node of the current blocking process is the current process, that is, p-> entry [p-> Nr]. wait_address = wait_address; the value is current, while old_task records the process that was blocked last time.