Hi Nicolas,

Sure the implementation description is super important, and did not say that. 
All I said is that it is an implementation description and not a high level one.

I just checked the descriptions starting page 257 of the Smalltalk-80 The 
Language book, as well as VisualWorks's 1.0 Cookbook page 1029 - these are of a 
*totally* different, much higher level. That is what we need the most.

Sven

> On 10 Jan 2020, at 18:29, Nicolas Cellier 
> <nicolas.cellier.aka.n...@gmail.com> wrote:
> 
> 
> For example, whether a Semaphore would queue waiting process by order of 
> registration (thru a linked list for example) or by order of priority (thru a 
> Heap for example), would completely change its behavior.
> So isn't that kind of implementation detail SUPER important, especially when 
> hidden in VM?
> 
> Also, describing HOW it works is very often used as a mean to explain (and 
> make understand) a higher level feature.
> IMO, understanding a feature from one implementation is as useful as 
> understanding a feature by examples of usage.
> Even when implementation is plain Smalltalk, it's already an added value to 
> give main guidelines to help reading code (see this particular class or 
> message for understanding the core...), so when it's in VM...
> 
> Le ven. 10 janv. 2020 à 12:59, Danil Osipchuk <danil.osipc...@gmail.com> a 
> écrit :
> I didn't claim expertise on the subject (although I use semaphores 
> extensively), nor its simplicity, nor that the implementation description 
> should be the only guide on its usage (hence 'to add..., how it works' 
> wording)
> Said that, to me it is the case, when a clear description of what is going on 
> aids a lot. Instead of trying to define some rules and scenarios abstractly - 
> to help a user to reason about the system behavior (isn't Stef was willing to 
> look into VM code for this reason?). 
> 
> To me both scenarios of Stef could be explained that in first case the 
> 'signal' process is not getting preempted by the 'wait' process of the same 
> priority, while in second the preemption happens upon return from primitive 
> (hopefully my memory serves me well and my understanding is correct).
> 
> A tangent note on comments in general -- I've noticed more than once, that 
> people tend to produce far  clearer descriptions in exchanges like this -- 
> when discussing matter with others. 
> When a person is in documentation/comment writing mode he/she is sort of 
> tenses up in a formal state and often produces something not very helpful. 
> Current class comment of Semaphore is a perfect example, if I were not 
> familiar with the concept from other sources, I would not be able to make any 
> sense of it. So, I would suggest to use opportunities like this to improve 
> comments/docs when a bit of knowledge shows up in a discussion.
> 
> 
> 
> regards,
>  Danil
> 
> пт, 10 янв. 2020 г. в 13:09, Sven Van Caekenberghe <s...@stfx.eu>:
> Actually, it is just a, albeit concise, description of how Semaphores are 
> implemented.
> 
> It does not help much in understanding them, in learning how they can/should 
> be used, for what purposes and how code behaves.
> 
> Understanding of Process, priorities and Scheduling are also needed for a 
> more complete understanding.
> 
> This is not a simple subject.
> 
> Read https://en.wikipedia.org/wiki/Semaphore_(programming) and see how well 
> you understand the subject.
> 
> In short, it does not answer Stef's concrete question(s).
> 
> > On 10 Jan 2020, at 06:30, Danil Osipchuk <danil.osipc...@gmail.com> wrote:
> > 
> > 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 <eliot.mira...@gmail.com>:
> > 
> > 
> > On Thu, Jan 9, 2020 at 5:03 AM ducasse <steph...@netcourrier.com> 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
> 
> 


Reply via email to