Zephyr Project API 3.7.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
test_mutex_apis.c File Reference
#include <zephyr/ztest.h>

Macros

#define TIMEOUT   500
 
#define STACK_SIZE   (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
 
#define THREAD_HIGH_PRIORITY   1
 
#define THREAD_MID_PRIORITY   3
 
#define THREAD_LOW_PRIORITY   5
 

Functions

 K_MUTEX_DEFINE (kmutex)
 TESTPOINT: init via K_MUTEX_DEFINE.
 
static K_THREAD_STACK_DEFINE (tstack,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static K_THREAD_STACK_DEFINE (tstack2,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static K_THREAD_STACK_DEFINE (tstack3,(512+CONFIG_TEST_EXTRA_STACK_SIZE))
 
static void tThread_entry_lock_forever (void *p1, void *p2, void *p3)
 
static void tThread_entry_lock_no_wait (void *p1, void *p2, void *p3)
 
static void tThread_entry_lock_timeout_fail (void *p1, void *p2, void *p3)
 
static void tThread_entry_lock_timeout_pass (void *p1, void *p2, void *p3)
 
static void tmutex_test_lock (struct k_mutex *pmutex, void(*entry_fn)(void *, void *, void *))
 
static void tmutex_test_lock_timeout (struct k_mutex *pmutex, void(*entry_fn)(void *, void *, void *))
 
static void tmutex_test_lock_unlock (struct k_mutex *pmutex)
 
static void tThread_T1_priority_inheritance (void *p1, void *p2, void *p3)
 
static void tThread_T2_priority_inheritance (void *p1, void *p2, void *p3)
 
static void tThread_lock_with_time_period (void *p1, void *p2, void *p3)
 
static void tThread_waiter (void *p1, void *p2, void *p3)
 
 ZTEST_USER (mutex_api_1cpu, test_mutex_reent_lock_forever)
 
 ZTEST_USER (mutex_api, test_mutex_reent_lock_no_wait)
 
 ZTEST_USER (mutex_api, test_mutex_reent_lock_timeout_fail)
 
 ZTEST_USER (mutex_api_1cpu, test_mutex_reent_lock_timeout_pass)
 
 ZTEST_USER (mutex_api_1cpu, test_mutex_lock_unlock)
 
 ZTEST_USER (mutex_api, test_mutex_recursive)
 Test recursive mutex.
 
 ZTEST_USER (mutex_api_1cpu, test_mutex_priority_inheritance)
 Test mutex's priority inheritance mechanism.
 
static void tThread_mutex_lock_should_fail (void *p1, void *p2, void *p3)
 
 ZTEST (mutex_api_1cpu, test_mutex_timeout_race_during_priority_inversion)
 Test fix for subtle race during priority inversion.
 
static void * mutex_api_tests_setup (void)
 
 ZTEST_SUITE (mutex_api, NULL, mutex_api_tests_setup, NULL, NULL, NULL)
 
 ZTEST_SUITE (mutex_api_1cpu, NULL, mutex_api_tests_setup, ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL)
 

Variables

static ZTEST_DMEM int case_type
 
static ZTEST_DMEM int thread_ret = TC_FAIL
 
static struct k_mutex tmutex
 
static struct k_thread tdata
 
static struct k_thread tdata2
 
static struct k_thread tdata3
 

Macro Definition Documentation

◆ STACK_SIZE

#define STACK_SIZE   (512 + CONFIG_TEST_EXTRA_STACK_SIZE)

◆ THREAD_HIGH_PRIORITY

#define THREAD_HIGH_PRIORITY   1

◆ THREAD_LOW_PRIORITY

#define THREAD_LOW_PRIORITY   5

◆ THREAD_MID_PRIORITY

#define THREAD_MID_PRIORITY   3

◆ TIMEOUT

#define TIMEOUT   500

Function Documentation

◆ K_MUTEX_DEFINE()

K_MUTEX_DEFINE ( kmutex  )

TESTPOINT: init via K_MUTEX_DEFINE.

◆ K_THREAD_STACK_DEFINE() [1/3]

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

◆ K_THREAD_STACK_DEFINE() [2/3]

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

◆ K_THREAD_STACK_DEFINE() [3/3]

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

◆ mutex_api_tests_setup()

static void * mutex_api_tests_setup ( void  )
static

◆ tmutex_test_lock()

static void tmutex_test_lock ( struct k_mutex pmutex,
void(*)(void *, void *, void *)  entry_fn 
)
static

◆ tmutex_test_lock_timeout()

static void tmutex_test_lock_timeout ( struct k_mutex pmutex,
void(*)(void *, void *, void *)  entry_fn 
)
static

TESTPOINT: test k_mutex_init mutex

◆ tmutex_test_lock_unlock()

static void tmutex_test_lock_unlock ( struct k_mutex pmutex)
static

◆ tThread_entry_lock_forever()

static void tThread_entry_lock_forever ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_entry_lock_no_wait()

static void tThread_entry_lock_no_wait ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_entry_lock_timeout_fail()

static void tThread_entry_lock_timeout_fail ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_entry_lock_timeout_pass()

static void tThread_entry_lock_timeout_pass ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_lock_with_time_period()

static void tThread_lock_with_time_period ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_mutex_lock_should_fail()

static void tThread_mutex_lock_should_fail ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_T1_priority_inheritance()

static void tThread_T1_priority_inheritance ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_T2_priority_inheritance()

static void tThread_T2_priority_inheritance ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ tThread_waiter()

static void tThread_waiter ( void *  p1,
void *  p2,
void *  p3 
)
static

◆ ZTEST()

ZTEST ( mutex_api_1cpu  ,
test_mutex_timeout_race_during_priority_inversion   
)

Test fix for subtle race during priority inversion.

  • A low priority thread (Tlow) locks mutex A.
  • A high priority thread (Thigh) blocks on mutex A, boosting the priority of Tlow.
  • Thigh times out waiting for mutex A.
  • Before Thigh has a chance to execute, Tlow unlocks mutex A (which now has no owner) and drops its own priority.
  • Thigh now gets a chance to execute and finds that it timed out, and then enters the block of code to lower the priority of the thread that owns mutex A (now nobody).
  • Thigh tries to the dereference the owner of mutex A (which is nobody, and thus it is NULL). This leads to an exception.
See also
k_mutex_lock()

◆ ZTEST_SUITE() [1/2]

ZTEST_SUITE ( mutex_api  ,
NULL  ,
mutex_api_tests_setup  ,
NULL  ,
NULL  ,
NULL   
)

◆ ZTEST_SUITE() [2/2]

ZTEST_SUITE ( mutex_api_1cpu  ,
NULL  ,
mutex_api_tests_setup  ,
ztest_simple_1cpu_before  ,
ztest_simple_1cpu_after  ,
NULL   
)

◆ ZTEST_USER() [1/7]

ZTEST_USER ( mutex_api  ,
test_mutex_recursive   
)

Test recursive mutex.

To verify that getting a lock of a mutex already locked will succeed and waiters will be unblocked only when the number of locks reaches zero.

TESTPOINT: when mutex has no owner, we cannot unlock it

TESTPOINT: lock the mutex recursively

TESTPOINT: unlock the mutex recursively

TESTPOINT: waiter thread got the mutex

◆ ZTEST_USER() [2/7]

ZTEST_USER ( mutex_api  ,
test_mutex_reent_lock_no_wait   
)

TESTPOINT: test k_mutex_init mutex

TESTPOINT: test K_MUTEX_DEFINE mutex

◆ ZTEST_USER() [3/7]

ZTEST_USER ( mutex_api  ,
test_mutex_reent_lock_timeout_fail   
)

TESTPOINT: test k_mutex_init mutex

TESTPOINT: test K_MUTEX_DEFINE mutex

◆ ZTEST_USER() [4/7]

ZTEST_USER ( mutex_api_1cpu  ,
test_mutex_lock_unlock   
)

TESTPOINT: test k_mutex_init mutex

TESTPOINT: test K_MUTEX_DEFINE mutex

◆ ZTEST_USER() [5/7]

ZTEST_USER ( mutex_api_1cpu  ,
test_mutex_priority_inheritance   
)

Test mutex's priority inheritance mechanism.

To verify mutex provide priority inheritance to prevent priority inversion, and there are 3 cases need to run. The thread T1 hold the mutex first and cases list as below:

  • case 1. When priority T2 > T1, priority inheritance happened.
  • case 2. When priority T1 > T2, priority inheritance won't happened.
  • case 3. When priority T2 > T3 > T1, priority inheritance happened but T2 wait for timeout and T3 got the mutex.

TESTPOINT: run test case 1, given priority T1 < T2

TESTPOINT: The current thread does not own the mutex.

TESTPOINT: run test case 2, given priority T1 > T2, this means priority inheritance won't happen.

TESTPOINT: run test case 3, given priority T1 < T3 < T2, but t2 do not get mutex due to timeout.

◆ ZTEST_USER() [6/7]

ZTEST_USER ( mutex_api_1cpu  ,
test_mutex_reent_lock_forever   
)

TESTPOINT: test k_mutex_init mutex

TESTPOINT: test K_MUTEX_DEFINE mutex

◆ ZTEST_USER() [7/7]

ZTEST_USER ( mutex_api_1cpu  ,
test_mutex_reent_lock_timeout_pass   
)

TESTPOINT: test k_mutex_init mutex

TESTPOINT: test K_MUTEX_DEFINE mutex

Variable Documentation

◆ case_type

ZTEST_DMEM int case_type
static

◆ tdata

struct k_thread tdata
static

◆ tdata2

struct k_thread tdata2
static

◆ tdata3

struct k_thread tdata3
static

◆ thread_ret

ZTEST_DMEM int thread_ret = TC_FAIL
static

◆ tmutex

struct k_mutex tmutex
static