<br><font size=2 face="sans-serif">Hi Michael,</font>
<br>
<br><font size=2 face="sans-serif">I see what you are doing with that lock
:-) But isn't the lock a hack ? Eg, I could instead</font>
<br><font size=2 face="sans-serif">do this (If I can make sure the redundant
lock/unlock is not optimized out) and it would</font>
<br><font size=2 face="sans-serif">still work :</font>
<br>
<br><font size=2 face="sans-serif">stop_thread()</font>
<br><font size=2 face="sans-serif">{</font>
<br><font size=2 face="sans-serif">        clear_bit();</font>
<br><font size=2 face="sans-serif">        lock();
       /* empty lock/unlock to synchronize
with the mcast_send() */</font>
<br><font size=2 face="sans-serif">        unlock();
/* make the other routine FINISH before we start other activity */</font>
<br><font size=2 face="sans-serif">        ...</font>
<br><font size=2 face="sans-serif">        ...</font>
<br><font size=2 face="sans-serif">}</font>
<br><font size=2 face="sans-serif">mcast_send()</font>
<br><font size=2 face="sans-serif">{</font>
<br><font size=2 face="sans-serif">        lock();</font>
<br><font size=2 face="sans-serif">        if
(test_bit)</font>
<br><font size=2 face="sans-serif">        ...</font>
<br><font size=2 face="sans-serif">        ...</font>
<br><font size=2 face="sans-serif">        unlock();</font>
<br><font size=2 face="sans-serif">}</font>
<br>
<br><font size=2 face="sans-serif">So basically, the lock is not required
for clearing (and absolutely not required for</font>
<br><font size=2 face="sans-serif">setting) the bit, but a lock is required
before we start waiting, to enable us to</font>
<br><font size=2 face="sans-serif">synchronize with any sends. The lock
is being used as a signalling mechanism</font>
<br><font size=2 face="sans-serif">between two processes (in this case,
lock/unlock is a mechanism for the mcast_send()</font>
<br><font size=2 face="sans-serif">to finish if running).</font>
<br>
<br><font size=2 face="sans-serif">Thanks,</font>
<br>
<br><font size=2 face="sans-serif">- KK</font>
<br><font size=2 face="sans-serif">        </font>
<br><font size=2><tt>"Michael S. Tsirkin" <mst@mellanox.co.il>
wrote on 12/12/2005 12:26:23 PM:<br>
<br>
> Quoting r. Krishna Kumar2 <krkumar2@in.ibm.com>:<br>
> > Isn't all that managed by clearing/testing the bit ? Because
holding the<br>
> > lock doesn't solve <br>
> > it.<br>
> > To give an example : <br>
> > <br>
> > stop_thread() <br>
> > { <br>
> >         lock(); <br>
> >         clear(); <br>
> >         unlock(); <br>
> >         ... <br>
> >         wait_for_completion(mcast); <br>
> > } <br>
> > <br>
> > mcast_send() <br>
> > { <br>
> >         lock(); <br>
> >         test(); <br>
> >         results_in_creation_of_entries_done_etc();;
<br>
> >         unlock(); <br>
> > } <br>
> > <br>
> > In this case, if mcast_send() gets the lock first and proceeds
while the<br>
> > stop_thread is spinning <br>
> > on the lock, the entries are created and then the stop_thread()
clears<br>
> > the bit and at this point <br>
> > in time, no more entries can be ever created. Now if the lock
were<br>
> > removed, the behavior <br>
> > is identical - the mcast_send() would test the bit, and get the
lock()<br>
> > while the stop_thread() <br>
> > clears the bit (without a lock) and waits for completion, while
*no<br>
> > more* mcast_sends() would <br>
> > ever continue beyond this time. <br>
> <br>
> Now mcast_send can call init_completion *after* stop_thread does wait
for<br>
> completion.<br>
> It could also call list_add while mcast_stop_thread walks the list.<br>
> <br>
> Thats what I am trying to prevent.<br>
> <br>
> <br>
> -- <br>
> MST<br>
</tt></font>