Skip to content

Commit 0dda3b2

Browse files
committed
feature: read-write spinlock test
Signed-off-by: TaiJu Wu <[email protected]>
1 parent 26d597c commit 0dda3b2

File tree

1 file changed

+111
-10
lines changed

1 file changed

+111
-10
lines changed

testing/ostest/spinlock.c

+111-10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
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;
4243
static pthread_t g_thread1;
4344
static 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+
4552
static 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

Comments
 (0)