@@ -1840,6 +1840,15 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
1840
1840
WOLFSENTRY_ERROR_RETURN (BUSY );
1841
1841
}
1842
1842
1843
+ if ((lock -> read_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
1844
+ (thread -> shared_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
1845
+ {
1846
+ if (sem_post (& lock -> sem ) < 0 )
1847
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
1848
+ else
1849
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
1850
+ }
1851
+
1843
1852
++ lock -> read_waiter_count ;
1844
1853
1845
1854
if (sem_post (& lock -> sem ) < 0 )
@@ -1899,7 +1908,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
1899
1908
thread -> tracked_shared_lock = lock ;
1900
1909
thread -> recursion_of_tracked_lock = 1 ;
1901
1910
}
1902
- else if (thread -> tracked_shared_lock == lock )
1911
+ else if (thread -> tracked_shared_lock == lock ) /* can't happen */
1903
1912
++ thread -> recursion_of_tracked_lock ;
1904
1913
1905
1914
if ((flags & (WOLFSENTRY_LOCK_FLAG_GET_RESERVATION_TOO | WOLFSENTRY_LOCK_FLAG_TRY_RESERVATION_TOO )) &&
@@ -1961,6 +1970,18 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
1961
1970
store_reservation = 1 ;
1962
1971
}
1963
1972
1973
+ if ((lock -> read_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
1974
+ (thread -> shared_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
1975
+ ((thread -> tracked_shared_lock == lock ) && (thread -> recursion_of_tracked_lock == WOLFSENTRY_RWLOCK_MAX_COUNT )) ||
1976
+ (lock -> holder_count .read >= WOLFSENTRY_RWLOCK_MAX_COUNT - store_reservation ) ||
1977
+ (store_reservation && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )))
1978
+ {
1979
+ if (sem_post (& lock -> sem ) < 0 )
1980
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
1981
+ else
1982
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
1983
+ }
1984
+
1964
1985
if (lock -> state == WOLFSENTRY_LOCK_UNLOCKED )
1965
1986
WOLFSENTRY_ATOMIC_STORE (lock -> state , WOLFSENTRY_LOCK_SHARED );
1966
1987
@@ -2031,6 +2052,11 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
2031
2052
case WOLFSENTRY_LOCK_EXCLUSIVE :
2032
2053
if (WOLFSENTRY_ATOMIC_LOAD (lock -> write_lock_holder ) == WOLFSENTRY_THREAD_GET_ID ) {
2033
2054
if (! (flags & WOLFSENTRY_LOCK_FLAG_NONRECURSIVE_MUTEX )) {
2055
+ if ((lock -> holder_count .write == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
2056
+ (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )))
2057
+ {
2058
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2059
+ }
2034
2060
/* recursively locking while holding write is effectively uncontended. */
2035
2061
++ lock -> holder_count .write ;
2036
2062
if (thread )
@@ -2047,18 +2073,22 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
2047
2073
if (flags & WOLFSENTRY_LOCK_FLAG_NONRECURSIVE_MUTEX )
2048
2074
WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
2049
2075
else {
2076
+ if (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2077
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2050
2078
ret = wolfsentry_lock_shared2mutex_redeem_abstimed (lock , thread , abs_timeout , flags );
2051
2079
WOLFSENTRY_RERETURN_IF_ERROR (ret );
2052
- ++ lock -> holder_count .write ;
2080
+ ++ lock -> holder_count .write ; /* caller now holds the lock at least 2 deep. */
2053
2081
if (thread )
2054
2082
++ thread -> mutex_and_reservation_count ;
2055
2083
WOLFSENTRY_RETURN_OK ;
2056
2084
}
2057
2085
}
2058
2086
else if (thread && (thread -> tracked_shared_lock == lock )) {
2087
+ if (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2088
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2059
2089
ret = wolfsentry_lock_shared2mutex_abstimed (lock , thread , abs_timeout , flags );
2060
2090
WOLFSENTRY_RERETURN_IF_ERROR (ret );
2061
- ++ lock -> holder_count .write ;
2091
+ ++ lock -> holder_count .write ; /* caller now holds the lock at least 2 deep. */
2062
2092
if (thread )
2063
2093
++ thread -> mutex_and_reservation_count ;
2064
2094
WOLFSENTRY_RETURN_OK ;
@@ -2125,6 +2155,14 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
2125
2155
WOLFSENTRY_ERROR_RETURN (BUSY );
2126
2156
}
2127
2157
2158
+ if ((lock -> write_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
2159
+ (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )))
2160
+ {
2161
+ if (sem_post (& lock -> sem ) < 0 )
2162
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2163
+ else
2164
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2165
+ }
2128
2166
++ lock -> write_waiter_count ;
2129
2167
2130
2168
if (sem_post (& lock -> sem ) < 0 )
@@ -2272,15 +2310,29 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex2shared(struct wolfsent
2272
2310
WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
2273
2311
}
2274
2312
2313
+ if (thread -> shared_count >= WOLFSENTRY_RWLOCK_MAX_COUNT - lock -> holder_count .write ) {
2314
+ if (sem_post (& lock -> sem ) < 0 )
2315
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2316
+ else
2317
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2318
+ }
2319
+
2275
2320
if (flags & (WOLFSENTRY_LOCK_FLAG_GET_RESERVATION_TOO | WOLFSENTRY_LOCK_FLAG_TRY_RESERVATION_TOO )) {
2276
- /* can't happen, but be sure. */
2277
- if (lock -> read2write_reservation_holder != WOLFSENTRY_THREAD_NO_ID ) {
2321
+ if (lock -> read2write_reservation_holder != WOLFSENTRY_THREAD_NO_ID ) /* can't happen, but be sure. */ {
2278
2322
if (sem_post (& lock -> sem ) < 0 )
2279
2323
WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2280
2324
WOLFSENTRY_ERROR_RETURN (INTERNAL_CHECK_FATAL );
2281
2325
}
2282
- WOLFSENTRY_ATOMIC_STORE (lock -> read2write_reservation_holder , lock -> write_lock_holder );
2326
+ if ((thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
2327
+ (lock -> holder_count .write == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2328
+ {
2329
+ if (sem_post (& lock -> sem ) < 0 )
2330
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2331
+ else
2332
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2333
+ }
2283
2334
++ thread -> mutex_and_reservation_count ;
2335
+ WOLFSENTRY_ATOMIC_STORE (lock -> read2write_reservation_holder , lock -> write_lock_holder );
2284
2336
lock -> read2write_waiter_read_count = lock -> holder_count .write ;
2285
2337
/* note, not incrementing write_waiter_count, to allow shared lockers to get locks until the redemption phase. */
2286
2338
}
@@ -2344,6 +2396,9 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_reserve(struct
2344
2396
WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
2345
2397
}
2346
2398
2399
+ if (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )
2400
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2401
+
2347
2402
for (;;) {
2348
2403
int ret = sem_wait (& lock -> sem );
2349
2404
if (ret == 0 )
@@ -2369,6 +2424,13 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_reserve(struct
2369
2424
WOLFSENTRY_ERROR_RETURN (BUSY );
2370
2425
}
2371
2426
2427
+ if (lock -> holder_count .read == WOLFSENTRY_RWLOCK_MAX_COUNT ) {
2428
+ if (sem_post (& lock -> sem ) < 0 )
2429
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2430
+ else
2431
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2432
+ }
2433
+
2372
2434
WOLFSENTRY_ATOMIC_STORE (lock -> read2write_reservation_holder , WOLFSENTRY_THREAD_GET_ID );
2373
2435
++ thread -> mutex_and_reservation_count ;
2374
2436
/* note, not incrementing write_waiter_count, to allow shared lockers to get locks until the redemption phase. */
@@ -2457,6 +2519,15 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_redeem_abstimed
2457
2519
WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
2458
2520
}
2459
2521
2522
+ if ((thread -> mutex_and_reservation_count >= WOLFSENTRY_RWLOCK_MAX_COUNT - lock -> read2write_waiter_read_count ) ||
2523
+ (lock -> write_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2524
+ {
2525
+ if (sem_post (& lock -> sem ) < 0 )
2526
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2527
+ else
2528
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2529
+ }
2530
+
2460
2531
if (lock -> holder_count .read == lock -> read2write_waiter_read_count + 1 ) {
2461
2532
-- lock -> holder_count .read ; /* remove extra count associated with the reservation. */
2462
2533
lock -> promoted_at_count = lock -> holder_count .read ;
@@ -2713,6 +2784,17 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_abstimed(struct
2713
2784
WOLFSENTRY_ERROR_RETURN (BUSY );
2714
2785
}
2715
2786
2787
+ if ((thread -> mutex_and_reservation_count
2788
+ >=
2789
+ ((thread -> tracked_shared_lock == lock ) ? WOLFSENTRY_RWLOCK_MAX_COUNT : (WOLFSENTRY_RWLOCK_MAX_COUNT - thread -> recursion_of_tracked_lock ))) ||
2790
+ (lock -> write_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2791
+ {
2792
+ if (sem_post (& lock -> sem ) < 0 )
2793
+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2794
+ else
2795
+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2796
+ }
2797
+
2716
2798
if ((lock -> holder_count .read == 1 )
2717
2799
|| ((thread -> tracked_shared_lock == lock )
2718
2800
&& (lock -> holder_count .read == thread -> recursion_of_tracked_lock )))
0 commit comments