From 4c0b750d809bca811a402c6931774449d844f1f4 Mon Sep 17 00:00:00 2001 From: Pavithra Gurushankar Date: Fri, 26 Aug 2022 09:42:25 -0700 Subject: [PATCH 5.15.y] perf mutex: Wrapped usage of mutex and cond MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e57d897703c3bf8b66680c69c0e75fbd9d9617f1 ] Added a new header file mutex.h that wraps the usage of pthread_mutex_t and pthread_cond_t. By abstracting these it is possible to introduce error checking. Signed-off-by: Pavithra Gurushankar Reviewed-by: Adrian Hunter Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Alexandre Truong Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andres Freund Cc: Andrii Nakryiko Cc: André Almeida Cc: Athira Jajeev Cc: Christophe JAILLET Cc: Colin Ian King Cc: Dario Petrillo Cc: Darren Hart Cc: Dave Marchevsky Cc: Davidlohr Bueso Cc: Fangrui Song Cc: Hewenliang Cc: Ingo Molnar Cc: James Clark Cc: Jason Wang Cc: Jiri Olsa Cc: Kajol Jain Cc: Kim Phillips Cc: Leo Yan Cc: Mark Rutland Cc: Martin Liška Cc: Masami Hiramatsu Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Peter Zijlstra Cc: Quentin Monnet Cc: Ravi Bangoria Cc: Remi Bernon Cc: Riccardo Mancini Cc: Song Liu Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Thomas Richter Cc: Tom Rix Cc: Weiguo Li Cc: Wenyu Liu Cc: William Cohen Cc: Zechuan Chen Cc: bpf@vger.kernel.org Cc: llvm@lists.linux.dev Cc: yaowenbin Link: https://lore.kernel.org/r/20220826164242.43412-2-irogers@google.com Signed-off-by: Ian Rogers Signed-off-by: Arnaldo Carvalho de Melo [Harshit: Minor conflict resolution due to missing commit: 92ec3cc94c2c ("tools lib: Adopt list_sort() from the kernel sources") in 5.15.y] Signed-off-by: Harshit Mogalapalli --- tools/perf/util/Build | 1 + tools/perf/util/mutex.c | 117 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/mutex.h | 48 +++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 tools/perf/util/mutex.c create mode 100644 tools/perf/util/mutex.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 7d085927da41..9d4feb186ec0 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -138,6 +138,7 @@ perf-y += expr.o perf-y += branch.o perf-y += mem2node.o perf-y += clockid.o +perf-y += mutex.o perf-$(CONFIG_LIBBPF) += bpf-loader.o perf-$(CONFIG_LIBBPF) += bpf_map.o diff --git a/tools/perf/util/mutex.c b/tools/perf/util/mutex.c new file mode 100644 index 000000000000..5029237164e5 --- /dev/null +++ b/tools/perf/util/mutex.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "mutex.h" + +#include "debug.h" +#include +#include + +static void check_err(const char *fn, int err) +{ + char sbuf[STRERR_BUFSIZE]; + + if (err == 0) + return; + + pr_err("%s error: '%s'\n", fn, str_error_r(err, sbuf, sizeof(sbuf))); +} + +#define CHECK_ERR(err) check_err(__func__, err) + +static void __mutex_init(struct mutex *mtx, bool pshared) +{ + pthread_mutexattr_t attr; + + CHECK_ERR(pthread_mutexattr_init(&attr)); + +#ifndef NDEBUG + /* In normal builds enable error checking, such as recursive usage. */ + CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); +#endif + if (pshared) + CHECK_ERR(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); + + CHECK_ERR(pthread_mutex_init(&mtx->lock, &attr)); + CHECK_ERR(pthread_mutexattr_destroy(&attr)); +} + +void mutex_init(struct mutex *mtx) +{ + __mutex_init(mtx, /*pshared=*/false); +} + +void mutex_init_pshared(struct mutex *mtx) +{ + __mutex_init(mtx, /*pshared=*/true); +} + +void mutex_destroy(struct mutex *mtx) +{ + CHECK_ERR(pthread_mutex_destroy(&mtx->lock)); +} + +void mutex_lock(struct mutex *mtx) +{ + CHECK_ERR(pthread_mutex_lock(&mtx->lock)); +} + +void mutex_unlock(struct mutex *mtx) +{ + CHECK_ERR(pthread_mutex_unlock(&mtx->lock)); +} + +bool mutex_trylock(struct mutex *mtx) +{ + int ret = pthread_mutex_trylock(&mtx->lock); + + if (ret == 0) + return true; /* Lock acquired. */ + + if (ret == EBUSY) + return false; /* Lock busy. */ + + /* Print error. */ + CHECK_ERR(ret); + return false; +} + +static void __cond_init(struct cond *cnd, bool pshared) +{ + pthread_condattr_t attr; + + CHECK_ERR(pthread_condattr_init(&attr)); + if (pshared) + CHECK_ERR(pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); + + CHECK_ERR(pthread_cond_init(&cnd->cond, &attr)); + CHECK_ERR(pthread_condattr_destroy(&attr)); +} + +void cond_init(struct cond *cnd) +{ + __cond_init(cnd, /*pshared=*/false); +} + +void cond_init_pshared(struct cond *cnd) +{ + __cond_init(cnd, /*pshared=*/true); +} + +void cond_destroy(struct cond *cnd) +{ + CHECK_ERR(pthread_cond_destroy(&cnd->cond)); +} + +void cond_wait(struct cond *cnd, struct mutex *mtx) +{ + CHECK_ERR(pthread_cond_wait(&cnd->cond, &mtx->lock)); +} + +void cond_signal(struct cond *cnd) +{ + CHECK_ERR(pthread_cond_signal(&cnd->cond)); +} + +void cond_broadcast(struct cond *cnd) +{ + CHECK_ERR(pthread_cond_broadcast(&cnd->cond)); +} diff --git a/tools/perf/util/mutex.h b/tools/perf/util/mutex.h new file mode 100644 index 000000000000..cfff32a902d9 --- /dev/null +++ b/tools/perf/util/mutex.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_MUTEX_H +#define __PERF_MUTEX_H + +#include +#include + +/* + * A wrapper around the mutex implementation that allows perf to error check + * usage, etc. + */ +struct mutex { + pthread_mutex_t lock; +}; + +/* A wrapper around the condition variable implementation. */ +struct cond { + pthread_cond_t cond; +}; + +/* Default initialize the mtx struct. */ +void mutex_init(struct mutex *mtx); +/* + * Initialize the mtx struct and set the process-shared rather than default + * process-private attribute. + */ +void mutex_init_pshared(struct mutex *mtx); +void mutex_destroy(struct mutex *mtx); + +void mutex_lock(struct mutex *mtx); +void mutex_unlock(struct mutex *mtx); +/* Tries to acquire the lock and returns true on success. */ +bool mutex_trylock(struct mutex *mtx); + +/* Default initialize the cond struct. */ +void cond_init(struct cond *cnd); +/* + * Initialize the cond struct and specify the process-shared rather than default + * process-private attribute. + */ +void cond_init_pshared(struct cond *cnd); +void cond_destroy(struct cond *cnd); + +void cond_wait(struct cond *cnd, struct mutex *mtx); +void cond_signal(struct cond *cnd); +void cond_broadcast(struct cond *cnd); + +#endif /* __PERF_MUTEX_H */ -- 2.34.1