]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/locks_ppc.c
xnu-792.13.8.tar.gz
[apple/xnu.git] / osfmk / ppc / locks_ppc.c
index eebd348c47b7d208a34ceb9980b608392f8c397b..0ae0cd675cfe3d72b726adb159cb121c8a3263b7 100644 (file)
@@ -712,6 +712,9 @@ lock_init(
 #if    MACH_LDEBUG
        lck->lck_rw_deb.type = RW_TAG;
        lck->lck_rw_attr |= (LCK_RW_ATTR_DEBUG|LCK_RW_ATTR_DIS_THREAD|LCK_RW_ATTR_DIS_MYLOCK);
+       lck->lck_rw.lck_rw_priv_excl = TRUE;
+#else
+       lck->lck_rw_priv_excl = TRUE;
 #endif
 
 }
@@ -818,6 +821,10 @@ lck_rw_init(
                }
        } else {
                (void) memset((void *) lck, 0, sizeof(lck_rw_t));
+               if ((lck_attr->lck_attr_val)  & LCK_ATTR_RW_SHARED_PRIORITY)
+                       lck->lck_rw_priv_excl = FALSE;
+               else
+                       lck->lck_rw_priv_excl = TRUE;
        }
 
        lck_grp_reference(grp);
@@ -834,6 +841,10 @@ lck_rw_ext_init(
        lck_attr_t      *attr) {
 
        bzero((void *)lck, sizeof(lck_rw_ext_t));
+       if ((attr->lck_attr_val)  & LCK_ATTR_RW_SHARED_PRIORITY)
+               lck->lck_rw.lck_rw_priv_excl = FALSE;
+       else
+               lck->lck_rw.lck_rw_priv_excl = TRUE;
 
        if ((attr->lck_attr_val) & LCK_ATTR_DEBUG) {
                lck->lck_rw_deb.type = RW_TAG;
@@ -1091,7 +1102,8 @@ lck_rw_lock_shared_gen(
 
        lck_rw_ilk_lock(lck);
 
-       while (lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) {
+       while ((lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) &&
+               ((lck->lck_rw_shared_cnt == 0) || (lck->lck_rw_priv_excl))) {
                i = lock_wait_time[1];
 
                KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS, LCK_RW_LCK_SHARED_CODE) | DBG_FUNC_START,
@@ -1099,12 +1111,15 @@ lck_rw_lock_shared_gen(
 
                if (i != 0) {
                        lck_rw_ilk_unlock(lck);
-                       while (--i != 0 && (lck->lck_rw_want_excl || lck->lck_rw_want_upgrade))
+                       while (--i != 0 && 
+                              (lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) &&
+                              ((lck->lck_rw_shared_cnt == 0) || (lck->lck_rw_priv_excl)))
                                continue;
                        lck_rw_ilk_lock(lck);
                }
 
-               if (lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) {
+               if ((lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) &&
+                   ((lck->lck_rw_shared_cnt == 0) || (lck->lck_rw_priv_excl))) {
                        lck->lck_rw_waiting = TRUE;
                        res = assert_wait((event_t)(((unsigned int*)lck)+((sizeof(lck_rw_t)-1)/sizeof(unsigned int))), THREAD_UNINT);
                        if (res == THREAD_WAITING) {
@@ -1281,7 +1296,8 @@ lck_rw_try_lock_shared_gen(
 {
        lck_rw_ilk_lock(lck);
 
-       if (lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) {
+       if ((lck->lck_rw_want_excl || lck->lck_rw_want_upgrade) &&
+           ((lck->lck_rw_shared_cnt == 0) || (lck->lck_rw_priv_excl))) {
                lck_rw_ilk_unlock(lck);
                return(FALSE);
        }
@@ -1517,7 +1533,8 @@ lck_rw_lock_shared_ext(
        if (lock_stat)
                lck->lck_rw_grp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt++;
 
-       while (lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade) {
+       while ((lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade) &&
+              ((lck->lck_rw.lck_rw_shared_cnt == 0) || (lck->lck_rw.lck_rw_priv_excl))) {
                i = lock_wait_time[1];
 
                KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS, LCK_RW_LCK_SHARED_CODE) | DBG_FUNC_START,
@@ -1530,12 +1547,15 @@ lck_rw_lock_shared_ext(
 
                if (i != 0) {
                        lck_rw_ilk_unlock(&lck->lck_rw);
-                       while (--i != 0 && (lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade))
+                       while (--i != 0 && 
+                              (lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade) &&
+                              ((lck->lck_rw.lck_rw_shared_cnt == 0) || (lck->lck_rw.lck_rw_priv_excl)))
                                continue;
                        lck_rw_ilk_lock(&lck->lck_rw);
                }
 
-               if (lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade) {
+               if ((lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade)  &&
+                  ((lck->lck_rw.lck_rw_shared_cnt == 0) || (lck->lck_rw.lck_rw_priv_excl))) {
                        lck->lck_rw.lck_rw_waiting = TRUE;
                        res = assert_wait((event_t)(((unsigned int*)rlck)+((sizeof(lck_rw_t)-1)/sizeof(unsigned int))), THREAD_UNINT);
                        if (res == THREAD_WAITING) {
@@ -1792,7 +1812,8 @@ lck_rw_try_lock_shared_ext(
        if (lock_stat)
                lck->lck_rw_grp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt++;
 
-       if (lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade) {
+       if ((lck->lck_rw.lck_rw_want_excl || lck->lck_rw.lck_rw_want_upgrade) &&
+           ((lck->lck_rw.lck_rw_shared_cnt == 0) || (lck->lck_rw.lck_rw_priv_excl))) {
                if (lock_stat) {
                        lck->lck_rw_grp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt++;
                }