2626#include <assert.h>
2727#include <errno.h>
2828#include <nuttx/spinlock.h>
29+ #include <stdatomic.h>
2930
3031#include "ostest.h"
3132
@@ -42,33 +43,39 @@ static spinlock_t lock = SP_UNLOCKED;
4243static pthread_t g_thread1 ;
4344static pthread_t g_thread2 ;
4445
46+ #ifdef CONFIG_RW_SPINLOCK
47+ static pthread_t g_thread3 ;
48+ static rwlock_t rw_lock = RW_SP_UNLOCKED ;
49+ static atomic_int reader_counter = 0 ;
50+ #endif
51+
4552static int g_result = 0 ;
4653
47- static FAR void thread_spinlock ( FAR void * parameter )
54+ static FAR void * thread_native_spinlock ( FAR FAR void * parameter )
4855{
49- int pid = * (int * )parameter ;
56+ int pid = * (FAR int * )parameter ;
5057
5158 for (int i = 0 ; i < 10 ; i ++ )
5259 {
53- printf ("pid %d get lock g_result:%d\n" , pid , g_result );
60+ printf ("pid %d try to get lock g_result:%d\n" , pid , g_result );
5461 spin_lock (& lock );
5562 g_result ++ ;
5663 spin_unlock (& lock );
5764 printf ("pid %d release lock g_result:%d\n" , pid , g_result );
5865 }
59- }
6066
61- /****************************************************************************
62- * Public Functions
63- ****************************************************************************/
67+ return NULL ;
68+ }
6469
65- void spinlock_test (void )
70+ static FAR void test_native_spinlock (void )
6671{
6772 int status ;
6873 g_result = 0 ;
74+ lock = SP_UNLOCKED ;
75+ spin_initialize (& lock , SP_UNLOCKED );
6976
7077 status = pthread_create (& g_thread1 , NULL ,
71- ( void * ) thread_spinlock , & g_thread1 );
78+ thread_native_spinlock , & g_thread1 );
7279 if (status != 0 )
7380 {
7481 printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
@@ -77,7 +84,7 @@ void spinlock_test(void)
7784 }
7885
7986 status = pthread_create (& g_thread2 , NULL ,
80- ( void * ) thread_spinlock , & g_thread2 );
87+ thread_native_spinlock , & g_thread2 );
8188 if (status != 0 )
8289 {
8390 printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
@@ -90,3 +97,97 @@ void spinlock_test(void)
9097
9198 assert (g_result == 20 );
9299}
100+
101+ #if defined(CONFIG_RW_SPINLOCK )
102+ static void FAR * thread_read_spinlock (FAR void * parameter )
103+ {
104+ int pid = * (FAR int * )parameter ;
105+ int test ;
106+
107+ for (int i = 0 ; i < 10 ; ++ i )
108+ {
109+ printf ("pid %d try to get read lock g_result:%d\n" , pid , g_result );
110+ read_lock (& rw_lock );
111+ atomic_fetch_add (& reader_counter , 1 );
112+ test = g_result + 1 ;
113+ atomic_fetch_sub (& reader_counter , 1 );
114+ read_unlock (& rw_lock );
115+ printf ("pid %d release read lock g_result+1:%d\n" , pid , test );
116+ }
117+
118+ return NULL ;
119+ }
120+
121+ static void FAR * thread_wrt_spinlock (FAR void * parameter )
122+ {
123+ static int writer_counter = 0 ;
124+ int pid = * (FAR int * )parameter ;
125+
126+ for (int i = 0 ; i < 10 ; ++ i )
127+ {
128+ printf ("pid %d try to get write lock g_result:%d\n" , pid , g_result );
129+ write_lock (& rw_lock );
130+ writer_counter += 1 ;
131+ g_result ++ ;
132+ ASSERT (atomic_load (& reader_counter ) == 0 && writer_counter == 1 );
133+ writer_counter -= 1 ;
134+ write_unlock (& rw_lock );
135+ printf ("pid %d release write lock g_result:%d\n" , pid , g_result );
136+ }
137+
138+ return NULL ;
139+ }
140+
141+ static FAR void test_rw_spinlock (void )
142+ {
143+ int status ;
144+ g_result = 0 ;
145+ rwlock_init (& rw_lock );
146+
147+ status = pthread_create (& g_thread1 , NULL ,
148+ thread_read_spinlock , & g_thread1 );
149+ if (status != 0 )
150+ {
151+ printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
152+ status );
153+ ASSERT (false);
154+ }
155+
156+ status = pthread_create (& g_thread2 , NULL ,
157+ thread_read_spinlock , & g_thread2 );
158+ if (status != 0 )
159+ {
160+ printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
161+ status );
162+ ASSERT (false);
163+ }
164+
165+ status = pthread_create (& g_thread3 , NULL ,
166+ thread_wrt_spinlock , & g_thread3 );
167+ if (status != 0 )
168+ {
169+ printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
170+ status );
171+ ASSERT (false);
172+ }
173+
174+ pthread_join (g_thread1 , NULL );
175+ pthread_join (g_thread2 , NULL );
176+ pthread_join (g_thread3 , NULL );
177+
178+ assert (g_result == 10 );
179+ }
180+ #endif
181+
182+ /****************************************************************************
183+ * Public Functions
184+ ****************************************************************************/
185+
186+ void spinlock_test (void )
187+ {
188+ test_native_spinlock ();
189+
190+ #if defined(CONFIG_RW_SPINLOCK )
191+ test_rw_spinlock ();
192+ #endif
193+ }
0 commit comments