#define WAIT_FLAG 0x02
#define WANT_UPGRADE 0x04
#define WANT_EXCL 0x08
+#define PRIV_EXCL 0x8000
#define TH_FN_OWNED 0x01
.globl EXT(lock_write)
LEXT(lock_write)
#endif
+ lis r7,0xFFFF
+ ori r7,r7,(WANT_EXCL|WANT_UPGRADE|ILK_LOCKED)
rwleloop: lwarx r5,RW_DATA,r3 ; Grab the lock value
- rlwinm. r7,r5,30,1,31 ; Can we have it?
+ and. r8,r5,r7 ; Can we have it?
ori r6,r5,WANT_EXCL ; Mark Exclusive
bne-- rwlespin ; Branch if cannot be held
stwcx. r6,RW_DATA,r3 ; Update lock word
#endif
rwlsloop: lwarx r5,RW_DATA,r3 ; Grab the lock value
andi. r7,r5,WANT_EXCL|WANT_UPGRADE|ILK_LOCKED ; Can we have it?
+ bne-- rwlsopt ; Branch if cannot be held
+rwlsloopres:
addis r6,r5,1 ; Increment read cnt
- bne-- rwlsspin ; Branch if cannot be held
stwcx. r6,RW_DATA,r3 ; Update lock word
bne-- rwlsloop
.globl EXT(rwlsPatch_isync)
LEXT(rwlsPatch_isync)
isync
blr
+rwlsopt:
+ andi. r7,r5,PRIV_EXCL|ILK_LOCKED ; Can we have it?
+ bne-- rwlsspin ; Branch if cannot be held
+ lis r7,0xFFFF ; Get read cnt mask
+ and. r8,r5,r7 ; Is it shared
+ bne rwlsloopres ; Branch if can be held
rwlsspin:
li r4,lgKillResv ; Killing field
stwcx. r4,0,r4 ; Kill it
andi. r7,r5,ILK_LOCKED ; Test interlock flag
bne-- rwtlsspin ; Branch if interlocked
andi. r7,r5,WANT_EXCL|WANT_UPGRADE ; So, can we have it?
+ bne-- rwtlsopt ; Branch if held exclusive
+rwtlsloopres:
addis r6,r5,1 ; Increment read cnt
- bne-- rwtlsfail ; Branch if held exclusive
stwcx. r6,RW_DATA,r3 ; Update lock word
bne-- rwtlsloop
.globl EXT(rwtlsPatch_isync)
isync
li r3,1 ; Return TRUE
blr
+rwtlsopt:
+ andi. r7,r5,PRIV_EXCL ; Can we have it?
+ bne-- rwtlsfail ; Branch if cannot be held
+ lis r7,0xFFFF ; Get read cnt mask
+ and. r8,r5,r7 ; Is it shared
+ bne rwtlsloopres ; Branch if can be held
rwtlsfail:
li r3,0 ; Return FALSE
blr