[LTP] [RFC PATCH 2/2] sched_football: Rewrite into new API
Petr Vorel
pvorel@suse.cz
Thu Jul 11 12:43:58 CEST 2024
This is due test compilation broken on old gcc 4.8 we still support
since 8fc3cf4ad6.
Combining LTP librealtime (librttest.c) and LTP library is somehow
experimental. -lltp was needed to be added to CFLAGS but yet on musl
it fails to find the function on runtime:
tst_test.c:985: TBROK: No test function specified
librttest.c getopts were ignored, port just test specific -l and -n.
Fixes: 8fc3cf4ad6 ("sched_football: Re-add the crazy fans to interrupt everyone")
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
.../realtime/func/sched_football/Makefile | 1 +
.../func/sched_football/sched_football.c | 196 +++++++-----------
2 files changed, 81 insertions(+), 116 deletions(-)
diff --git a/testcases/realtime/func/sched_football/Makefile b/testcases/realtime/func/sched_football/Makefile
index 61753f0309..f194c2fbfc 100644
--- a/testcases/realtime/func/sched_football/Makefile
+++ b/testcases/realtime/func/sched_football/Makefile
@@ -25,4 +25,5 @@ top_srcdir ?= ../../../..
INSTALL_TARGETS := run_auto.sh
include $(top_srcdir)/include/mk/env_pre.mk
include $(abs_srcdir)/../../config.mk
+LDLIBS += -lltp
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/realtime/func/sched_football/sched_football.c b/testcases/realtime/func/sched_football/sched_football.c
index b6ae692af7..a3e4cbb344 100644
--- a/testcases/realtime/func/sched_football/sched_football.c
+++ b/testcases/realtime/func/sched_football/sched_football.c
@@ -1,62 +1,37 @@
-/******************************************************************************
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright © International Business Machines Corp., 2007, 2008
+ * Copyright (c) 2024 Petr Vorel <pvorel@suse.cz>
+ * Author: John Stultz <jstultz@google.com>
+ */
+
+/*\
+ * [Description]
*
- * Copyright © International Business Machines Corp., 2007, 2008
+ * Scheduler test that uses a football analogy.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * The premise is that we want to make sure that lower priority threads
+ * don't run while we have runnable higher priority threads.
+ * The offense is trying to increment the balls position, while the
+ * defense is trying to block that from happening.
+ * And the ref (highest priority thread) will blow the wistle if the
+ * ball moves. Finally, we have crazy fans (higer prority) that try to
+ * distract the defense by occasionally running onto the field.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
+ * [Algorithm]
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * NAME
- * sched_football.c
- *
- * DESCRIPTION
- * This is a scheduler test that uses a football analogy.
- * The premise is that we want to make sure that lower priority threads
- * don't run while we have runnable higher priority threads.
- * The offense is trying to increment the balls position, while the
- * defense is trying to block that from happening.
- * And the ref (highest priority thread) will blow the wistle if the
- * ball moves. Finally, we have crazy fans (higer prority) that try to
- * distract the defense by occasionally running onto the field.
- *
- * Steps:
- * - Create NR_CPU offense threads (lower priority)
- * - Create NR_CPU defense threads (mid priority)
- * - Create 2*NR_CPU fan threads (high priority)
- * - Create a referee thread (highest priority)
- * - Once everyone is on the field, the offense thread spins incrementing
- * the value of 'the_ball'. The defense thread tries to block the ball
- * by never letting the offense players get the CPU (it just spins).
- * The crazy fans sleep a bit, then jump the rail and run across the
- * field, disrupting the players on the field.
- * - The refree threads wakes up regularly to check if the game is over :)
- * - In the end, if the value of 'the_ball' is >0, the test is considered
- * to have failed.
- *
- * USAGE:
- * Use run_auto.sh script in current directory to build and run test.
- *
- * AUTHOR
- * John Stultz <johnstul@xxxxxxxxx >
- *
- * HISTORY
- * 2006-03-16 Reduced verbosity, non binary failure reporting, removal of
- * crazy_fans thread, added game_length argument by Darren Hart.
- * 2007-08-01 Remove all thread cleanup in favor of simply exiting.Various
- * bugfixes and cleanups. -- Josh Triplett
- * 2009-06-23 Simplified atomic startup mechanism, avoiding thundering herd
- * scheduling at the beginning of the game. -- Darren Hart
- *****************************************************************************/
+ * - Create NR_CPU offense threads (lower priority).
+ * - Create NR_CPU defense threads (mid priority).
+ * - Create 2*NR_CPU fan threads (high priority).
+ * - Create a referee thread (highest priority).
+ * - Once everyone is on the field, the offense thread spins incrementing
+ * the value of ball. The defense thread tries to block the ball
+ * by never letting the offense players get the CPU (it just spins).
+ * The crazy fans sleep a bit, then jump the rail and run across the
+ * field, disrupting the players on the field.
+ * - The refree threads wakes up regularly to check if the game is over :).
+ * - If the value of ball is > 0, the test is considered to have failed.
+ */
#include <stdio.h>
#include <stdlib.h>
@@ -71,55 +46,25 @@
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/time.h>
-#include <librttest.h>
#include <tst_atomic.h>
-#define TST_NO_DEFAULT_MAIN
#include <tst_timer.h>
-
+#include "librttest.h"
+#include "tst_test.h"
#define DEF_GAME_LENGTH 5
+#define SPIN_TIME_NS 200000000ULL
+#define SLEEP_TIME_NS 50000000ULL
-/* Here's the position of the ball */
-static int the_ball;
-
+static int ball;
static int players_per_team = 0;
static int game_length = DEF_GAME_LENGTH;
static int players_ready;
-void usage(void)
-{
- rt_help();
- printf("sched_football specific options:\n");
- printf(" -nPLAYERS players per team (defaults to num_cpus)\n");
- printf(" -lGAME_LENGTH game length in seconds (defaults to %d s)\n",
- DEF_GAME_LENGTH);
-}
-
-int parse_args(int c, char *v)
-{
+static char *str_game_length;
+static char *str_players_per_team;
- int handled = 1;
- switch (c) {
- case 'h':
- usage();
- exit(0);
- case 'n':
- players_per_team = atoi(v);
- break;
- case 'l':
- game_length = atoi(v);
- break;
- default:
- handled = 0;
- break;
- }
- return handled;
-}
-
-#define SPIN_TIME_NS 200000000ULL
-#define SLEEP_TIME_NS 50000000ULL
/* These are fans running across the field. They're trying to interrupt/distract everyone */
-void *thread_fan(void *arg)
+void *thread_fan(void *arg LTP_ATTRIBUTE_UNUSED)
{
prctl(PR_SET_NAME, "crazy_fan", 0, 0, 0);
tst_atomic_add_return(1, &players_ready);
@@ -139,38 +84,43 @@ void *thread_fan(void *arg)
nsec = tst_timespec_diff_ns(stop, start);
}
}
+
return NULL;
}
/* This is the defensive team. They're trying to block the offense */
-void *thread_defense(void *arg)
+void *thread_defense(void *arg LTP_ATTRIBUTE_UNUSED)
{
prctl(PR_SET_NAME, "defense", 0, 0, 0);
tst_atomic_add_return(1, &players_ready);
/*keep the ball from being moved */
while (1) {
}
+
return NULL;
}
/* This is the offensive team. They're trying to move the ball */
-void *thread_offense(void *arg)
+void *thread_offense(void *arg LTP_ATTRIBUTE_UNUSED)
{
prctl(PR_SET_NAME, "offense", 0, 0, 0);
tst_atomic_add_return(1, &players_ready);
while (1) {
- tst_atomic_add_return(1, &the_ball); /* move the ball ahead one yard */
+ tst_atomic_add_return(1, &ball); /* move the ball ahead one yard */
}
+
return NULL;
}
-int referee(int game_length)
+void referee(int game_length)
{
struct timeval start, now;
int final_ball;
+ tst_res(TINFO, "Starting referee thread");
+
prctl(PR_SET_NAME, "referee", 0, 0, 0);
- printf("Game On (%d seconds)!\n", game_length);
+ tst_res(TINFO, "Starting the game (%d sec)", game_length);
/* open trace marker early to avoid latency with the first message */
trace_marker_prep();
@@ -178,7 +128,7 @@ int referee(int game_length)
now = start;
/* Start the game! */
- tst_atomic_store(0, &the_ball);
+ tst_atomic_store(0, &ball);
atrace_marker_write("sched_football", "Game_started!");
/* Watch the game */
@@ -187,29 +137,26 @@ int referee(int game_length)
gettimeofday(&now, NULL);
}
atrace_marker_write("sched_football", "Game_Over!");
- final_ball = tst_atomic_load(&the_ball);
+ final_ball = tst_atomic_load(&ball);
+
/* Blow the whistle */
- printf("Game Over!\n");
- printf("Final ball position: %d\n", final_ball);
- return final_ball != 0;
+ tst_res(TINFO, "Final ball position: %d", final_ball);
+
+ TST_EXP_EXPR(final_ball == 0);
}
-int main(int argc, char *argv[])
+static void do_test(void)
{
struct sched_param param;
int priority;
int i;
- int result;
- setup();
-
- rt_init("n:l:h", parse_args, argc, argv);
if (players_per_team == 0)
players_per_team = sysconf(_SC_NPROCESSORS_ONLN);
tst_atomic_store(0, &players_ready);
- printf("Running with: players_per_team=%d game_length=%d\n",
+ tst_res(TINFO, "players_per_team: %d game_length: %d",
players_per_team, game_length);
/* We're the ref, so set our priority right */
@@ -221,7 +168,7 @@ int main(int argc, char *argv[])
* They are lower priority than defense, so they must be started first.
*/
priority = 15;
- printf("Starting %d offense threads at priority %d\n",
+ tst_res(TINFO, "Starting %d offense threads at priority %d",
players_per_team, priority);
for (i = 0; i < players_per_team; i++)
create_fifo_thread(thread_offense, NULL, priority);
@@ -232,7 +179,7 @@ int main(int argc, char *argv[])
/* Start the defense */
priority = 30;
- printf("Starting %d defense threads at priority %d\n",
+ tst_res(TINFO, "Starting %d defense threads at priority %d",
players_per_team, priority);
for (i = 0; i < players_per_team; i++)
create_fifo_thread(thread_defense, NULL, priority);
@@ -243,7 +190,7 @@ int main(int argc, char *argv[])
/* Start the crazy fans*/
priority = 50;
- printf("Starting %d fan threads at priority %d\n",
+ tst_res(TINFO, "Starting %d fan threads at priority %d",
players_per_team, priority);
for (i = 0; i < players_per_team*2; i++)
create_fifo_thread(thread_fan, NULL, priority);
@@ -255,9 +202,26 @@ int main(int argc, char *argv[])
/* let things get into steady state */
sleep(2);
/* Ok, everyone is on the field, bring out the ref */
- printf("Starting referee thread\n");
- result = referee(game_length);
- printf("Result: %s\n", result ? "FAIL" : "PASS");
- return result;
+ referee(game_length);
}
+
+static void do_setup(void)
+{
+ if (tst_parse_int(str_game_length, &game_length, 1, INT_MAX))
+ tst_brk(TBROK, "Invalid game length '%s'", str_game_length);
+
+ if (tst_parse_int(str_players_per_team, &players_per_team, 1, INT_MAX))
+ tst_brk(TBROK, "Invalid number of players '%s'", str_players_per_team);
+}
+
+static struct tst_test test = {
+ .test_all = do_test,
+ .setup = do_setup,
+ .options = (struct tst_option[]) {
+ {"l:", &str_game_length, "Game length in sec (default: "
+ TST_TO_STR(DEF_GAME_LENGTH) " sec)"},
+ {"n:", &str_players_per_team, "Number of players (default: number of CPU)"},
+ {}
+ },
+};
--
2.45.2
More information about the ltp
mailing list