Maybe to add this into the class comment, this is the most concise and clear description of how it works i've ever seen
пт, 10 янв. 2020 г., 8:13 Eliot Miranda <[email protected]>: > > > On Thu, Jan 9, 2020 at 5:03 AM ducasse <[email protected]> wrote: > >> Hi >> >> I wanted to explain >> >> | semaphore p1 p2 | >> semaphore := Semaphore new. >> p1 := [ semaphore wait. >> 'p1' crTrace ] fork. >> >> p2 := [semaphore signal. >> 'p2' crTrace ] fork. >> >> displays p2 and p1. >> but I would like explain clearly but it depends on the semantics of >> signal. >> >> >> - ==p1== is scheduled and its execution starts to wait on the semaphore, >> so it is removed from the run queue of the scheduler and added to the >> waiting list of the semaphore. >> - ==p2== is scheduled and it signals the semaphore. The semaphore takes >> the first waiting process (==p1==) and reschedule it by adding it to the >> end of the suspended lists. >> > > Since Smalltalk does not have a preemptive scheduler, neither p1 nor p2 > will start to run until something else happens after the execution of p1 := > [...] fork. p2 := [...] fork. So for example, if there is Processor yield > then p1 can start to run. > > So you need to add code to your example to be able to determine what will > happen. The easiest thing would be to delay long enough that both can run. > 1 millisecond is more than enough. > > >> Now this sentence "The semaphore takes the first waiting process (==p1==) >> and reschedule it by adding it to the end of the suspended lists.” is super >> naive. Is the semaphore signalling scheduled? or not? >> > > I would say these three things, something like this: > > "A semaphore is a queue (implemented as a linked list) and an excess > signals count, which is a non-negative integer. On instance creation a new > semaphore is empty and has a zero excess signals count. A semaphore > created for mutual exclusion is empty and has an excess signals count of > one." > > "When a process waits on a semaphore, if the semaphore's excess signals > count is non-zero, then the excess signal count is decremented, and the > process proceeds. But if the semaphore has a zero excess signals count > then the process is unscheduled and added to the end of the semaphore, > after any other processes that are queued on the semaphore." > > "When a semaphore is signaled, if it is not empty, the first process is > removed from it and added to the runnable processes in the scheduler. If > the semaphore is empty its excess signals count is incremented. > > Given these three statements it is easy to see how they work, how to use > them for mutual exclusion, etc. > > >> >> signal >> "Primitive. Send a signal through the receiver. If one or more >> processes >> have been suspended trying to receive a signal, allow the first >> one to >> proceed. If no process is waiting, remember the excess signal. >> Essential. >> See Object documentation whatIsAPrimitive." >> >> <primitive: 85> >> self primitiveFailed >> >> "self isEmpty >> ifTrue: [excessSignals := excessSignals+1] >> ifFalse: [Processor resume: self removeFirstLink]" >> >> >> I wanted to know what is really happening when a semaphore is signalled. >> Now resume: does not exist on Processor. >> >> I will look in the VM code. >> >> >> S >> >> >> >> >> >> S. >> >> > > -- > _,,,^..^,,,_ > best, Eliot >
