From b1303b115ef2bf7f8f0caf46341b20e634213dfb Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Mon, 7 Jul 2025 15:42:07 +0200 Subject: [PATCH] crypto/threads_lock_contention: factor out lock contention recording MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Eugene Syromiatnikov Reviewed-by: Neil Horman Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/27983) --- crypto/threads_pthread.c | 75 +++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index cc611d2ad03..afdab335793 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -714,6 +714,33 @@ static ossl_inline void ossl_free_rwlock_contention_data(void) } } +static int record_lock_contention(pthread_rwlock_t *lock, + struct stack_traces *traces, bool write) +{ + void *buffer[BT_BUF_SIZE]; + OSSL_TIME start, end; + int ret; + + start = ossl_time_now(); + ret = (write ? pthread_rwlock_wrlock : pthread_rwlock_rdlock)(lock); + if (ret) + return ret; + end = ossl_time_now(); + traces->stacks[traces->idx].nptrs = backtrace(buffer, BT_BUF_SIZE); + traces->stacks[traces->idx].strings = backtrace_symbols(buffer, + traces->stacks[traces->idx].nptrs); + traces->stacks[traces->idx].duration = ossl_time_subtract(end, start); + traces->stacks[traces->idx].start = start; + traces->stacks[traces->idx].write = write; + traces->idx++; + if (traces->idx >= STACKS_COUNT) { + fprintf(stderr, "STACK RECORD OVERFLOW!\n"); + print_stack_traces(traces, contention_fp); + } + + return 0; +} + static ossl_inline int ossl_rwlock_rdlock(pthread_rwlock_t *lock) { struct stack_traces *traces = get_stack_traces(true); @@ -723,28 +750,12 @@ static ossl_inline int ossl_rwlock_rdlock(pthread_rwlock_t *lock) traces->lock_depth++; if (pthread_rwlock_tryrdlock(lock)) { - void *buffer[BT_BUF_SIZE]; - OSSL_TIME start, end; - int ret; + int ret = record_lock_contention(lock, traces, false); - start = ossl_time_now(); - ret = pthread_rwlock_rdlock(lock); - if (ret) { + if (ret) traces->lock_depth--; - return ret; - } - end = ossl_time_now(); - traces->stacks[traces->idx].nptrs = backtrace(buffer, BT_BUF_SIZE); - traces->stacks[traces->idx].strings = backtrace_symbols(buffer, - traces->stacks[traces->idx].nptrs); - traces->stacks[traces->idx].duration = ossl_time_subtract(end, start); - traces->stacks[traces->idx].start = start; - traces->stacks[traces->idx].write = 0; - traces->idx++; - if (traces->idx >= STACKS_COUNT) { - fprintf(stderr, "STACK RECORD OVERFLOW!\n"); - print_stack_traces(traces, contention_fp); - } + + return ret; } return 0; @@ -759,28 +770,12 @@ static ossl_inline int ossl_rwlock_wrlock(pthread_rwlock_t *lock) traces->lock_depth++; if (pthread_rwlock_trywrlock(lock)) { - void *buffer[BT_BUF_SIZE]; - OSSL_TIME start, end; - int ret; + int ret = record_lock_contention(lock, traces, true); - start = ossl_time_now(); - ret = pthread_rwlock_wrlock(lock); - if (ret) { + if (ret) traces->lock_depth--; - return ret; - } - end = ossl_time_now(); - traces->stacks[traces->idx].nptrs = backtrace(buffer, BT_BUF_SIZE); - traces->stacks[traces->idx].strings = backtrace_symbols(buffer, - traces->stacks[traces->idx].nptrs); - traces->stacks[traces->idx].duration = ossl_time_subtract(end, start); - traces->stacks[traces->idx].start = start; - traces->stacks[traces->idx].write = 1; - traces->idx++; - if (traces->idx >= STACKS_COUNT) { - fprintf(stderr, "STACK RECORD OVERFLOW!\n"); - print_stack_traces(traces, contention_fp); - } + + return ret; } return 0; -- 2.47.3