]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/hw_lock.s
xnu-792.13.8.tar.gz
[apple/xnu.git] / osfmk / ppc / hw_lock.s
index 3b49b75664a5bf86ead48c9acd091329d7787fe5..5d842da0d6f11c0443643fecaa924f0182cdef79 100644 (file)
@@ -40,6 +40,7 @@
 #define        WAIT_FLAG               0x02
 #define        WANT_UPGRADE    0x04
 #define        WANT_EXCL               0x08
+#define        PRIV_EXCL               0x8000
 
 #define TH_FN_OWNED            0x01
 
@@ -2012,8 +2013,10 @@ LEXT(lck_rw_lock_exclusive)
                        .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
@@ -2046,14 +2049,21 @@ LEXT(lock_read)
 #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
@@ -2200,8 +2210,9 @@ rwtlsloop:        lwarx   r5,RW_DATA,r3                                   ; Grab the lock value
                        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)
@@ -2209,6 +2220,12 @@ LEXT(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