From nobody Wed Nov 27 09:43:05 2024 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF7791D1F77 for ; Fri, 11 Oct 2024 22:04:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728684252; cv=none; b=Ee+mTtajkYC9SLO0xMWgLll3v56EMrssACrM2QwY6BeHJVWHqCVyl8PqHdszuiqzHHjwS+ml/FIjL5W0BEt/iCenwqYyJ8tYbeizZzMgb25m6gKRCTA1uX3ima5Wm3lhdMGNpGWh5X96NtFubfoLLXxuFFO7nQUmwDyXsmr95kU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728684252; c=relaxed/simple; bh=cVFHyHnq6TrMxc5fZUbBCZHrcp12iOBhqisVsG/m8d0=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=ulYxvrXQN/X+Zo1AS9Mo6iSZiNrHkRK+xwkTMKQKeD6a8xZvT3qHcMOJQoADIcOhEKimrwNfPjNIhICHZQyeZsqiIQM95qIUoVMxY06SZAg0xnQjQWyuzssisDu8Ei0LdR9cFIKtIlJEIksA2cUrAa9BNUygMc4G9kePHBrsEJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=eHsHb9tf; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="eHsHb9tf" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e29205f6063so1479209276.1 for ; Fri, 11 Oct 2024 15:04:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1728684250; x=1729289050; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ddlbx8whXmomEW8ZV85yTS+anC+8hSMDj9tPf/FCtxQ=; b=eHsHb9tfBK7cHtljo+eWgA7OYjqoCa8kSmIvltN1aLBI1DMBAfVyikCkHJpQEFUGfM HMQJtFSkUAzVPQMI7eQqwtreKUM/DPEuBce333bmmk6dnSiynKdAM/zKQIXQ0gAboNMe oZDniB2Pjn/lQxihPBKlHspzGnjYI5djsUrqJYv2kTw4cOpG2t6Qx/6l/02NMhaiEdzG GxKlrxqpid2z0s/Ba/+7OiWJpnyQuZDKYDpiHhk4QyCtdRURUirMxizOe7SETsIYQ+Bo sd6WcvOvrQLPVR6gCemHpZy3vJfvohXIt2vVIltOzN9fMGvv4OZP1LEeZCga1RApsIEE GmuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728684250; x=1729289050; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ddlbx8whXmomEW8ZV85yTS+anC+8hSMDj9tPf/FCtxQ=; b=AbEGGjGuBSSGESayg0eWRE0TeA0Esk5XAVvjPsSeOY5xG3hggpyCJNKMEDfb+vklUE IgkJGjZxdrnQPqxKrZtfq1XB7ATlxKw5SmgvAoAZhPuFdggEjr30599ATch5K6eKnMbo KpaxJbhOs+XhLWF0a9bM9iGwKMHC/i9y750HIcQ/emy2vhdA6QzoG/Wm7w+zzFWtSneT zaJlHLIOuS79IBYVwCwiDmJJAI6H3HZRFLRWKm+RH+dr1fiNum3N87fdYmuLLt9YhE/7 sO6S7wvpbssKBEv4+XiBU0BULGejowFR6h+143Gn56XNFbE0VN1+HS/qaGoMPMSr82Nc +Uiw== X-Forwarded-Encrypted: i=1; AJvYcCVuI9AZaHDnU7kZ7HIzWkio+qsEGruB3mEkpsKBzztviLaDffIR1P5MHPkaE9PHzC976Dgk9s8r5N/SVgQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yzjj6zEQRlH/aoDZx3PREByLngYMYdVDcXHcB1hTl8gkDLEQ6Xj 1nalHQ9UNOXazJyVtwOj7IfnUa10l4vsRmbyC5pmQzRnjBUFfLJ+HeIIRc+RJ28y0Y5jFBqVVHk t60KSLA== X-Google-Smtp-Source: AGHT+IGICUHaZFxM7wOjXnnLZ5hyhXGYPt16hW/X1bKliAAyX+svgNa1tBgHEBUYgRaGMen2Agvxfbh+ivDW X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:8144:56f:2e1e:4db]) (user=irogers job=sendgmr) by 2002:a25:ae60:0:b0:e28:f8e6:f4c6 with SMTP id 3f1490d57ef6-e2919dbf049mr14115276.2.1728684248890; Fri, 11 Oct 2024 15:04:08 -0700 (PDT) Date: Fri, 11 Oct 2024 15:03:48 -0700 In-Reply-To: <20241011220354.756798-1-irogers@google.com> Message-Id: <20241011220354.756798-3-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20241011220354.756798-1-irogers@google.com> X-Mailer: git-send-email 2.47.0.rc1.288.g06298d1525-goog Subject: [PATCH v2 2/8] perf test: Display number of active running tests From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , James Clark , Howard Chu , Athira Jajeev , Michael Petlan , Veronika Molnarova , Dapeng Mi , Thomas Richter , Ilya Leoshkevich , Colin Ian King , Weilin Wang , Andi Kleen , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Before polling or sleeping to wait for a test to complete, print out ": Running ( active)" where the number of active tests is determined by iterating over the tests and seeing which return false for check_if_command_finished. The line erasing and printing out only occur if the number of runnings tests changes to avoid the line flickering excessively. Knowing tests are running allows a user to know a test is running and in parallel mode how many of the tests are waiting to complete. If color mode is disabled then avoid displaying the "Running" message as deleting the line isn't reliable. Tested-by: James Clark Signed-off-by: Ian Rogers --- tools/perf/tests/builtin-test.c | 93 ++++++++++++++++++++++----------- tools/perf/util/color.h | 1 + 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 470a9709427d..bf03fb42420b 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -242,7 +242,10 @@ static int run_test_child(struct child_process *proces= s) return -err; } =20 -static int print_test_result(struct test_suite *t, int i, int subtest, int= result, int width) +#define TEST_RUNNING -3 + +static int print_test_result(struct test_suite *t, int i, int subtest, int= result, int width, + int running) { if (has_subtests(t)) { int subw =3D width > 2 ? width - 2 : width; @@ -252,6 +255,9 @@ static int print_test_result(struct test_suite *t, int = i, int subtest, int resul pr_info("%3d: %-*s:", i + 1, width, test_description(t, subtest)); =20 switch (result) { + case TEST_RUNNING: + color_fprintf(stderr, PERF_COLOR_YELLOW, " Running (%d active)\n", runni= ng); + break; case TEST_OK: pr_info(" Ok\n"); break; @@ -273,14 +279,17 @@ static int print_test_result(struct test_suite *t, in= t i, int subtest, int resul return 0; } =20 -static int finish_test(struct child_test *child_test, int width) +static int finish_test(struct child_test **child_tests, int running_test, = int child_test_num, + int width) { + struct child_test *child_test =3D child_tests[running_test]; struct test_suite *t =3D child_test->test; int i =3D child_test->test_num; int subi =3D child_test->subtest; int err =3D child_test->process.err; - bool err_done =3D err <=3D 0; + bool err_done =3D false; struct strbuf err_output =3D STRBUF_INIT; + int last_running =3D -1; int ret; =20 /* @@ -294,7 +303,7 @@ static int finish_test(struct child_test *child_test, i= nt width) * Busy loop reading from the child's stdout/stderr that are set to be * non-blocking until EOF. */ - if (!err_done) + if (err > 0) fcntl(err, F_SETFL, O_NONBLOCK); if (verbose > 1) { if (has_subtests(t)) @@ -308,38 +317,60 @@ static int finish_test(struct child_test *child_test,= int width) .events =3D POLLIN | POLLERR | POLLHUP | POLLNVAL, }, }; - char buf[512]; - ssize_t len; - - /* Poll to avoid excessive spinning, timeout set for 100ms. */ - poll(pfds, ARRAY_SIZE(pfds), /*timeout=3D*/100); - if (!err_done && pfds[0].revents) { - errno =3D 0; - len =3D read(err, buf, sizeof(buf) - 1); - - if (len <=3D 0) { - err_done =3D errno !=3D EAGAIN; - } else { - buf[len] =3D '\0'; - if (verbose > 1) - fprintf(stdout, "%s", buf); - else + if (perf_use_color_default) { + int running =3D 0; + + for (int y =3D running_test; y < child_test_num; y++) { + if (check_if_command_finished(&child_tests[y]->process) =3D=3D 0) + running++; + } + if (running !=3D last_running) { + if (last_running !=3D -1) { + /* + * Erase "Running (.. active)" line + * printed before poll/sleep. + */ + fprintf(debug_file(), PERF_COLOR_DELETE_LINE); + } + print_test_result(t, i, subi, TEST_RUNNING, width, running); + last_running =3D running; + } + } + + err_done =3D true; + if (err <=3D 0) { + /* No child stderr to poll, sleep for 10ms for child to complete. */ + usleep(10 * 1000); + } else { + /* Poll to avoid excessive spinning, timeout set for 100ms. */ + poll(pfds, ARRAY_SIZE(pfds), /*timeout=3D*/100); + if (pfds[0].revents) { + char buf[512]; + ssize_t len; + + len =3D read(err, buf, sizeof(buf) - 1); + + if (len > 0) { + err_done =3D false; + buf[len] =3D '\0'; strbuf_addstr(&err_output, buf); + } } } + if (err_done) + err_done =3D check_if_command_finished(&child_test->process); + } + if (perf_use_color_default && last_running !=3D -1) { + /* Erase "Running (.. active)" line printed before poll/sleep. */ + fprintf(debug_file(), PERF_COLOR_DELETE_LINE); } /* Clean up child process. */ ret =3D finish_command(&child_test->process); - if (verbose =3D=3D 1 && ret =3D=3D TEST_FAIL) { - /* Add header for test that was skipped above. */ - if (has_subtests(t)) - pr_info("%3d.%1d: %s:\n", i + 1, subi + 1, test_description(t, subi)); - else - pr_info("%3d: %s:\n", i + 1, test_description(t, -1)); + if (verbose > 1 || (verbose =3D=3D 1 && ret =3D=3D TEST_FAIL)) fprintf(stderr, "%s", err_output.buf); - } + strbuf_release(&err_output); - print_test_result(t, i, subi, ret, width); + print_test_result(t, i, subi, ret, width, /*running=3D*/0); if (err > 0) close(err); return 0; @@ -355,7 +386,7 @@ static int start_test(struct test_suite *test, int i, i= nt subi, struct child_tes pr_debug("--- start ---\n"); err =3D test_function(test, subi)(test, subi); pr_debug("---- end ----\n"); - print_test_result(test, i, subi, err, width); + print_test_result(test, i, subi, err, width, /*running=3D*/0); return 0; } =20 @@ -380,7 +411,7 @@ static int start_test(struct test_suite *test, int i, i= nt subi, struct child_tes err =3D start_command(&(*child)->process); if (err || !sequential) return err; - return finish_test(*child, width); + return finish_test(child, /*running_test=3D*/0, /*child_test_num=3D*/1, w= idth); } =20 #define for_each_test(j, k, t) \ @@ -465,7 +496,7 @@ static int __cmd_test(int argc, const char *argv[], str= uct intlist *skiplist) } for (i =3D 0; i < child_test_num; i++) { if (!sequential) { - int ret =3D finish_test(child_tests[i], width); + int ret =3D finish_test(child_tests, i, child_test_num, width); =20 if (ret) return ret; diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h index 01f7bed21c9b..4b9f8d5d4439 100644 --- a/tools/perf/util/color.h +++ b/tools/perf/util/color.h @@ -22,6 +22,7 @@ #define MIN_GREEN 0.5 #define MIN_RED 5.0 =20 +#define PERF_COLOR_DELETE_LINE "\033[A\33[2K\r" /* * This variable stores the value of color.ui */ --=20 2.47.0.rc1.288.g06298d1525-goog