Re: read-write spinlocks ??

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Gaurav Dhiman wrote:
- if we look at assembly code of __read_lock_failed (shown above), you
will find that we are looping until the value of lock is not >= 1,
this means that as soon as the value of lock will become 1 we will
come out of loop and will try to hold the rw lock by decrementing the
'lock' element of rw lock, but should not we check with condition >=
2, that will make it more efficient.

Actually remember if the lock value == 0 then it is locked for writing, that is all that we are looking for. Anything > 0 means we can try the read lock. Also remember that if there is one reader the value of the lock is 0x00ffffff not 0x00000001 because we acquire a read lock by decrementing the value not incrementing.



__read_lock_failed: lock ; incl (%eax) 1: cmpl $1,(%eax)

The above instruction is not focusing on whether the value is >= 1 so much as it is focusing on whether you can subtract 1 from it and not go negative.


        js      1b

        lock ; decl     (%eax)
        js      __read_lock_failed
        ret

The above function __read_lock_failed will be invoked when the reader
was not able to get the rw lock. This will happen in two cases
- when there is already a writer in CR, value of lock will be 0x00000000
- when there are maximum number of reader already present in CR, value
of lock at this will be 0x00000001 (am I right ?)

Now lets take these two cases one by one.

Case 1: when there is already a writer in CR - incoming reader will
keep on looping between cmpl and js instuctions, as the value of lock
is 0. Now as soon as the writer leaves the CR, it will make the lock
value to 0x01000000 (which is greater than 1 as well as 2), so the
condition for coming out of loop can be lock should be >= 2, rather
than 1.

Case 2: max readers already in CR - in this case the value of lock
will be 0x00000001, and we should keep on looping in cmpl and js
instructions because there is no space for more readers in CR. Sapace
will be created when any of the present reader will be leaving out of
CR and making the value of lock to 2, so in this case also the
condition of coming out of loop can be locak value >= 2.

So in any case if the value of lock is less than 2, we can not get a
lock and should keep on looping, else come out of the loop.

As per the current code (shown above), in case 2, we will coming out
of the inner loop (cmpl and js loop) bt will be looping in outer loop,
but in each loop we will be decrementing the value of lock, checking
if we got it and then again incrementing the lock value, because we
will never the get lock with value 1 (CR is full of readers), so in a
way we are increasing the cost and time of each loop. If we would have
checked for the condition greater than equal to 2 in inner loop (cmpl
js loop), we could have avoided this "decrement, check and increment"
thing in each loop, making the loop more faster.

So as far as I understand we should keep on looping on inner loop
(cmpl and js instructions) unless and untill lock value is not >= 2

Please provide your suggestions and feedback on this.

regards,
-gd


My reasoning for this is that we should only come out of loop and try
to hold the lock when there is any space for reader to go in critical
region (CR). When there are maximum number of readers in CR, the lock
will have value 0x00000001 (that means 1), so at value 1 there is
nospace for more readers in CR and incoming readers should keep on
looping, as soon as the value is incremented by the outgoing reader
from CR, the value will become 2 and at this time the waiting reader
should try to get in CR, so I think the condition for looping should
be:

1: lock; cmpl $2, (%eax)
  js 1b

Please give your comments on this.

-gd


On 4/26/05, K.R. Foley <kr@xxxxxxxxxx> wrote:


Gaurav Dhiman wrote:


Thanks for your reply, it clears my doubt of keeping two locks, one
for read and one for write. As this info can be stored in one element
only, we dont need two.




You're right, but in fact, the implementation has been so that both
information are encoded inside a single integer. You don't really need
two counters, but :
- a counter of readers


why we need to keep a count of readers, does that matter ?

Because you can't get a write lock while there are any readers.

From this and the rest of your message, I am not sure you are getting
how this works:

readers and writers are mutually exclusive. While there are readers you
can't get the write lock. While there is a writer, there are no readers.



- a bit indicating whether a writer owns the lock or not


So, in fact, one bit of the integer is reserved to "mark" the rwlock as
owned by a writer or not. Have a look at include/asm-i386/rwlock.h, and
particularly the definition of RW_LOCK_BIAS.


Can you let me know whats the significance of this flag, is this flag
used to mark the writer and other bits used for keeping a count of
reades.

This is the value that is subtracted to get the write lock. It also happens to be the init/idle value of the lock. So, if subtracting RW_LOCK_BIAS from the lock value yields 0x00000000 then you have acquired the write lock.

Since we are on the subject, read locks are also gotten by subtracting

from the value of the lock and are represented by any number less than

0x01000000.



Have a look at the implementation of __build_read_lock_const() and
__build_write_lock_const() is the same file.


cud not understand this assembly code, where is the helper function
defined, it is calling ?

helper is the name of the function (in this case the spin function) that is passed in like:

__build_write_lock(rw, "__write_lock_failed");

Which is in spinlock.h



Sincerly,

Thomas
--
Thomas Petazzoni
thomas.petazzoni@xxxxxxxx



--

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



-- kr



--
   kr





--
   kr

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux