This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit e2486dfc09e6c7657da829f2b9ebf7074200e270 Author: ouyangxiangzhen <[email protected]> AuthorDate: Thu Feb 5 09:55:20 2026 +0800 ostest/spinlock: Update the comments. This commit updated the comments. Assisted-By: mimo-v2.6-pro Signed-off-by: ouyangxiangzhen <[email protected]> --- testing/ostest/spinlock.c | 196 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 171 insertions(+), 25 deletions(-) diff --git a/testing/ostest/spinlock.c b/testing/ostest/spinlock.c index db4f32ffc..e62b5bd28 100644 --- a/testing/ostest/spinlock.c +++ b/testing/ostest/spinlock.c @@ -38,21 +38,37 @@ * Preprocessor Definitions ****************************************************************************/ +/* Maximum number of test threads - typically one per CPU core */ + #define MAX_THREAD_NUM (CONFIG_SMP_NCPUS) -#define LOOP_TIMES (CONFIG_TESTING_LOOP_SCALE * 100000) +/* Number of lock/unlock iterations per thread */ + +#define LOOP_TIMES (CONFIG_TESTING_LOOP_SCALE * 10000) + +/**************************************************************************** + * Type Definitions + ****************************************************************************/ + +/* Shared arguments for all test threads. + * This structure contains data that all threads need to access. + */ aligned_data(64) struct spinlock_pub_args_s { - FAR void *lock; - volatile uint32_t counter; - atomic_t barrier; - uint32_t thread_num; + FAR void *lock; /* Pointer to the lock being tested */ + volatile uint32_t counter; /* Shared counter protected by the lock */ + atomic_t barrier; /* Synchronization barrier for thread startup */ + uint32_t thread_num; /* Total number of threads participating */ }; +/* Per-thread arguments. + * Each thread has its own instance of this structure. + */ + struct spinlock_thread_args_s { - uint64_t delta; - FAR struct spinlock_pub_args_s *pub; + uint64_t delta; /* Execution time for this thread (nanoseconds) */ + FAR struct spinlock_pub_args_s *pub; /* Pointer to shared arguments */ }; aligned_data(64) union spinlock_test_u @@ -66,7 +82,23 @@ aligned_data(64) union spinlock_test_u * Private Functions ****************************************************************************/ -/* Helper functions for timespec calculating */ +/**************************************************************************** + * Name: calc_diff + * + * Description: + * Calculate time difference between two timespec structures. + * This function computes the elapsed time between start and end times, + * handling the case where the nanoseconds component of the end time + * is less than the start time (requiring a borrow from seconds). + * + * Input Parameters: + * start - Pointer to the starting timespec + * end - Pointer to the ending timespec + * + * Returned Value: + * Time difference in nanoseconds + * + ****************************************************************************/ static inline uint64_t calc_diff(FAR struct timespec *start, FAR struct timespec *end) @@ -83,31 +115,63 @@ static inline uint64_t calc_diff(FAR struct timespec *start, return diff_sec * 1000000000ULL + diff_nsec; } +/**************************************************************************** + * Name: LOCK_TEST_FUNC + * + * Description: + * Test thread function for different lock types. + * This macro generates a test thread function for a specific lock type. + * Each thread performs LOOP_TIMES lock/unlock operations and measures + * the execution time. + * + * Input Parameters: + * lock_type - Type of lock to test (e.g., spinlock_t, rspinlock_t) + * lock_func - Lock acquisition function + * unlock_func - Lock release function + * + * Returned Value: + * None + * + ****************************************************************************/ + #define LOCK_TEST_FUNC(lock_type, lock_func, unlock_func) \ FAR static void * lock_type##_test_thread(FAR void *arg) \ { \ struct spinlock_thread_args_s *param = \ (struct spinlock_thread_args_s *)arg; \ - irqstate_t flags; \ + irqstate_t flags; \ struct timespec start; \ struct timespec end; \ - uint32_t i; \ + uint32_t idx; \ FAR struct spinlock_pub_args_s *pub = param->pub; \ - FAR lock_type *l = (FAR lock_type *)pub->lock; \ + FAR lock_type *lock = (FAR lock_type *)pub->lock; \ + \ + /* Synchronize thread startup using atomic barrier */ \ + \ atomic_add(&pub->barrier, 1); \ while (atomic_read(&pub->barrier) != pub->thread_num) \ { \ sched_yield(); \ } \ + \ + /* Start timing */ \ + \ clock_gettime(CLOCK_REALTIME, &start); \ - for (i = 0; i < LOOP_TIMES; i++) \ + \ + /* Perform lock/unlock operations */ \ + \ + for (idx = 0; idx < LOOP_TIMES; idx++) \ { \ - flags = lock_func(l); \ + flags = lock_func(lock); \ pub->counter++; \ - unlock_func(l, flags); \ + unlock_func(lock, flags); \ } \ + \ + /* Stop timing and calculate duration */ \ + \ clock_gettime(CLOCK_REALTIME, &end); \ param->delta = calc_diff(&start, &end); \ + \ return NULL; \ } @@ -115,21 +179,41 @@ LOCK_TEST_FUNC(spinlock_t, spin_lock_irqsave, spin_unlock_irqrestore) LOCK_TEST_FUNC(rspinlock_t, rspin_lock_irqsave, rspin_unlock_irqrestore) LOCK_TEST_FUNC(seqcount_t, write_seqlock_irqsave, write_sequnlock_irqrestore) +/**************************************************************************** + * Name: run_test_thread + * + * Description: + * Run a multi-threaded lock performance test. + * This function creates multiple threads that concurrently perform + * lock/unlock operations on the same lock. It measures the total + * execution time and calculates throughput. + * + * Input Parameters: + * lock - Pointer to the lock being tested + * thread_func - Thread function that performs lock operations + * thread_num - Number of threads to create + * lock_type - String describing the lock type (for output) + * + * Returned Value: + * None + * + ****************************************************************************/ + static inline void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), uint32_t thread_num, const char *lock_type) { - pthread_t tid[MAX_THREAD_NUM]; - struct spinlock_pub_args_s pub; - pthread_attr_t attr; - struct sched_param sparam; + struct spinlock_pub_args_s pub; + pthread_attr_t attr; + struct sched_param sparam; + pthread_t tid[MAX_THREAD_NUM]; struct spinlock_thread_args_s param[MAX_THREAD_NUM]; - struct timespec stime; - struct timespec etime; - cpu_set_t cpu_set = 1u; - uint64_t total_ns = 0u; - int status; - int i; + struct timespec stime; + struct timespec etime; + int status; + int i; + cpu_set_t cpu_set = 1u; + uint64_t total_ns = 0u; /* Initialize the public parameters. */ @@ -212,6 +296,8 @@ void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), } } + /* Wait for all threads to complete */ + for (i = 0; i < thread_num; i++) { status = pthread_join(tid[i], NULL); @@ -252,7 +338,21 @@ void run_test_thread(void *lock, FAR void *(*thread_func)(FAR void *arg), ****************************************************************************/ /**************************************************************************** - * Name: spinlock_test + * Name: spinlock_test_thread_num + * + * Description: + * Run lock performance tests for a specific number of threads. + * This function tests three different lock types: + * - spinlock_t: Basic spinlock + * - rspinlock_t: Recursive spinlock + * - seqcount_t: Sequence counter lock + * + * Input Parameters: + * thread_num - Number of threads to use in the test + * + * Returned Value: + * None + * ****************************************************************************/ static void spinlock_test_thread_num(unsigned thread_num) @@ -261,16 +361,39 @@ static void spinlock_test_thread_num(unsigned thread_num) printf("Thread num: %u, Loop times: %d\n\n", thread_num, LOOP_TIMES); + /* Test basic spinlock */ + spin_lock_init(&lock.spinlock); run_test_thread(&lock, spinlock_t_test_thread, thread_num, "spinlock"); + /* Test recursive spinlock */ + rspin_lock_init(&lock.rspinlock); run_test_thread(&lock, rspinlock_t_test_thread, thread_num, "rspinlock"); + /* Test sequence counter lock */ + seqlock_init(&lock.seqcount); run_test_thread(&lock, seqcount_t_test_thread, thread_num, "seqcount"); } +/**************************************************************************** + * Name: spinlock_test_thread + * + * Description: + * Main test thread function that runs tests with varying thread counts. + * This function iterates through different thread counts (1 to + * MAX_THREAD_NUM) to test lock performance under different concurrency + * levels. + * + * Input Parameters: + * arg - Unused argument + * + * Returned Value: + * Always returns NULL + * + ****************************************************************************/ + static void *spinlock_test_thread(void *arg) { unsigned tnr; @@ -283,20 +406,43 @@ static void *spinlock_test_thread(void *arg) return NULL; } +/**************************************************************************** + * Name: spinlock_test + * + * Description: + * Entry point for the spinlock performance test suite. + * This function creates a test thread at a high priority to run + * the lock performance tests. The tests measure throughput and + * execution time for different lock types under varying thread counts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + void spinlock_test(void) { pthread_t tid; pthread_attr_t attr; struct sched_param sparam; + /* Initialize thread attributes */ + ASSERT(0 == pthread_attr_init(&attr)); + /* Set the test thread priority to SCHED_PRIORITY_MAX */ + ASSERT(0 == sched_getparam(getpid(), &sparam)); sparam.sched_priority = SCHED_PRIORITY_MAX; ASSERT(0 == pthread_attr_setschedparam(&attr, &sparam)); printf("spinlock_test: start......\n"); + /* Create and run the test thread */ + ASSERT(0 == pthread_create(&tid, &attr, spinlock_test_thread, NULL)); ASSERT(0 == pthread_join(tid, NULL));
