support for read/write-lock and read/write-trylock
Change-Id: I609071c0f6234d0d413c8b312d8a8379abf6846e Refs: #1323
This commit is contained in:
committed by
Masamichi Takagi
parent
8efced7bf7
commit
258156b57e
13
test/issues/1323/Makefile
Normal file
13
test/issues/1323/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
CC = gcc
|
||||
TARGET = rwlock
|
||||
|
||||
all:: $(TARGET)
|
||||
|
||||
rwlock: rwlock.c
|
||||
$(CC) -g -Wall -o $@ $^ -lpthread
|
||||
|
||||
test:: all
|
||||
sh ./rwlock.sh
|
||||
|
||||
clean::
|
||||
rm -f $(TARGET) *.o
|
||||
19
test/issues/1323/README
Normal file
19
test/issues/1323/README
Normal file
@@ -0,0 +1,19 @@
|
||||
【read/write lock 動作確認】
|
||||
□ テスト内容
|
||||
rwlock test 1: write_lock のテストを行う
|
||||
rwlock test 2: write_trylock のテストを行う
|
||||
rwlock test 3: write_lock と read_lock のテストを行う
|
||||
rwlock test 4: write_trylock と read_trylock のテストを行う
|
||||
|
||||
□ 実行手順
|
||||
$ make test
|
||||
|
||||
McKernelのインストール先は、$HOME/.mck_test_config を
|
||||
参照する。.mck_test_config は、McKernel をビルドした際に生成される
|
||||
mck_test_config.sample ファイルを $HOME にコピーし、適宜編集すること。
|
||||
|
||||
尚、テスト実行には rwlock.patch を適用した McKernel を使用すること。
|
||||
|
||||
□ 実行結果
|
||||
rwlock.txt 参照。
|
||||
全ての項目が PASS していることを確認。
|
||||
74
test/issues/1323/rwlock.c
Normal file
74
test/issues/1323/rwlock.c
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
int cmd;
|
||||
int procs;
|
||||
int rc;
|
||||
|
||||
void *
|
||||
rwtest(void *arg)
|
||||
{
|
||||
int r = syscall(750, cmd, procs);
|
||||
|
||||
if (r)
|
||||
rc = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
pthread_t *threads;
|
||||
int i;
|
||||
|
||||
if (!argv[1]) {
|
||||
long val = syscall(750, 10);
|
||||
int running = syscall(750, 11);
|
||||
long lockval = syscall(750, 12);
|
||||
|
||||
fprintf(stderr, "%ld %d %016lx\n", val, running, lockval);
|
||||
exit(0);
|
||||
}
|
||||
cmd = atoi(argv[1]);
|
||||
if (cmd < 1 || cmd > 4) {
|
||||
fprintf(stderr, "invalid test ID (%s)\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (!argv[2]) {
|
||||
fprintf(stderr, "no procs present\n");
|
||||
exit(1);
|
||||
}
|
||||
procs = atoi(argv[2]);
|
||||
if (procs < 1) {
|
||||
fprintf(stderr, "invalid procs (%s)\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
if (syscall(750, 0) == -1) {
|
||||
fprintf(stderr, "invalid test environment\n");
|
||||
exit(1);
|
||||
}
|
||||
threads = malloc(sizeof(pthread_t) * procs);
|
||||
for (i = 0; i < procs; i++) {
|
||||
if (pthread_create(threads + i, NULL, rwtest, NULL)) {
|
||||
fprintf(stderr, "pthread_create: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
rc = 0;
|
||||
for (i = 0; i < procs; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
if (rc) {
|
||||
fprintf(stderr, "rwlock test %d FAIL\n", cmd);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "rwlock test %d PASS\n", cmd);
|
||||
exit(0);
|
||||
}
|
||||
239
test/issues/1323/rwlock.patch
Normal file
239
test/issues/1323/rwlock.patch
Normal file
@@ -0,0 +1,239 @@
|
||||
diff --git a/arch/arm64/kernel/include/syscall_list.h b/arch/arm64/kernel/include/syscall_list.h
|
||||
index f911674..fe089fc 100644
|
||||
--- a/arch/arm64/kernel/include/syscall_list.h
|
||||
+++ b/arch/arm64/kernel/include/syscall_list.h
|
||||
@@ -134,6 +134,8 @@ SYSCALL_HANDLED(731, util_indicate_clone)
|
||||
SYSCALL_HANDLED(732, get_system)
|
||||
SYSCALL_HANDLED(733, util_register_desc)
|
||||
|
||||
+SYSCALL_HANDLED(750, rwlock_test)
|
||||
+
|
||||
/* McKernel Specific */
|
||||
SYSCALL_HANDLED(801, swapout)
|
||||
SYSCALL_HANDLED(802, linux_mlock)
|
||||
diff --git a/arch/x86_64/kernel/include/syscall_list.h b/arch/x86_64/kernel/include/syscall_list.h
|
||||
index 79eda7f..4fac75c 100644
|
||||
--- a/arch/x86_64/kernel/include/syscall_list.h
|
||||
+++ b/arch/x86_64/kernel/include/syscall_list.h
|
||||
@@ -174,6 +174,8 @@ SYSCALL_HANDLED(731, util_indicate_clone)
|
||||
SYSCALL_HANDLED(732, get_system)
|
||||
SYSCALL_HANDLED(733, util_register_desc)
|
||||
|
||||
+SYSCALL_HANDLED(750, rwlock_test)
|
||||
+
|
||||
/* McKernel Specific */
|
||||
SYSCALL_HANDLED(801, swapout)
|
||||
SYSCALL_HANDLED(802, linux_mlock)
|
||||
diff --git a/kernel/syscall.c b/kernel/syscall.c
|
||||
index 06d3d48..acdd702 100644
|
||||
--- a/kernel/syscall.c
|
||||
+++ b/kernel/syscall.c
|
||||
@@ -9482,6 +9482,208 @@ SYSCALL_DECLARE(util_register_desc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+SYSCALL_DECLARE(rwlock_test)
|
||||
+{
|
||||
+ int cmd = (int)ihk_mc_syscall_arg0(ctx);
|
||||
+ int procs = (int)ihk_mc_syscall_arg1(ctx);
|
||||
+ static ihk_atomic_t barrier;
|
||||
+ static int counter;
|
||||
+ static struct ihk_rwlock lock;
|
||||
+ int i;
|
||||
+ int bsp;
|
||||
+ union {
|
||||
+ int rcint;
|
||||
+ long rclong;
|
||||
+ } retval;
|
||||
+
|
||||
+ switch(cmd) {
|
||||
+ case 0:
|
||||
+ ihk_mc_rwlock_init(&lock);
|
||||
+ return 0;
|
||||
+
|
||||
+ case 1:
|
||||
+ bsp = ihk_atomic_inc_return(&barrier) == 1;
|
||||
+ if (bsp) {
|
||||
+ kprintf("rwlock_test 1 start\n");
|
||||
+ counter = 0;
|
||||
+ }
|
||||
+ while (ihk_atomic_read(&barrier) != procs) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 100000; i++) {
|
||||
+ ihk_mc_write_lock(&lock);
|
||||
+ counter++;
|
||||
+ ihk_mc_write_unlock(&lock);
|
||||
+ }
|
||||
+ ihk_atomic_dec(&barrier);
|
||||
+ while (ihk_atomic_read(&barrier) != 0) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ if (bsp) {
|
||||
+ if (counter == 100000 * procs) {
|
||||
+ kprintf("rwlock_test 1 OK\n");
|
||||
+ }
|
||||
+ else {
|
||||
+ kprintf("rwlock_test 1 NG %d != %d\n",
|
||||
+ ihk_atomic_read(&barrier),
|
||||
+ 100000 * procs);
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case 2:
|
||||
+ bsp = ihk_atomic_inc_return(&barrier) == 1;
|
||||
+ if (bsp) {
|
||||
+ kprintf("rwlock_test 2 start\n");
|
||||
+ counter = 0;
|
||||
+ }
|
||||
+ while (ihk_atomic_read(&barrier) != procs) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 100000; i++) {
|
||||
+ while (!ihk_mc_write_trylock(&lock)) {
|
||||
+ while (!ihk_mc_write_can_lock(&lock)) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+ }
|
||||
+ counter++;
|
||||
+ ihk_mc_write_unlock(&lock);
|
||||
+ }
|
||||
+ ihk_atomic_dec(&barrier);
|
||||
+ while (ihk_atomic_read(&barrier) != 0) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ if (bsp) {
|
||||
+ if (counter == 100000 * procs) {
|
||||
+ kprintf("rwlock_test 2 OK\n");
|
||||
+ }
|
||||
+ else {
|
||||
+ kprintf("rwlock_test 2 NG %d != %d\n",
|
||||
+ ihk_atomic_read(&barrier),
|
||||
+ 100000 * procs);
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case 3:
|
||||
+ bsp = ihk_atomic_inc_return(&barrier) == 1;
|
||||
+ if (bsp) {
|
||||
+ kprintf("rwlock_test 3 start\n");
|
||||
+ counter = 0;
|
||||
+ }
|
||||
+ while (ihk_atomic_read(&barrier) != procs) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 100000; i++) {
|
||||
+ int tmp;
|
||||
+ ihk_mc_write_lock(&lock);
|
||||
+ counter++;
|
||||
+ ihk_mc_write_unlock(&lock);
|
||||
+ ihk_mc_read_lock(&lock);
|
||||
+ tmp = counter;
|
||||
+ ihk_mc_read_unlock(&lock);
|
||||
+ if (tmp >= 100000 * procs) {
|
||||
+ kprintf("rwlock_test 3 break OK\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ ihk_atomic_dec(&barrier);
|
||||
+ while (ihk_atomic_read(&barrier) != 0) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ if (bsp) {
|
||||
+ if (counter == 100000 * procs) {
|
||||
+ kprintf("rwlock_test 3 OK\n");
|
||||
+ }
|
||||
+ else {
|
||||
+ kprintf("rwlock_test 3 NG %d != %d\n",
|
||||
+ ihk_atomic_read(&barrier),
|
||||
+ 100000 * procs);
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case 4:
|
||||
+ bsp = ihk_atomic_inc_return(&barrier) == 1;
|
||||
+ if (bsp) {
|
||||
+ kprintf("rwlock_test 4 start\n");
|
||||
+ counter = 0;
|
||||
+ }
|
||||
+ while (ihk_atomic_read(&barrier) != procs) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 100000; i++) {
|
||||
+ int brk = 0;
|
||||
+
|
||||
+ for (;;) {
|
||||
+ int tmp;
|
||||
+
|
||||
+ if (ihk_mc_write_trylock(&lock)) {
|
||||
+ counter++;
|
||||
+ ihk_mc_write_unlock(&lock);
|
||||
+ brk = 1;
|
||||
+ }
|
||||
+ if (ihk_mc_read_trylock(&lock)) {
|
||||
+ tmp = counter;
|
||||
+ ihk_mc_read_unlock(&lock);
|
||||
+ if (tmp >= 100000 * procs) {
|
||||
+ kprintf("rwlock_test 4 break OK\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (brk) {
|
||||
+ break;
|
||||
+ }
|
||||
+ while (!ihk_mc_write_can_lock(&lock) &&
|
||||
+ !ihk_mc_read_can_lock(&lock)) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ ihk_atomic_dec(&barrier);
|
||||
+ while (ihk_atomic_read(&barrier) != 0) {
|
||||
+ cpu_pause();
|
||||
+ }
|
||||
+
|
||||
+ if (bsp) {
|
||||
+ if (counter == 100000 * procs) {
|
||||
+ kprintf("rwlock_test 4 OK\n");
|
||||
+ }
|
||||
+ else {
|
||||
+ kprintf("rwlock_test 4 NG %d != %d\n",
|
||||
+ ihk_atomic_read(&barrier),
|
||||
+ 100000 * procs);
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case 10:
|
||||
+ return counter;
|
||||
+
|
||||
+ case 11:
|
||||
+ return ihk_atomic_read(&barrier);
|
||||
+
|
||||
+ case 12:
|
||||
+ memcpy(&retval, &lock, sizeof(struct ihk_rwlock));
|
||||
+ if (sizeof(struct ihk_rwlock) == 8) {
|
||||
+ return retval.rclong;
|
||||
+ }
|
||||
+ return retval.rcint;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void
|
||||
reset_cputime()
|
||||
{
|
||||
12
test/issues/1323/rwlock.sh
Normal file
12
test/issues/1323/rwlock.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
USELTP=0
|
||||
USEOSTEST=0
|
||||
BOOTPARAM="-c 2-7,9-15 -m 1G@0"
|
||||
|
||||
. ../../common.sh
|
||||
|
||||
################################################################################
|
||||
$MCEXEC ./rwlock 1 10
|
||||
$MCEXEC ./rwlock 2 10
|
||||
$MCEXEC ./rwlock 3 10
|
||||
$MCEXEC ./rwlock 4 10
|
||||
14
test/issues/1323/rwlock.txt
Normal file
14
test/issues/1323/rwlock.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Script started on Wed Jul 24 10:55:01 2019
|
||||
bash-4.2$ make test
|
||||
gcc -g -Wall -o rwlock rwlock.c -lpthread
|
||||
sh ./rwlock.sh
|
||||
mcstop+release.sh ... done
|
||||
mcreboot.sh -c 2-7,9-15 -m 1G@0 ... done
|
||||
rwlock test 1 PASS
|
||||
rwlock test 2 PASS
|
||||
rwlock test 3 PASS
|
||||
rwlock test 4 PASS
|
||||
bash-4.2$ exit
|
||||
exit
|
||||
|
||||
Script done on Wed Jul 24 10:55:20 2019
|
||||
Reference in New Issue
Block a user