Re: [PATCH v3 09/18] perf ui: Update use of pthread mutex

From: Adrian Hunter
Date: Fri Aug 26 2022 - 13:22:49 EST


On 26/08/22 19:02, Ian Rogers wrote:
> On Fri, Aug 26, 2022 at 3:24 AM Adrian Hunter <adrian.hunter@xxxxxxxxx> wrote:
>>
>> On 24/08/22 18:38, Ian Rogers wrote:
>>> Switch to the use of mutex wrappers that provide better error checking.
>>>
>>> Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
>>> ---
>>> tools/perf/ui/browser.c | 20 ++++++++++----------
>>> tools/perf/ui/browsers/annotate.c | 2 +-
>>> tools/perf/ui/setup.c | 5 +++--
>>> tools/perf/ui/tui/helpline.c | 5 ++---
>>> tools/perf/ui/tui/progress.c | 8 ++++----
>>> tools/perf/ui/tui/setup.c | 8 ++++----
>>> tools/perf/ui/tui/util.c | 18 +++++++++---------
>>> tools/perf/ui/ui.h | 4 ++--
>>> 8 files changed, 35 insertions(+), 35 deletions(-)
>>>
>>> diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
>>> index fa5bd5c20e96..78fb01d6ad63 100644
>>> --- a/tools/perf/ui/browser.c
>>> +++ b/tools/perf/ui/browser.c
>>> @@ -268,9 +268,9 @@ void __ui_browser__show_title(struct ui_browser *browser, const char *title)
>>>
>>> void ui_browser__show_title(struct ui_browser *browser, const char *title)
>>> {
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> __ui_browser__show_title(browser, title);
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>>
>>> int ui_browser__show(struct ui_browser *browser, const char *title,
>>> @@ -284,7 +284,7 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
>>>
>>> browser->refresh_dimensions(browser);
>>>
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> __ui_browser__show_title(browser, title);
>>>
>>> browser->title = title;
>>> @@ -295,16 +295,16 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
>>> va_end(ap);
>>> if (err > 0)
>>> ui_helpline__push(browser->helpline);
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> return err ? 0 : -1;
>>> }
>>>
>>> void ui_browser__hide(struct ui_browser *browser)
>>> {
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> ui_helpline__pop();
>>> zfree(&browser->helpline);
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>>
>>> static void ui_browser__scrollbar_set(struct ui_browser *browser)
>>> @@ -352,9 +352,9 @@ static int __ui_browser__refresh(struct ui_browser *browser)
>>>
>>> int ui_browser__refresh(struct ui_browser *browser)
>>> {
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> __ui_browser__refresh(browser);
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>>
>>> return 0;
>>> }
>>> @@ -390,10 +390,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
>>> while (1) {
>>> off_t offset;
>>>
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> err = __ui_browser__refresh(browser);
>>> SLsmg_refresh();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> if (err < 0)
>>> break;
>>>
>>> diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
>>> index 44ba900828f6..b8747e8dd9ea 100644
>>> --- a/tools/perf/ui/browsers/annotate.c
>>> +++ b/tools/perf/ui/browsers/annotate.c
>>> @@ -8,11 +8,11 @@
>>> #include "../../util/hist.h"
>>> #include "../../util/sort.h"
>>> #include "../../util/map.h"
>>> +#include "../../util/mutex.h"
>>> #include "../../util/symbol.h"
>>> #include "../../util/evsel.h"
>>> #include "../../util/evlist.h"
>>> #include <inttypes.h>
>>> -#include <pthread.h>
>>> #include <linux/kernel.h>
>>> #include <linux/string.h>
>>> #include <linux/zalloc.h>
>>> diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
>>> index 700335cde618..25ded88801a3 100644
>>> --- a/tools/perf/ui/setup.c
>>> +++ b/tools/perf/ui/setup.c
>>> @@ -1,5 +1,4 @@
>>> // SPDX-License-Identifier: GPL-2.0
>>> -#include <pthread.h>
>>> #include <dlfcn.h>
>>> #include <unistd.h>
>>>
>>> @@ -8,7 +7,7 @@
>>> #include "../util/hist.h"
>>> #include "ui.h"
>>>
>>> -pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
>>> +struct mutex ui__lock;
>>> void *perf_gtk_handle;
>>> int use_browser = -1;
>>>
>>> @@ -76,6 +75,7 @@ int stdio__config_color(const struct option *opt __maybe_unused,
>>>
>>> void setup_browser(bool fallback_to_pager)
>>> {
>>> + mutex_init(&ui__lock);
>>> if (use_browser < 2 && (!isatty(1) || dump_trace))
>>> use_browser = 0;
>>>
>>> @@ -118,4 +118,5 @@ void exit_browser(bool wait_for_ok)
>>> default:
>>> break;
>>> }
>>> + mutex_destroy(&ui__lock);
>>
>> Looks like exit_browser() can be called even when setup_browser()
>> was never called.
>>
>> Note, it also looks like PTHREAD_MUTEX_INITIALIZER is all zeros so
>> pthread won't notice.
>
> Memory sanitizer will notice some cases of this and so I didn't want
> to code defensively around exit being called ahead of setup.

I am not sure you understood.

As I wrote, exit_browser() can be called even when setup_browser()
was never called, so it is not defensive programming, it is necessary
programming that you only get away without doing because
PTHREAD_MUTEX_INITIALIZER is all zeros.

>
> Thanks,
> Ian
>
>>> }
>>> diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c
>>> index 298d6af82fdd..db4952f5990b 100644
>>> --- a/tools/perf/ui/tui/helpline.c
>>> +++ b/tools/perf/ui/tui/helpline.c
>>> @@ -2,7 +2,6 @@
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> #include <string.h>
>>> -#include <pthread.h>
>>> #include <linux/kernel.h>
>>> #include <linux/string.h>
>>>
>>> @@ -33,7 +32,7 @@ static int tui_helpline__show(const char *format, va_list ap)
>>> int ret;
>>> static int backlog;
>>>
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> ret = vscnprintf(ui_helpline__last_msg + backlog,
>>> sizeof(ui_helpline__last_msg) - backlog, format, ap);
>>> backlog += ret;
>>> @@ -45,7 +44,7 @@ static int tui_helpline__show(const char *format, va_list ap)
>>> SLsmg_refresh();
>>> backlog = 0;
>>> }
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>>
>>> return ret;
>>> }
>>> diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
>>> index 3d74af5a7ece..71b6c8d9474f 100644
>>> --- a/tools/perf/ui/tui/progress.c
>>> +++ b/tools/perf/ui/tui/progress.c
>>> @@ -45,7 +45,7 @@ static void tui_progress__update(struct ui_progress *p)
>>> }
>>>
>>> ui__refresh_dimensions(false);
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> y = SLtt_Screen_Rows / 2 - 2;
>>> SLsmg_set_color(0);
>>> SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
>>> @@ -56,7 +56,7 @@ static void tui_progress__update(struct ui_progress *p)
>>> bar = ((SLtt_Screen_Cols - 2) * p->curr) / p->total;
>>> SLsmg_fill_region(y, 1, 1, bar, ' ');
>>> SLsmg_refresh();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>>
>>> static void tui_progress__finish(void)
>>> @@ -67,12 +67,12 @@ static void tui_progress__finish(void)
>>> return;
>>>
>>> ui__refresh_dimensions(false);
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> y = SLtt_Screen_Rows / 2 - 2;
>>> SLsmg_set_color(0);
>>> SLsmg_fill_region(y, 0, 3, SLtt_Screen_Cols, ' ');
>>> SLsmg_refresh();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>>
>>> static struct ui_progress_ops tui_progress__ops = {
>>> diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
>>> index b1be59b4e2a4..a3b8c397c24d 100644
>>> --- a/tools/perf/ui/tui/setup.c
>>> +++ b/tools/perf/ui/tui/setup.c
>>> @@ -29,10 +29,10 @@ void ui__refresh_dimensions(bool force)
>>> {
>>> if (force || ui__need_resize) {
>>> ui__need_resize = 0;
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> SLtt_get_screen_size();
>>> SLsmg_reinit_smg();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>> }
>>>
>>> @@ -170,10 +170,10 @@ void ui__exit(bool wait_for_ok)
>>> "Press any key...", 0);
>>>
>>> SLtt_set_cursor_visibility(1);
>>> - if (!pthread_mutex_trylock(&ui__lock)) {
>>> + if (mutex_trylock(&ui__lock)) {
>>> SLsmg_refresh();
>>> SLsmg_reset_smg();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>> SLang_reset_tty();
>>> perf_error__unregister(&perf_tui_eops);
>>> diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
>>> index 0f562e2cb1e8..3c5174854ac8 100644
>>> --- a/tools/perf/ui/tui/util.c
>>> +++ b/tools/perf/ui/tui/util.c
>>> @@ -95,7 +95,7 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
>>> t = sep + 1;
>>> }
>>>
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>>
>>> max_len += 2;
>>> nr_lines += 8;
>>> @@ -125,17 +125,17 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
>>> SLsmg_write_nstring((char *)exit_msg, max_len);
>>> SLsmg_refresh();
>>>
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>>
>>> x += 2;
>>> len = 0;
>>> key = ui__getch(delay_secs);
>>> while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>>
>>> if (key == K_BKSPC) {
>>> if (len == 0) {
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> goto next_key;
>>> }
>>> SLsmg_gotorc(y, x + --len);
>>> @@ -147,7 +147,7 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
>>> }
>>> SLsmg_refresh();
>>>
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>>
>>> /* XXX more graceful overflow handling needed */
>>> if (len == sizeof(buf) - 1) {
>>> @@ -215,19 +215,19 @@ void __ui__info_window(const char *title, const char *text, const char *exit_msg
>>>
>>> void ui__info_window(const char *title, const char *text)
>>> {
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> __ui__info_window(title, text, NULL);
>>> SLsmg_refresh();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> }
>>>
>>> int ui__question_window(const char *title, const char *text,
>>> const char *exit_msg, int delay_secs)
>>> {
>>> - pthread_mutex_lock(&ui__lock);
>>> + mutex_lock(&ui__lock);
>>> __ui__info_window(title, text, exit_msg);
>>> SLsmg_refresh();
>>> - pthread_mutex_unlock(&ui__lock);
>>> + mutex_unlock(&ui__lock);
>>> return ui__getch(delay_secs);
>>> }
>>>
>>> diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h
>>> index 9b6fdf06e1d2..99f8d2fe9bc5 100644
>>> --- a/tools/perf/ui/ui.h
>>> +++ b/tools/perf/ui/ui.h
>>> @@ -2,11 +2,11 @@
>>> #ifndef _PERF_UI_H_
>>> #define _PERF_UI_H_ 1
>>>
>>> -#include <pthread.h>
>>> +#include "../util/mutex.h"
>>> #include <stdbool.h>
>>> #include <linux/compiler.h>
>>>
>>> -extern pthread_mutex_t ui__lock;
>>> +extern struct mutex ui__lock;
>>> extern void *perf_gtk_handle;
>>>
>>> extern int use_browser;
>>