Hello,
As you have noticed i have invented four variants of my scalable RWLock,
the ones that ends with an X in there names are starvation-free the
others are not..
Why i have decided to come with salable and starvation-free RWLocks,
cause you can have frequent reads and infrequent writes but from time
to time you can have frequent writes, so i think it is important to have a scalable and starvation-free RWLock , this is why i have come up with two variants of scalable and starvation-free RWLocks.
And as i told you before my lightweight variant and starvation-free
RWLock called LW_RWLockX scales even at 3% of writes, that's also very interresting to know...
And you have to know also that even if we are in a scenario with many more writes than 3% of writes and my scalable LW_RWLockX don't scale globally in the timing you have to know that LW_RWLockX will still be useful , cause even if it doen't scale globally in the timing , you have to understand that if from the time t1 to the time t2 there is writes and reads and from the time t2 to time t3 there is only reads, so even if the time from t1 to t2 will add more to the overall time cause there is writes threads, the perceived throughput from time t2 to t3 will be higher and the waiting time from t2 to t3 will be lower cause all my RWLocks will be scalable from t2 to t3 and this will make all my scalable RWLocks useful cause for example the database clients from internet or intranet waiting from t2 to t3 will be served more quickly and this is still useful and this will make my scalable RWLocks still useful even if it doesn't scale above 3% of writes.
I have updated my scalable RWLock to 3.06, in this new
version i have optimized more scalable RWLockX and scalable LW_RWLockX..
Here is what have changed...
Before, the RWLock() method looked like this:
===
procedure TRWLOCK.WLock;
var i:integer;
begin
lock.wait;
event1.resetEvent;
event2.resetEvent;
FCount3^.fcount3:=1;
repeat;
event2.setEvent;
asm pause end;
event2.resetEvent;
until nbr^.nbr=0;
for i:=0 to GetSystemThreadCount-1 do
begin
while (FCount1^
.fcount1<>0)
do
begin
//if mysleep=0 then sleep(0);
//else sleep(1);
end;
end;
end;
===
To optimize it more you have to write it like this:
==
procedure TRWLOCK.WLock;
var i:integer;
begin
lock.wait;
repeat;
event2.setEvent;
asm pause end;
event2.resetEvent;
until nbr^.nbr=0;
event1.resetEvent;
//event2.resetEvent;
FCount3^.fcount3:=1;
for i:=0 to GetSystemThreadCount-1 do
begin
while (FCount1^.fcount1<>0)
do
begin
//if mysleep=0 then sleep(0);
//else sleep(1);
end;
end;
end;
===
Since the repeat-until block is now located before FCount3^.fcount3:=1;
so this will give better parallelism to my RWLockX and LW_RWLockX.
You can download all the variants of my scalable RWLock version 3.06 from:
http://pages.videotron.com/aminer/
Thank you,
Amine Moulay Ramdane.