Zephyr API Documentation 4.1.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
complex_inversion.c File Reference

Test complex mutex priority inversion. More...

#include <zephyr/tc_util.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/sys/mutex.h>

Macros

#define STACKSIZE   (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
 
#define PARTICIPANT_THREAD_OPTIONS   (K_INHERIT_PERMS)
 
#define DEFINE_PARTICIPANT_THREAD(id)
 
#define CREATE_PARTICIPANT_THREAD(id, pri)
 
#define START_PARTICIPANT_THREAD(id)
 
#define JOIN_PARTICIPANT_THREAD(id)
 
#define WAIT_FOR_MAIN()
 
#define ADVANCE_THREAD(id)
 
#define SIGNAL_THREAD(id)
 
#define WAIT_FOR_THREAD(id)
 

Functions

static K_MUTEX_DEFINE (mutex_0)
 
static K_MUTEX_DEFINE (mutex_1)
 
static void thread_05 (struct k_sem *wait, struct k_sem *done)
 thread_05 -
 
static void thread_06 (struct k_sem *wait, struct k_sem *done)
 thread_06 -
 
static void thread_07 (struct k_sem *wait, struct k_sem *done)
 thread_07 -
 
static void thread_08 (struct k_sem *wait, struct k_sem *done)
 thread_08 -
 
static K_THREAD_STACK_DEFINE (thread_05_stack_area,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static K_SEM_DEFINE (thread_05_wait, 0, 1)
 
static K_SEM_DEFINE (thread_05_done, 0, 1)
 
static K_THREAD_STACK_DEFINE (thread_06_stack_area,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static K_SEM_DEFINE (thread_06_wait, 0, 1)
 
static K_SEM_DEFINE (thread_06_done, 0, 1)
 
static K_THREAD_STACK_DEFINE (thread_07_stack_area,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static K_SEM_DEFINE (thread_07_wait, 0, 1)
 
static K_SEM_DEFINE (thread_07_done, 0, 1)
 
static K_THREAD_STACK_DEFINE (thread_08_stack_area,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static K_SEM_DEFINE (thread_08_wait, 0, 1)
 
static K_SEM_DEFINE (thread_08_done, 0, 1)
 
static void create_participant_threads (void)
 
static void start_participant_threads (void)
 
static void join_participant_threads (void)
 
void test_complex_inversion (void)
 Main thread to test mutex locking.
 

Variables

static ZTEST_DMEM int tc_rc = TC_PASS
 
static struct k_thread thread_05_thread_data
 
static k_tid_t thread_05_tid
 
static struct k_thread thread_06_thread_data
 
static k_tid_t thread_06_tid
 
static struct k_thread thread_07_thread_data
 
static k_tid_t thread_07_tid
 
static struct k_thread thread_08_thread_data
 
static k_tid_t thread_08_tid
 

Detailed Description

Test complex mutex priority inversion.

This module demonstrates the kernel's priority inheritance algorithm with two mutexes and four threads, ensuring that boosting priority of a thread waiting on another mutex does not break assumptions of the mutex's waitq, causing the incorrect thread to run or a crash.

Sequence for priority inheritance testing:

  • thread_08 takes mutex_1
  • thread_07 takes mutex_0 then waits on mutex_1
  • thread_06 waits on mutex_1
  • thread_05 waits on mutex_0, boosting priority of thread_07
  • thread_08 gives mutex_1, thread_07 takes mutex_1
  • thread_07 gives mutex_1, thread_06 takes mutex_1
  • thread_07 gives mutex_0, thread_05 takes mutex_0
  • thread_06 gives mutex_1
  • thread_05 gives mutex_0

Macro Definition Documentation

◆ ADVANCE_THREAD

#define ADVANCE_THREAD ( id)
Value:
WAIT_FOR_THREAD(id);
#define SIGNAL_THREAD(id)
Definition complex_inversion.c:67

◆ CREATE_PARTICIPANT_THREAD

#define CREATE_PARTICIPANT_THREAD ( id,
pri )
Value:
thread_##id##_tid = k_thread_create(&thread_##id##_thread_data, thread_##id##_stack_area, \
K_THREAD_STACK_SIZEOF(thread_##id##_stack_area), \
(k_thread_entry_t)thread_##id, &thread_##id##_wait, \
&thread_##id##_done, NULL, pri, \
k_thread_name_set(thread_##id##_tid, "thread_" STRINGIFY(id));
void(* k_thread_entry_t)(void *p1, void *p2, void *p3)
Thread entry point function type.
Definition arch_interface.h:48
#define PARTICIPANT_THREAD_OPTIONS
Definition complex_inversion.c:40
#define K_FOREVER
Generate infinite timeout delay.
Definition kernel.h:1481
k_tid_t k_thread_create(struct k_thread *new_thread, k_thread_stack_t *stack, size_t stack_size, k_thread_entry_t entry, void *p1, void *p2, void *p3, int prio, uint32_t options, k_timeout_t delay)
Create a thread.
#define K_THREAD_STACK_SIZEOF(sym)
Return the size in bytes of a stack memory region.
Definition thread_stack.h:436
#define NULL
Definition iar_missing_defs.h:20
#define STRINGIFY(s)
Definition common.h:166

◆ DEFINE_PARTICIPANT_THREAD

#define DEFINE_PARTICIPANT_THREAD ( id)
Value:
static K_THREAD_STACK_DEFINE(thread_##id##_stack_area, STACKSIZE); \
static struct k_thread thread_##id##_thread_data; \
static k_tid_t thread_##id##_tid; \
static K_SEM_DEFINE(thread_##id##_wait, 0, 1); \
static K_SEM_DEFINE(thread_##id##_done, 0, 1);
#define STACKSIZE
Definition complex_inversion.c:33
#define K_SEM_DEFINE(name, initial_count, count_limit)
Statically define and initialize a semaphore.
Definition kernel.h:3384
#define K_THREAD_STACK_DEFINE(sym, size)
Define a toplevel thread stack memory region.
Definition thread_stack.h:516
Thread Structure.
Definition thread.h:262

◆ JOIN_PARTICIPANT_THREAD

#define JOIN_PARTICIPANT_THREAD ( id)
Value:
k_thread_join(&(thread_##id##_thread_data), K_FOREVER);
int k_thread_join(struct k_thread *thread, k_timeout_t timeout)
Sleep until a thread exits.

◆ PARTICIPANT_THREAD_OPTIONS

#define PARTICIPANT_THREAD_OPTIONS   (K_INHERIT_PERMS)

◆ SIGNAL_THREAD

#define SIGNAL_THREAD ( id)
Value:
k_sem_give(&thread_##id##_wait);
void k_sem_give(struct k_sem *sem)
Give a semaphore.

◆ STACKSIZE

#define STACKSIZE   (512 + CONFIG_TEST_EXTRA_STACK_SIZE)

◆ START_PARTICIPANT_THREAD

#define START_PARTICIPANT_THREAD ( id)
Value:
k_thread_start(&(thread_##id##_thread_data));
static void k_thread_start(k_tid_t thread)
Start an inactive thread.
Definition kernel.h:1103

◆ WAIT_FOR_MAIN

#define WAIT_FOR_MAIN ( )
Value:
k_sem_give(done); \
k_sem_take(wait, K_FOREVER);

◆ WAIT_FOR_THREAD

#define WAIT_FOR_THREAD ( id)
Value:
zassert_ok(k_sem_take(&thread_##id##_done, K_MSEC(100)));
#define K_MSEC(ms)
Generate timeout delay from milliseconds.
Definition kernel.h:1435
int k_sem_take(struct k_sem *sem, k_timeout_t timeout)
Take a semaphore.
#define zassert_ok(cond,...)
Assert that cond is 0 (success)
Definition ztest_assert.h:289

Function Documentation

◆ create_participant_threads()

static void create_participant_threads ( void )
static

◆ join_participant_threads()

static void join_participant_threads ( void )
static

◆ K_MUTEX_DEFINE() [1/2]

static K_MUTEX_DEFINE ( mutex_0 )
static

◆ K_MUTEX_DEFINE() [2/2]

static K_MUTEX_DEFINE ( mutex_1 )
static

◆ K_SEM_DEFINE() [1/8]

static K_SEM_DEFINE ( thread_05_done ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [2/8]

static K_SEM_DEFINE ( thread_05_wait ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [3/8]

static K_SEM_DEFINE ( thread_06_done ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [4/8]

static K_SEM_DEFINE ( thread_06_wait ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [5/8]

static K_SEM_DEFINE ( thread_07_done ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [6/8]

static K_SEM_DEFINE ( thread_07_wait ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [7/8]

static K_SEM_DEFINE ( thread_08_done ,
0 ,
1  )
static

◆ K_SEM_DEFINE() [8/8]

static K_SEM_DEFINE ( thread_08_wait ,
0 ,
1  )
static

◆ K_THREAD_STACK_DEFINE() [1/4]

static K_THREAD_STACK_DEFINE ( thread_05_stack_area ,
(512+CONFIG_TEST_EXTRA_STACK_SIZE)  )
static

◆ K_THREAD_STACK_DEFINE() [2/4]

static K_THREAD_STACK_DEFINE ( thread_06_stack_area ,
(512+CONFIG_TEST_EXTRA_STACK_SIZE)  )
static

◆ K_THREAD_STACK_DEFINE() [3/4]

static K_THREAD_STACK_DEFINE ( thread_07_stack_area ,
(512+CONFIG_TEST_EXTRA_STACK_SIZE)  )
static

◆ K_THREAD_STACK_DEFINE() [4/4]

static K_THREAD_STACK_DEFINE ( thread_08_stack_area ,
(512+CONFIG_TEST_EXTRA_STACK_SIZE)  )
static

◆ start_participant_threads()

static void start_participant_threads ( void )
static

◆ test_complex_inversion()

void test_complex_inversion ( void )

Main thread to test mutex locking.

This thread orchestrates mutex locking on other threads and verifies that the correct thread is holding mutexes at any given step.

◆ thread_05()

static void thread_05 ( struct k_sem * wait,
struct k_sem * done )
static

thread_05 -

◆ thread_06()

static void thread_06 ( struct k_sem * wait,
struct k_sem * done )
static

thread_06 -

◆ thread_07()

static void thread_07 ( struct k_sem * wait,
struct k_sem * done )
static

thread_07 -

◆ thread_08()

static void thread_08 ( struct k_sem * wait,
struct k_sem * done )
static

thread_08 -

Variable Documentation

◆ tc_rc

ZTEST_DMEM int tc_rc = TC_PASS
static

◆ thread_05_thread_data

struct k_thread thread_05_thread_data
static

◆ thread_05_tid

k_tid_t thread_05_tid
static

◆ thread_06_thread_data

struct k_thread thread_06_thread_data
static

◆ thread_06_tid

k_tid_t thread_06_tid
static

◆ thread_07_thread_data

struct k_thread thread_07_thread_data
static

◆ thread_07_tid

k_tid_t thread_07_tid
static

◆ thread_08_thread_data

struct k_thread thread_08_thread_data
static

◆ thread_08_tid

k_tid_t thread_08_tid
static