Files
mckernel/test/issues/1323/rwlock.patch
Tomoki Shirasawa 258156b57e support for read/write-lock and read/write-trylock
Change-Id: I609071c0f6234d0d413c8b312d8a8379abf6846e
Refs: #1323
2019-08-08 00:38:55 +00:00

240 lines
5.0 KiB
Diff

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()
{