26
26
#include <assert.h>
27
27
#include <errno.h>
28
28
#include <nuttx/spinlock.h>
29
+ #include <stdatomic.h>
29
30
30
31
#include "ostest.h"
31
32
@@ -42,33 +43,39 @@ static spinlock_t lock = SP_UNLOCKED;
42
43
static pthread_t g_thread1 ;
43
44
static pthread_t g_thread2 ;
44
45
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
+
45
52
static int g_result = 0 ;
46
53
47
- static FAR void thread_spinlock ( FAR void * parameter )
54
+ static FAR void * thread_native_spinlock ( FAR FAR void * parameter )
48
55
{
49
- int pid = * (int * )parameter ;
56
+ int pid = * (FAR int * )parameter ;
50
57
51
58
for (int i = 0 ; i < 10 ; i ++ )
52
59
{
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 );
54
61
spin_lock (& lock );
55
62
g_result ++ ;
56
63
spin_unlock (& lock );
57
64
printf ("pid %d release lock g_result:%d\n" , pid , g_result );
58
65
}
59
- }
60
66
61
- /****************************************************************************
62
- * Public Functions
63
- ****************************************************************************/
67
+ return NULL ;
68
+ }
64
69
65
- void spinlock_test (void )
70
+ static FAR void test_native_spinlock (void )
66
71
{
67
72
int status ;
68
73
g_result = 0 ;
74
+ lock = SP_UNLOCKED ;
75
+ spin_initialize (& lock , SP_UNLOCKED );
69
76
70
77
status = pthread_create (& g_thread1 , NULL ,
71
- ( void * ) thread_spinlock , & g_thread1 );
78
+ thread_native_spinlock , & g_thread1 );
72
79
if (status != 0 )
73
80
{
74
81
printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
@@ -77,7 +84,7 @@ void spinlock_test(void)
77
84
}
78
85
79
86
status = pthread_create (& g_thread2 , NULL ,
80
- ( void * ) thread_spinlock , & g_thread2 );
87
+ thread_native_spinlock , & g_thread2 );
81
88
if (status != 0 )
82
89
{
83
90
printf ("spinlock_test: ERROR pthread_create failed, status=%d\n" ,
@@ -90,3 +97,97 @@ void spinlock_test(void)
90
97
91
98
assert (g_result == 20 );
92
99
}
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