#include "internal/threads_common.h"
#include "internal/rcu.h"
#ifdef REPORT_RWLOCK_CONTENTION
+# include <stdbool.h>
# include "internal/time.h"
#endif
#include "rcu_internal.h"
return;
}
+static struct stack_traces *get_stack_traces(bool init)
+{
+ struct stack_traces *traces = CRYPTO_THREAD_get_local(&thread_contention_data);
+
+ if (!traces && init) {
+ traces = OPENSSL_zalloc(sizeof(*traces));
+ CRYPTO_THREAD_set_local(&thread_contention_data, traces);
+ }
+
+ return traces;
+}
+
static void print_stack_traces(struct stack_traces *traces, FILE *fptr)
{
unsigned int j;
{
CRYPTO_THREAD_run_once(&init_contention_fp, init_contention_fp_once);
__atomic_add_fetch(&rwlock_count, 1, __ATOMIC_ACQ_REL);
- {
- struct stack_traces *thread_stack_info;
-
- thread_stack_info = CRYPTO_THREAD_get_local(&thread_contention_data);
- if (thread_stack_info == NULL) {
- thread_stack_info = OPENSSL_zalloc(sizeof(struct stack_traces));
- CRYPTO_THREAD_set_local(&thread_contention_data, thread_stack_info);
- }
- }
}
static ossl_inline void ossl_free_rwlock_contention_data(void)
static ossl_inline int ossl_rwlock_rdlock(pthread_rwlock_t *lock)
{
- struct stack_traces *traces = CRYPTO_THREAD_get_local(&thread_contention_data);
+ struct stack_traces *traces = get_stack_traces(true);
- if (ossl_unlikely(traces == NULL)) {
- traces = OPENSSL_zalloc(sizeof(struct stack_traces));
- CRYPTO_THREAD_set_local(&thread_contention_data, traces);
- if (ossl_unlikely(traces == NULL))
- return ENOMEM;
- }
+ if (ossl_unlikely(traces == NULL))
+ return ENOMEM;
traces->lock_depth++;
if (pthread_rwlock_tryrdlock(lock)) {
static ossl_inline int ossl_rwlock_wrlock(pthread_rwlock_t *lock)
{
- struct stack_traces *traces = CRYPTO_THREAD_get_local(&thread_contention_data);
+ struct stack_traces *traces = get_stack_traces(true);
- if (ossl_unlikely(traces == NULL)) {
- traces = OPENSSL_zalloc(sizeof(struct stack_traces));
- CRYPTO_THREAD_set_local(&thread_contention_data, traces);
- if (ossl_unlikely(traces == NULL))
- return ENOMEM;
- }
+ if (ossl_unlikely(traces == NULL))
+ return ENOMEM;
traces->lock_depth++;
if (pthread_rwlock_trywrlock(lock)) {
return ret;
{
- struct stack_traces *traces = CRYPTO_THREAD_get_local(&thread_contention_data);
+ struct stack_traces *traces = get_stack_traces(false);
if (contention_fp != NULL && traces != NULL) {
traces->lock_depth--;