Zephyr Project API 3.7.2
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)   k_thread_start(&(thread_##id##_thread_data));
 
#define JOIN_PARTICIPANT_THREAD(id)   k_thread_join(&(thread_##id##_thread_data), K_FOREVER);
 
#define WAIT_FOR_MAIN()
 
#define ADVANCE_THREAD(id)
 
#define SIGNAL_THREAD(id)   k_sem_give(&thread_##id##_wait);
 
#define WAIT_FOR_THREAD(id)   zassert_ok(k_sem_take(&thread_##id##_done, K_MSEC(100)));
 

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)
 
 ZTEST (mutex_api, test_complex_inversion)
 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 STRINGIFY(s)
Definition common.h:134
#define PARTICIPANT_THREAD_OPTIONS
Definition complex_inversion.c:40
#define K_FOREVER
Generate infinite timeout delay.
Definition kernel.h:1363
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:437

◆ 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:3247
#define K_THREAD_STACK_DEFINE(sym, size)
Define a toplevel thread stack memory region.
Definition thread_stack.h:517
Thread Structure.
Definition thread.h:259

◆ JOIN_PARTICIPANT_THREAD

#define JOIN_PARTICIPANT_THREAD (   id)    k_thread_join(&(thread_##id##_thread_data), K_FOREVER);

◆ PARTICIPANT_THREAD_OPTIONS

#define PARTICIPANT_THREAD_OPTIONS   (K_INHERIT_PERMS)

◆ SIGNAL_THREAD

#define SIGNAL_THREAD (   id)    k_sem_give(&thread_##id##_wait);

◆ STACKSIZE

#define STACKSIZE   (512 + CONFIG_TEST_EXTRA_STACK_SIZE)

◆ START_PARTICIPANT_THREAD

#define START_PARTICIPANT_THREAD (   id)    k_thread_start(&(thread_##id##_thread_data));

◆ WAIT_FOR_MAIN

#define WAIT_FOR_MAIN ( )
Value:
k_sem_give(done); \
k_sem_take(wait, K_FOREVER);
void k_sem_give(struct k_sem *sem)
Give a semaphore.

◆ WAIT_FOR_THREAD

#define WAIT_FOR_THREAD (   id)    zassert_ok(k_sem_take(&thread_##id##_done, K_MSEC(100)));

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  ,
,
 
)
static

◆ K_SEM_DEFINE() [2/8]

static K_SEM_DEFINE ( thread_05_wait  ,
,
 
)
static

◆ K_SEM_DEFINE() [3/8]

static K_SEM_DEFINE ( thread_06_done  ,
,
 
)
static

◆ K_SEM_DEFINE() [4/8]

static K_SEM_DEFINE ( thread_06_wait  ,
,
 
)
static

◆ K_SEM_DEFINE() [5/8]

static K_SEM_DEFINE ( thread_07_done  ,
,
 
)
static

◆ K_SEM_DEFINE() [6/8]

static K_SEM_DEFINE ( thread_07_wait  ,
,
 
)
static

◆ K_SEM_DEFINE() [7/8]

static K_SEM_DEFINE ( thread_08_done  ,
,
 
)
static

◆ K_SEM_DEFINE() [8/8]

static K_SEM_DEFINE ( thread_08_wait  ,
,
 
)
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

◆ 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 -

◆ ZTEST()

ZTEST ( mutex_api  ,
test_complex_inversion   
)

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.

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