summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Kacur <jkacur@redhat.com>2022-05-10 14:11:17 -0400
committerJohn Kacur <jkacur@redhat.com>2022-05-10 14:11:17 -0400
commitd7f457b5f804d8295959c5b0f0e06f72b5976f85 (patch)
treee9a9d4af228f82f473289bd1d205ba602080c1f9
parent9d6093b0c1396f778655cab6fb26f88c3badc561 (diff)
downloadrt-tests-d7f457b5f804d8295959c5b0f0e06f72b5976f85.tar.gz
rt-tests: Remove classic_pi
This very early program in the rt-tests suite has been completed rewritten and is now called pi_stress. There is no reason to keep these old files around. Signed-off-by: John Kacur <jkacur@redhat.com>
-rw-r--r--src/pi_tests/classic_pi.c599
-rw-r--r--src/pi_tests/classic_pi.odgbin12470 -> 0 bytes
2 files changed, 0 insertions, 599 deletions
diff --git a/src/pi_tests/classic_pi.c b/src/pi_tests/classic_pi.c
deleted file mode 100644
index 64af889..0000000
--- a/src/pi_tests/classic_pi.c
+++ /dev/null
@@ -1,599 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * classic_pi - Classic Priority Inversion deadlock test case
- * Copyright (C) 2006, 2007 Clark Williams <williams@redhat.com>
- */
-
-/* This program tests Priority Inheritance mutexes and their ability
- to avoid Priority Inversion deadlocks
-
- The basic premise here is to set up a deadlock scenario and confirm that PI
- mutexes resolve the situation. Three worker threads will be created from the
- main thread: low, medium and high priority threads that use SCHED_FIFO as
- their scheduling policy. The low priority thread claims a mutex and then
- starts "working". The medium priority thread starts and preempts the low
- priority thread. Then the high priority thread runs and attempts to claim
- the mutex owned by the low priority thread. Without priority inheritance,
- this will deadlock the program. With priority inheritance, the low priority
- thread receives a priority boost, finishes it's "work" and releases the mutex,
- which allows the high priority thread to run and finish and then the medium
- priority thread finishes.
-
- That's the theory, anyway...
-
- CW - 2006 */
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <pthread.h>
-#include <sched.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <getopt.h>
-
-/* test timeout */
-#define TIMEOUT 2
-
-/* determine if the C library supports Priority Inheritance mutexes */
-#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT != -1
-#define HAVE_PI_MUTEX 1
-#else
-#define HAVE_PI_MUTEX 0
-#endif
-
-int use_pi_mutex = HAVE_PI_MUTEX;
-
-#define SUCCESS 0
-#define FAILURE 1
-
-/* the number of times we cause a priority inversion situation */
-int inversions = 1;
-
-int verbose = 0;
-
-struct option options [] = {
- { "verbose", no_argument, NULL, 'v' },
- { "quiet", no_argument, NULL, 'q' },
- { "no-pi", no_argument, NULL, 'n'},
- { "inversions" , required_argument, NULL, 'i'},
-};
-
-/* define priorities for the threads */
-#define SKEL_PRIO(x) (x)
-#define MAIN_PRIO(x) (x - 1)
-#define HIGH_PRIO(x) (x - 2)
-#define MED_PRIO(x) (x - 3)
-#define LOW_PRIO(x) (x - 4)
-
-enum thread_names {LOW=0, MEDIUM, HIGH, NUM_WORKER_THREADS};
-
-pthread_mutex_t mutex;
-pthread_mutexattr_t mutex_attr;
-
-pthread_barrier_t all_threads_ready;
-pthread_barrier_t all_threads_done;
-
-// state barriers
-pthread_barrier_t start_barrier;
-pthread_barrier_t locked_barrier;
-pthread_barrier_t elevate_barrier;
-pthread_barrier_t finish_barrier;
-
-volatile int deadlocked = 0;
-volatile int high_has_run = 0;
-volatile int low_unlocked = 0;
-
-cpu_set_t cpu_mask;
-
-struct thread_parameters {
- pthread_t tid;
- int inversions;
-} thread_parameters[NUM_WORKER_THREADS];
-
-/* forward prototypes */
-void *low_priority(void *arg);
-void *med_priority(void *arg);
-void *high_priority(void *arg);
-int setup_thread_attr(pthread_attr_t *attr, int prio, cpu_set_t *mask);
-int set_cpu_affinity(cpu_set_t *mask);
-void error(char *, ...);
-void info(char *, ...);
-
-int
-initialize_barriers(void)
-{
- int status;
-
- status = pthread_barrier_init(&all_threads_ready, NULL, NUM_WORKER_THREADS+1);
- if (status) {
- error("initialize_barriers: failed to initialize all_threads_ready\n");
- return FAILURE;
- }
- status = pthread_barrier_init(&all_threads_done, NULL, NUM_WORKER_THREADS+1);
- if (status) {
- error("initialize_barriers: failed to initialize all_threads_done\n");
- return FAILURE;
- }
- status = pthread_barrier_init(&start_barrier, NULL, NUM_WORKER_THREADS);
- if (status) {
- error("initialize_barriers: failed to initialize start_barrier\n");
- return FAILURE;
- }
- status = pthread_barrier_init(&locked_barrier, NULL, 2);
- if (status) {
- error("initializing_barriers: failed to intialize locked_barrier\n");
- return FAILURE;
- }
- status = pthread_barrier_init(&elevate_barrier, NULL, 2);
- if (status) {
- error("initializing_barriers: failed to initialize elevate_barrier\n");
- return FAILURE;
- }
- status = pthread_barrier_init(&finish_barrier, NULL, NUM_WORKER_THREADS);
- if (status) {
- error("initializing_barriers: failed to initialize finish_barrier\n");
- return FAILURE;
- }
- return SUCCESS;
-}
-
-void cleanup(void)
-{
- int i;
- int status;
- for (i = 0; i < NUM_WORKER_THREADS; i++) {
- status = pthread_kill(thread_parameters[i].tid, SIGQUIT);
- if (status)
- error("cleanup: error sending SIGQUIT to thread %d\n",
- thread_parameters[i].tid);
- }
-}
-
-void handler(int signal)
-{
- info("handler: %s fired\n", sys_siglist[signal]);
- cleanup();
- if (signal == SIGALRM) {
- error("handler: DEADLOCK detected!\n");
- deadlocked = 1;
- }
-}
-
-void usage(void)
-{
- printf ("classic_pi [options]\n");
- printf (" options:\n");
- printf (" -v|--verbose\n");
- printf (" -q|--quiet\n");
- printf (" -n|--no-pi\n");
- printf (" -i <n> |--inversions=<n>\n");
-}
-
-int main(int argc, char **argv)
-{
- int status;
- int prio_max;
- pthread_attr_t thread_attr;
- struct sched_param thread_param;
- int opt;
-
- /* Make sure we see all message, even those on stdout. */
- setvbuf (stdout, NULL, _IONBF, 0);
-
- /* process command line arguments */
- while ((opt = getopt_long(argc, argv, "+", options, NULL)) != -1) {
- switch (opt) {
- case '?':
- usage();
- exit(1);
- case 'v':
- verbose = 1;
- break;
- case 'q':
- verbose = 0;
- break;
- case 'n':
- use_pi_mutex = 0;
- break;
- case 'i':
- inversions = strtol(optarg, NULL, 10);
- info("main: doing %d inversion loops\n", inversions);
- break;
- }
- }
-
- /* initialize default attributes for the mutex */
- status = pthread_mutexattr_init(&mutex_attr);
- if (status) {
- error("main: initializing mutex attribute: 0x%x\n", status);
- return FAILURE;
- }
-
- if (use_pi_mutex) {
- /* set priority inheritance attribute for mutex */
- status = pthread_mutexattr_setprotocol(&mutex_attr,
- PTHREAD_PRIO_INHERIT);
- if (status) {
- error("main: setting mutex attribute policy: 0x%x\n", status);
- return FAILURE;
- }
- }
- info("main: Priority Inheritance turned %s\n", use_pi_mutex ? "on" : "off");
-
- /* initialize our mutex */
- status = pthread_mutex_init(&mutex, &mutex_attr);
- if (status) {
- error("main: initializing mutex: 0x%x\n", status);
- return FAILURE;
- }
-
- /* set up our barriers */
- status = initialize_barriers();
- if (status)
- return FAILURE;
-
- /* set up CPU affinity so we only use one processor */
- if (set_cpu_affinity(&cpu_mask))
- return FAILURE;
-
- /* boost us to max priority (so we keep running) :) */
- prio_max = sched_get_priority_max(SCHED_FIFO);
- thread_param.sched_priority = MAIN_PRIO(prio_max);
- status = pthread_setschedparam(pthread_self(), SCHED_FIFO, &thread_param);
- if (status) {
- error("main: boosting to max priority: 0x%x\n", status);
- /* Don't fail if we don't have the right privledges */
- return SUCCESS;
- }
-
- /* start the low priority thread */
- info("main: creating low priority thread\n");
- setup_thread_attr(&thread_attr, LOW_PRIO(prio_max), &cpu_mask);
- thread_parameters[LOW].inversions = inversions;
- status = pthread_create(&thread_parameters[LOW].tid,
- &thread_attr,
- low_priority,
- &thread_parameters[LOW]);
- if (status != 0) {
- error("main: creating low_priority thread: 0x%x\n", status);
- return FAILURE;
- }
-
- /* create the medium priority thread */
- info("main: creating medium priority thread\n");
- setup_thread_attr(&thread_attr, MED_PRIO(prio_max), &cpu_mask);
- thread_parameters[MEDIUM].inversions = inversions;
- status = pthread_create(&thread_parameters[MEDIUM].tid,
- &thread_attr,
- med_priority,
- &thread_parameters[MEDIUM]);
- if (status != 0) {
- error("main: creating med_priority thread: 0x%x\n", status);
- return FAILURE;
- }
-
- /* create the high priority thread */
- info("main: creating high priority thread\n");
- if (setup_thread_attr(&thread_attr, HIGH_PRIO(prio_max), &cpu_mask))
- return FAILURE;
- thread_parameters[HIGH].inversions = inversions;
- status = pthread_create(&thread_parameters[HIGH].tid,
- &thread_attr,
- high_priority,
- &thread_parameters[HIGH]);
- if (status != 0) {
- error("main: creating high_priority thread: 0x%x\n", status);
- cleanup();
- return FAILURE;
- }
-
- signal(SIGINT, handler);
- signal(SIGALRM, handler);
-
- info("main: releasing all threads\n");
- status = pthread_barrier_wait(&all_threads_ready);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("main: pthread_barrier_wait(all_threads_ready): 0x%x\n", status);
- cleanup();
- return FAILURE;
- }
- info("main: all threads initialized, waiting for mutex to be claimed\n");
-
- alarm(TIMEOUT * inversions);
- info("main: waiting for threads to finish\n");
-
- status = pthread_barrier_wait(&all_threads_done);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("main: pthread_barrier_wait(all_threads_done): 0x%x\n", status);
- cleanup();
- return FAILURE;
- }
- alarm(0);
- info("main: all threads terminated!\n");
- if (deadlocked) {
- info("main: test failed\n");
- return FAILURE;
- }
- info("main: test passed\n");
- return SUCCESS;
-}
-
-
-int setup_thread_attr(pthread_attr_t *attr, int prio, cpu_set_t *mask)
-{
- int status;
- struct sched_param thread_param;
-
- status = pthread_attr_init(attr);
- if (status) {
- error("setup_thread_attr: initializing thread attribute: 0x%x\n", status);
- return FAILURE;
- }
- status = pthread_attr_setschedpolicy(attr, SCHED_FIFO);
- if (status) {
- error("setup_thread_attr: setting attribute policy to SCHED_FIFO: 0x%x\n", status);
- return FAILURE;
- }
- status = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
- if (status) {
- error("setup_thread_attr: setting explicit scheduling inheritance: 0x%x\n", status);
- return FAILURE;
- }
- thread_param.sched_priority = prio;
- status = pthread_attr_setschedparam(attr, &thread_param);
- if (status) {
- error("setup_thread_attr: setting scheduler param: 0x%x\n", status);
- return FAILURE;
- }
- status = pthread_attr_setaffinity_np(attr, sizeof(cpu_set_t), mask);
- if (status) {
- error("setup_thread_attr: setting affinity attribute: 0x%x\n", status);
- return FAILURE;
- }
- return SUCCESS;
-}
-
-int set_cpu_affinity(cpu_set_t *cpu_set)
-{
- int status, i;
- cpu_set_t current_mask, new_mask;
-
- /* Now set our CPU affinity to only run one one processor */
- status = sched_getaffinity(0, sizeof(cpu_set_t), &current_mask);
- if (status) {
- error("set_cpu_affinity: getting CPU affinity mask: 0x%x\n", status);
- return FAILURE;
- }
- for (i = 0; i < sizeof(cpu_set_t) * 8; i++) {
- if (CPU_ISSET(i, &current_mask))
- break;
- }
- if (i >= sizeof(cpu_set_t) * 8) {
- error("set_cpu_affinity: No schedulable CPU found!\n");
- return FAILURE;
- }
- CPU_ZERO(&new_mask);
- CPU_SET(i, &new_mask);
- status = sched_setaffinity(0, sizeof(cpu_set_t), &new_mask);
- if (status) {
- error("set_cpu_affinity: setting CPU affinity mask: 0x%x\n", status);
- return FAILURE;
- }
- info("set_cpu_affinity: using processr %d\n", i);
- *cpu_set = new_mask;
- return SUCCESS;
-}
-
-void report_threadinfo(char *name)
-{
- int status;
- struct sched_param thread_param;
- int thread_policy;
-
- status = pthread_getschedparam(pthread_self(), &thread_policy, &thread_param);
- if (status) {
- error("report_threadinfo: failed to get scheduler param: 0x%x\n", status);
- exit(FAILURE);
- }
- info("%s: running as %s thread at priority %d\n",
- name, thread_policy == SCHED_FIFO ? "FIFO" :
- thread_policy == SCHED_RR ? "RR" : "OTHER",
- thread_param.sched_priority);
-}
-
-void *low_priority(void *arg)
-{
- int status;
- struct thread_parameters *p = (struct thread_parameters *)arg;
-
- report_threadinfo("low_priority");
-
- info("low_priority: entering ready state\n");
-
- /* wait for all threads to be ready */
- status = pthread_barrier_wait(&all_threads_ready);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("low_priority: pthread_barrier_wait(all_threads_ready): %x", status);
- return NULL;
- }
-
- info("low_priority: starting inversion loop (%d)\n", p->inversions);
- while (p->inversions-- > 0) {
- /* initial state */
- info("low_priority: entering start wait (%d)\n", p->inversions+1);
- status = pthread_barrier_wait(&start_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("low_priority: pthread_barrier_wait(start): %x\n", status);
- return NULL;
- }
- info("low_priority: claiming mutex\n");
- pthread_mutex_lock(&mutex);
- info("low_priority: mutex locked\n");
-
- info("low_priority: entering locked wait\n");
- status = pthread_barrier_wait(&locked_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("low_priority: pthread_barrier_wait(locked): %x\n", status);
- return NULL;
- }
-
- /* wait for priority boost */
- info("low_priority: entering elevated wait\n");
- low_unlocked = 0; /* prevent race with med_priority */
- status = pthread_barrier_wait(&elevate_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("low_priority: pthread_barrier_wait(elevate): %x\n", status);
- return NULL;
- }
- low_unlocked = 1;
-
- /* release the mutex */
- info("low_priority: unlocking mutex\n");
- pthread_mutex_unlock(&mutex);
-
- /* finish state */
- info("low_priority: entering finish wait\n");
- status = pthread_barrier_wait(&finish_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("low_priority: pthread_barrier_wait(elevate): %x\n", status);
- return NULL;
- }
-
- }
- /* let main know we're done */
- info("low_priority: entering exit state\n");
- status = pthread_barrier_wait(&all_threads_done);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("low_priority: pthread_barrier_wait(all_threads_done): %x", status);
- return NULL;
- }
- info("low_priority: exiting\n");
- return NULL;
-}
-
-void *med_priority(void *arg)
-{
- int status;
- struct thread_parameters *p = (struct thread_parameters *)arg;
-
- report_threadinfo("med_priority");
-
- info("med_priority: entering ready state\n");
- /* wait for all threads to be ready */
- status = pthread_barrier_wait(&all_threads_ready);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("med_priority: pthread_barrier_wait(all_threads_ready): %x", status);
- return NULL;
- }
-
- info("med_priority: starting inversion loop (%d)\n", p->inversions);
- while (p->inversions-- > 0) {
- /* start state */
- info("med_priority: entering start state (%d)\n", p->inversions+1);
- status = pthread_barrier_wait(&start_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("med_priority: pthread_barrier_wait(start): %x", status);
- return NULL;
- }
- info("med_priority: entering elevate state\n");
- do {
- status = pthread_barrier_wait(&elevate_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("med_priority: pthread_barrier_wait(elevate): %x", status);
- return NULL;
- }
- } while (!high_has_run && !low_unlocked);
- info("med_priority: entering finish state\n");
- status = pthread_barrier_wait(&finish_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("med_priority: pthread_barrier_wait(finished): %x", status);
- return NULL;
- }
- }
-
- info("med_priority: entering exit state\n");
- status = pthread_barrier_wait(&all_threads_done);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("med_priority: pthread_barrier_wait(all_threads_done): %x", status);
- return NULL;
- }
- info("med_priority: exiting\n");
- return NULL;
-}
-
-void *high_priority(void *arg)
-{
- int status;
- struct thread_parameters *p = (struct thread_parameters *)arg;
-
- report_threadinfo("high_priority");
-
- info("high_priority: entering ready state\n");
-
- /* wait for all threads to be ready */
- status = pthread_barrier_wait(&all_threads_ready);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("high_priority: pthread_barrier_wait(all_threads_ready): %x", status);
- return NULL;
- }
-
- info("high_priority: starting inversion loop (%d)\n", p->inversions);
- while (p->inversions-- > 0) {
- high_has_run = 0;
- info("high_priority: entering start state (%d)\n", p->inversions+1);
- status = pthread_barrier_wait(&start_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("high_priority: pthread_barrier_wait(start): %x", status);
- return NULL;
- }
- info("high_priority: entering running state\n");
- status = pthread_barrier_wait(&locked_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("high_priority: pthread_barrier_wait(running): %x", status);
- return NULL;
- }
- info("high_priority: locking mutex\n");
- pthread_mutex_lock(&mutex);
- info("high_priority: got mutex\n");
- high_has_run = 1;
- info("high_priority: unlocking mutex\n");
- pthread_mutex_unlock(&mutex);
- info("high_priority: entering finish state\n");
- status = pthread_barrier_wait(&finish_barrier);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("high_priority: pthread_barrier_wait(finish): %x", status);
- return NULL;
- }
- }
-
- info("high_priority: entering exit state\n");
- status = pthread_barrier_wait(&all_threads_done);
- if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
- error("high_priority: pthread_barrier_wait(all_threads_done): %x", status);
- return NULL;
- }
- info("high_priority: exiting\n");
- return NULL;
-}
-
-void error(char *fmt, ...)
-{
- va_list ap;
- fputs("ERROR: ", stderr);
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-
-void info(char *fmt, ...)
-{
- if (verbose) {
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- }
-}
diff --git a/src/pi_tests/classic_pi.odg b/src/pi_tests/classic_pi.odg
deleted file mode 100644
index 889294b..0000000
--- a/src/pi_tests/classic_pi.odg
+++ /dev/null
Binary files differ