From mboxrd@z Thu Jan 1 00:00:00 1970 From: ruben@mrbrklyn.com (Ruben Safir) Date: Wed, 22 Apr 2015 07:23:48 -0400 Subject: wait queues semiphores kernel implementations In-Reply-To: <20150421150500.GA4412@grml> References: <55345527.2050402@mrbrklyn.com> <20150420152352.GA4333@grml> <55352BD5.9020506@mrbrklyn.com> <20150421150500.GA4412@grml> Message-ID: <553784C4.60203@mrbrklyn.com> To: kernelnewbies@lists.kernelnewbies.org List-Id: kernelnewbies.lists.kernelnewbies.org Ruben QUOTED Previously: <<> On 04/21/2015 11:05 AM, michi1 at michaelblizek.twilightparadox.com wrote: > Hi! > > On 12:39 Mon 20 Apr , Ruben Safir wrote: >> On 04/20/2015 11:23 AM, michi1 at michaelblizek.twilightparadox.com wrote: >>> I would not recommend that. There are already functions in linux/wait.h for >>> these purposes like wait_event_interruptible(). >> >> >> can you do that in the kernel? The wait_event_interuptable creates wait >> queues? > > No, wait_event_interuptable waits on an existing waitqueue. If you want to > create a waitqueue, call init_waitqueue_head(). > > -Michi > Here is the confusing part. this is a discussion on wait and semiphores in a standard text 5.6.2 Semaphore Implementation Recall that the implementation of mutex locks discussed in Section 5.5 suffers from busy waiting. The definitions of the wait() and signal() semaphore operations just described present the same problem. To overcome the need for busy waiting, we can modify the definition of the wait() and signal() operations as follows: When a process executes the wait() operation and finds that the semaphore value is not positive, it must wait. However, rather than engaging in busy waiting, the process can block itself. The block operation places a process into a waiting queue associated with the semaphore, and the state of the process is switched to the waiting state. Then control is transferred to the CPU scheduler, which selects another process to execute. A process that is blocked, waiting on a semaphore S, should be restarted when some other process executes a signal() operation. The process is restarted by a wakeup() operation, which changes the process from the waiting state to the ready state. The process is then placed in the ready queue. (The CPU may or may not be switched from the running process to the newly ready process, depending on the CPU-scheduling algorithm.) To implement semaphores under this definition, we define a semaphore as follows: typedef struct { int value; struct process *list; } semaphore; Each semaphore has an integer value and a list of processes list. When a process must wait on a semaphore, it is added to the list of processes. A signal() operation removes one process from the list of waiting processes and awakens that process. Now, the wait() semaphore operation can be defined as wait(semaphore *S) { S->value--; if (S->value < 0) { add this process to S->list; block(); } } and the signal() semaphore operation can be defined as signal(semaphore *S) { S->value++; if (S->value <= 0) { remove a process P from S->list; wakeup(P); } } Minus the Semiphore, that sounds like what we are doing with the wait list in the scheduler. But it looks like we are leaving it to the user. Why? It is similar but oddly different so I'm trying to figure out what is happening here. Ruben