diff --git a/test/uti/arm64/CT12.c b/test/uti/arm64/CT12.c new file mode 100644 index 00000000..d4842fc5 --- /dev/null +++ b/test/uti/arm64/CT12.c @@ -0,0 +1,90 @@ +/* CT12.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uti.h" + +int passed = 0, sem = 0; +pthread_t thr; + +void *util_thread(void *arg) +{ + int rc; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, + "CT12100 running on Linux CPU OK\n"); + } + else { + fprintf(stderr, + "CT12100 running on Linux CPU NG (%d)\n", + rc); + } + passed = 1; + + rc = syscall(__NR_futex, &sem, + FUTEX_WAIT, 0, NULL, NULL, 0); + if (rc != 0) { + fprintf(stderr, + "CT12101 FUTEX_WAIT NG (%s)\n", + strerror(errno)); + } + else { + fprintf(stderr, + "CT12101 FUTEX_WAIT OK\n"); + } + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + fprintf(stderr, "CT12001 futex START\n"); + + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "util_indicate_clone rc=%d, errno=%d\n", + rc, errno); + fflush(stderr); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT12002 pthread_create OK\n"); + + while (!passed) { + cpu_pause(); + } + usleep(100000); + + rc = syscall(__NR_futex, &sem, + FUTEX_WAKE, 1, NULL, NULL, 0); + if (rc != 1) { + fprintf(stderr, + "CT12003 FUTEX_WAKE NG (%d,%s)\n", + rc, strerror(errno)); + } + else { + fprintf(stderr, "CT12003 FUTEX_WAKE OK\n"); + } + + pthread_join(thr, NULL); + fprintf(stderr, "CT12004 pthread_join OK\n"); + + fprintf(stderr, "CT12005 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT13.c b/test/uti/arm64/CT13.c new file mode 100644 index 00000000..8e12c0f5 --- /dev/null +++ b/test/uti/arm64/CT13.c @@ -0,0 +1,91 @@ +/* CT13.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include /* For SYS_xxx definitions */ +#include +#include +#include "uti.h" + +int passed = 0, sem = 0; +pthread_t thr; + +void *util_thread(void *arg) +{ + int rc; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, + "CT13100 running on Linux CPU OK\n"); + } + else { + fprintf(stderr, + "CT13100 running on Linux CPU NG (%d)\n", + rc); + } + + while (!passed) { + cpu_pause(); + } + + /* debug messages via serial takes 0.05 sec */ + usleep(100000); + + rc = syscall(__NR_futex, &sem, + FUTEX_WAKE, 1, NULL, NULL, 0); + if (rc != 1) { + fprintf(stderr, + "CT13101 FUTEX_WAKE NG (%d,%s)\n", + rc, strerror(errno)); + } + else { + fprintf(stderr, "CT13101 FUTEX_WAKE OK\n"); + } + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + fprintf(stderr, "CT13001 futex START\n"); + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "util_indicate_clone rc=%d, errno=%d\n", + rc, errno); + fflush(stderr); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT13002 pthread_create OK\n"); + + passed = 1; + + rc = syscall(__NR_futex, &sem, + FUTEX_WAIT, 0, NULL, NULL, 0); + if (rc != 0) { + fprintf(stderr, + "CT13003 FUTEX_WAIT NG (%s)\n", + strerror(errno)); + } + else { + fprintf(stderr, "CT13003 FUTEX_WAIT OK\n"); + } + + pthread_join(thr, NULL); + fprintf(stderr, "CT13004 pthread_join OK\n"); + + fprintf(stderr, "CT13005 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT14.c b/test/uti/arm64/CT14.c new file mode 100644 index 00000000..d68537bf --- /dev/null +++ b/test/uti/arm64/CT14.c @@ -0,0 +1,137 @@ +/* CT14.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uti.h" + +pthread_mutex_t mutex; +int owned; +pthread_t thr; + +#define TS2NS(sec, nsec) \ + ((unsigned long)(sec) * 1000000000ULL + \ + (unsigned long)(nsec)) + +static inline void BULK_FSW(unsigned long n, + unsigned long *ptr) +{ + int j; + + for (j = 0; j < (n); j++) { + FIXED_SIZE_WORK(ptr); + } +} + +/* nsec per work */ +double nspw; + +#define N_INIT 10000000 + +void fwq_init(unsigned long *mem) +{ + struct timespec start, end; + unsigned long nsec; + + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + BULK_FSW(N_INIT, mem); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + nsec = (TS2NS(end.tv_sec, end.tv_nsec) - + TS2NS(start.tv_sec, start.tv_nsec)); + nspw = nsec / (double)N_INIT; + printf("nsec=%ld, nspw=%f\n", nsec, nspw); +} + +void fwq(unsigned long delay_nsec, unsigned long *mem) +{ + //printf("delay_nsec=%ld,count=%f\n", + // delay_nsec, delay_nsec / nspw); + BULK_FSW(delay_nsec / nspw, mem); +} + +void *util_thread(void *arg) +{ + int rc; + unsigned long mem; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, + "CT14100 running on Linux OK\n"); + } + else { + fprintf(stderr, + "CT14100 running on Linux NG (%d)\n", rc); + } + errno = 0; + + /* Sending debug messages through serial takes 0.05 sec */ + fwq(500 * 1000 * 1000UL, &mem); + + pthread_mutex_lock(&mutex); + if (owned) { + fprintf(stderr, "CT14101 lock second OK\n"); + } + else { + fprintf(stderr, "CT14101 lock second NG\n"); + } + owned = 1; + pthread_mutex_unlock(&mutex); + + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + unsigned long mem; + + pthread_mutex_init(&mutex, NULL); + fwq_init(&mem); + + fprintf(stderr, "CT14001 futex START\n"); + + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "CT14002 util_indicate_clone NG (rc=%d, errno=%d)\n", + rc, errno); + fflush(stderr); + } + else { + fprintf(stderr, "CT14002 util_indicate_clone OK\n"); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT14003 pthread_create OK\n"); + + pthread_mutex_lock(&mutex); + if (!owned) { + fprintf(stderr, "CT14004 lock first OK\n"); + } + else { + fprintf(stderr, "CT14004 lock first NG\n"); + } + owned = 1; + + /* Need 2 sec to make child sleep */ + fwq(2000 * 1000 * 1000UL, &mem); + pthread_mutex_unlock(&mutex); + + pthread_join(thr, NULL); + fprintf(stderr, "CT14005 pthread_join OK\n"); + + fprintf(stderr, "CT14006 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT15.c b/test/uti/arm64/CT15.c new file mode 100644 index 00000000..87a3dcd9 --- /dev/null +++ b/test/uti/arm64/CT15.c @@ -0,0 +1,133 @@ +/* CT15.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uti.h" + +pthread_mutex_t mutex; +int owned; +pthread_t thr; + +#define TS2NS(sec, nsec) \ + ((unsigned long)(sec) * 1000000000ULL + \ + (unsigned long)(nsec)) + +static inline void BULK_FSW(unsigned long n, unsigned long *ptr) +{ + int j; + + for (j = 0; j < (n); j++) { + FIXED_SIZE_WORK(ptr); + } +} + +double nspw; /* nsec per work */ + +#define N_INIT 10000000 + +void fwq_init(unsigned long *mem) +{ + struct timespec start, end; + unsigned long nsec; + + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + BULK_FSW(N_INIT, mem); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + nsec = (TS2NS(end.tv_sec, end.tv_nsec) - + TS2NS(start.tv_sec, start.tv_nsec)); + nspw = nsec / (double)N_INIT; + printf("nsec=%ld, nspw=%f\n", nsec, nspw); +} + +void fwq(unsigned long delay_nsec, unsigned long *mem) +{ + //printf("delay_nsec=%ld,count=%f\n", + // delay_nsec, delay_nsec / nspw); + BULK_FSW(delay_nsec / nspw, mem); +} + +void *util_thread(void *arg) +{ + int rc; + unsigned long mem; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, + "CT15100 running on Linux OK\n"); + } + else { + fprintf(stderr, + "CT15100 running on Linux NG (%d)\n", rc); + } + errno = 0; + + pthread_mutex_lock(&mutex); + if (!owned) { + fprintf(stderr, "CT15101 lock first OK\n"); + } else { + fprintf(stderr, "CT15101 lock first NG\n"); + } + owned = 1; + + /* Need 2 sec to make parent sleep */ + fwq(2000 * 1000 * 1000UL, &mem); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + unsigned long mem; + + pthread_mutex_init(&mutex, NULL); + fwq_init(&mem); + + fprintf(stderr, "CT15001 futex START\n"); + + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "CT15002 util_indicate_clone NG (rc=%d, errno=%d)\n", + rc, errno); + fflush(stderr); + } + else { + fprintf(stderr, "CT15002 util_indicate_clone OK\n"); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT15003 pthread_create OK\n"); + + /* Sending debug messages through serial takes 0.05 sec */ + fwq(500 * 1000 * 1000UL, &mem); + + pthread_mutex_lock(&mutex); + if (owned) { + fprintf(stderr, "CT15004 lock second OK\n"); + } else { + fprintf(stderr, "CT15004 lock second NG\n"); + } + owned = 1; + pthread_mutex_unlock(&mutex); + + pthread_join(thr, NULL); + fprintf(stderr, "CT15005 pthread_join OK\n"); + + fprintf(stderr, "CT15006 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT16.c b/test/uti/arm64/CT16.c new file mode 100644 index 00000000..3789deb2 --- /dev/null +++ b/test/uti/arm64/CT16.c @@ -0,0 +1,93 @@ +/* CT16.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uti.h" + +pthread_mutex_t mutex; +pthread_cond_t cond; +int passed, flag; +pthread_t thr; + +void *util_thread(void *arg) +{ + int rc; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, + "CT16101 running on Linux OK\n"); + } + else { + fprintf(stderr, + "CT16101 running on Linux NG (%d)\n", rc); + } + errno = 0; + + passed = 1; + pthread_mutex_lock(&mutex); + while (!flag) { + pthread_cond_wait(&cond, &mutex); + } + flag = 0; + pthread_mutex_unlock(&mutex); + + fprintf(stderr, + "CT16102 return from pthread_cond_wait() OK\n"); + + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + + fprintf(stderr, "CT16001 futex START\n"); + + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "CT16002 util_indicate_clone NG (rc=%d, errno=%d)\n", + rc, errno); + fflush(stderr); + } + else { + fprintf(stderr, "CT16002 util_indicate_clone OK\n"); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT16003 pthread_create OK\n"); + + while (!passed) { + cpu_pause(); + } + + /* Send debug message through serial takes 0.05 sec */ + usleep(100 * 1000UL); + + pthread_mutex_lock(&mutex); + flag = 1; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + pthread_join(thr, NULL); + fprintf(stderr, "CT16004 pthread_join OK\n"); + + fprintf(stderr, "CT16005 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT17.c b/test/uti/arm64/CT17.c new file mode 100644 index 00000000..f5c368f4 --- /dev/null +++ b/test/uti/arm64/CT17.c @@ -0,0 +1,92 @@ +/* CT17.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uti.h" + +pthread_mutex_t mutex; +pthread_cond_t cond; +int passed, flag; +pthread_t thr; + +void *util_thread(void *arg) +{ + int rc; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, + "CT17100 running on Linux OK\n"); + } + else { + fprintf(stderr, + "CT17100 running on Linux NG (%d)\n", rc); + } + + while (!passed) { + cpu_pause(); + } + + /* Send debug message through serial takes 0.05 sec */ + usleep(100 * 1000UL); + + pthread_mutex_lock(&mutex); + flag = 1; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + + fprintf(stderr, "CT17001 futex START\n"); + + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "CT17002 util_indicate_clone NG (rc=%d, errno=%d)\n", + rc, errno); + fflush(stderr); + } + else { + fprintf(stderr, "CT17002 util_indicate_clone OK\n"); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT17003 pthread_create OK\n"); + + passed = 1; + pthread_mutex_lock(&mutex); + fprintf(stderr, "CT17004 lock on %p OK\n", &mutex); + while (!flag) { + pthread_cond_wait(&cond, &mutex); + fprintf(stderr, "CT17005 wake on %p OK\n", &cond); + } + flag = 0; + + pthread_mutex_unlock(&mutex); + + pthread_join(thr, NULL); + fprintf(stderr, "CT17006 pthread_join OK\n"); + + fprintf(stderr, "CT17007 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT18.c b/test/uti/arm64/CT18.c new file mode 100644 index 00000000..7147f365 --- /dev/null +++ b/test/uti/arm64/CT18.c @@ -0,0 +1,127 @@ +/* CT18.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For SYS_xxx definitions */ +#include +#include +#include +#include "uti.h" + +int passed, sem, flag; +pthread_t thr; +#define TS2NS(sec, nsec) \ + ((unsigned long)(sec) * 1000000000ULL + \ + (unsigned long)(nsec)) + +void *util_thread(void *arg) +{ + int rc; + struct timespec start, timeout, end; + unsigned long elapsed; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, "CT18101 running on Linux CPU OK\n"); + } + else { + fprintf(stderr, "CT18101 running on Linux CPU NG (%d)\n", rc); + } + + passed = 1; + + rc = clock_gettime(CLOCK_REALTIME, &start); + if (rc != 0) { + fprintf(stderr, "clock_gettime failed\n"); + return NULL; + } + fprintf(stderr, "start=%ld.%09ld\n", start.tv_sec, start.tv_nsec); + + timeout.tv_sec = start.tv_sec; + timeout.tv_nsec = start.tv_nsec + 800UL * 1000 * 1000; + if (timeout.tv_nsec > 1000UL * 1000 * 1000) { + timeout.tv_sec += 1; + timeout.tv_nsec -= 1000UL * 1000 * 1000; + } + rc = syscall(__NR_futex, &sem, + FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, + 0, &timeout, NULL, 0x12345678); + fprintf(stderr, "op=%x\n", FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME); + + rc = clock_gettime(CLOCK_REALTIME, &end); + if (rc != 0) { + fprintf(stderr, "clock_gettime failed\n"); + return NULL; + } + fprintf(stderr, "end=%ld.%09ld\n", end.tv_sec, end.tv_nsec); + + if (rc != 0) { + fprintf(stderr, "CT18102 FUTEX_WAIT NG (%s)\n", + strerror(errno)); + } + else { + fprintf(stderr, "CT18102 FUTEX_WAIT OK\n"); + } + + elapsed = TS2NS(end.tv_sec, end.tv_nsec) - + TS2NS(start.tv_sec, start.tv_nsec); + if (flag == 0 || elapsed < 800UL * 1000 * 1000 + 80UL * 1000 * 1000) { + fprintf(stderr, "CT18103 timeout OK\n"); + } + else { + fprintf(stderr, "CT18103 timeout NG (%lx)\n", elapsed); + } + + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + fprintf(stderr, "CT18001 futex START\n"); + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, "util_indicate_clone rc=%d, errno=%d\n", + rc, errno); + fflush(stderr); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT18002 pthread_create OK\n"); + + while (!passed) { + cpu_pause(); + } + usleep(800 * 1000UL * 10); + + flag = 1; + rc = syscall(__NR_futex, &sem, + FUTEX_WAKE_BITSET, 1, NULL, NULL, 0x12345678); + if (rc != 0) { + fprintf(stderr, + "CT18003 FUTEX_WAKE missing the waiter NG (%d,%s)\n", + rc, strerror(errno)); + } + else { + fprintf(stderr, "CT18003 FUTEX_WAKE missing the waiter OK\n"); + } + + pthread_join(thr, NULL); + fprintf(stderr, "CT18004 pthread_join OK\n"); + + fprintf(stderr, "CT18005 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT19.c b/test/uti/arm64/CT19.c new file mode 100644 index 00000000..ee98640f --- /dev/null +++ b/test/uti/arm64/CT19.c @@ -0,0 +1,129 @@ +/* CT19.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For SYS_xxx definitions */ +#include +#include +#include +#include "uti.h" + +int passed, sem, flag; +pthread_t thr; +#define TS2NS(sec, nsec) \ + ((unsigned long)(sec) * 1000000000ULL + \ + (unsigned long)(nsec)) + +void *util_thread(void *arg) +{ + int rc; + struct timespec start, timeout, end; + unsigned long elapsed; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, "CT19100 running on Linux CPU OK\n"); + } + else { + fprintf(stderr, "CT19100 running on Linux CPU NG (%d)\n", rc); + } + + passed = 1; + + rc = clock_gettime(CLOCK_MONOTONIC, &start); + if (rc != 0) { + fprintf(stderr, "clock_gettime failed\n"); + return NULL; + } + fprintf(stderr, "start=%ld.%09ld\n", start.tv_sec, start.tv_nsec); + + timeout.tv_sec = start.tv_sec; + timeout.tv_nsec = start.tv_nsec + 800UL * 1000 * 1000; + if (timeout.tv_nsec > 1000UL * 1000 * 1000) { + timeout.tv_sec += 1; + timeout.tv_nsec -= 1000UL * 1000 * 1000; + } + /* timeout - clock_gettime(CLOCK_MONOTONIC) */ + rc = syscall(__NR_futex, &sem, FUTEX_WAIT_BITSET, + 0, &timeout, NULL, 0x12345678); + fprintf(stderr, "op=%x\n", FUTEX_WAIT_BITSET); + + rc = clock_gettime(CLOCK_MONOTONIC, &end); + if (rc != 0) { + fprintf(stderr, "clock_gettime failed\n"); + return NULL; + } + fprintf(stderr, "end=%ld.%09ld\n", end.tv_sec, end.tv_nsec); + + if (rc != 0) { + fprintf(stderr, "CT19101 FUTEX_WAIT NG (%s)\n", + strerror(errno)); + } + else { + fprintf(stderr, "CT19101 FUTEX_WAIT OK\n"); + } + + elapsed = TS2NS(end.tv_sec, end.tv_nsec) - + TS2NS(start.tv_sec, start.tv_nsec); + if (flag == 0 || elapsed < 800UL * 1000 * 1000 + + 80UL * 1000 * 1000) { + fprintf(stderr, "CT19102 timeout OK\n"); + } + else { + fprintf(stderr, "CT19101 timeout NG\n"); + } + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + fprintf(stderr, "CT19001 futex START\n"); + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "util_indicate_clone rc=%d, errno=%d\n", + rc, errno); + fflush(stderr); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT19002 pthread_create OK\n"); + + while (!passed) { + cpu_pause(); + } + usleep(2000 * 1000UL); + + flag = 1; + rc = syscall(__NR_futex, &sem, FUTEX_WAKE_BITSET, + 1, NULL, NULL, 0x12345678); + if (rc != 0) { + fprintf(stderr, + "CT19003 FUTEX_WAKE missing the waiter NG (%d,%s)\n", + rc, strerror(errno)); + } + else { + fprintf(stderr, + "CT19003 FUTEX_WAKE missing the waiter OK\n"); + } + + pthread_join(thr, NULL); + fprintf(stderr, "CT19004 pthread_join OK\n"); + + fprintf(stderr, "CT19005 END\n"); + exit(0); +} diff --git a/test/uti/arm64/CT20.c b/test/uti/arm64/CT20.c new file mode 100644 index 00000000..e7db2b42 --- /dev/null +++ b/test/uti/arm64/CT20.c @@ -0,0 +1,121 @@ +/* CT20.c COPYRIGHT FUJITSU LIMITED 2019 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For SYS_xxx definitions */ +#include +#include +#include +#include "uti.h" + +int passed, sem, flag; +pthread_t thr; +#define TS2NS(sec, nsec) \ + ((unsigned long)(sec) * 1000000000ULL + \ + (unsigned long)(nsec)) + +void *util_thread(void *arg) +{ + int rc; + struct timespec start, timeout, end; + unsigned long elapsed; + + rc = syscall(__NR_get_system); + if (rc == -1) { + fprintf(stderr, "CT20100 running on Linux CPU OK\n"); + } + else { + fprintf(stderr, "CT20100 running on Linux CPU NG (%d)\n", rc); + } + + passed = 1; + + rc = clock_gettime(CLOCK_REALTIME, &start); + if (rc != 0) { + fprintf(stderr, "clock_gettime failed\n"); + return NULL; + } + fprintf(stderr, "start=%ld.%09ld\n", start.tv_sec, start.tv_nsec); + + timeout.tv_sec = 0; + timeout.tv_nsec = 800ULL * 1000 * 1000; + rc = syscall(__NR_futex, &sem, FUTEX_WAIT, 0, &timeout, NULL, 0); + + rc = clock_gettime(CLOCK_REALTIME, &end); + if (rc != 0) { + fprintf(stderr, "clock_gettime failed\n"); + return NULL; + } + fprintf(stderr, "end=%ld.%09ld\n", end.tv_sec, end.tv_nsec); + + if (rc != 0) { + fprintf(stderr, "CT20101 FUTEX_WAIT NG (%s)\n", + strerror(errno)); + } + else { + fprintf(stderr, "CT20101 FUTEX_WAIT OK\n"); + } + + elapsed = TS2NS(end.tv_sec, end.tv_nsec) - + TS2NS(start.tv_sec, start.tv_nsec); + if (flag == 0 || elapsed < 800UL * 1000 * 1000 + + 80UL * 1000 * 1000) { + fprintf(stderr, "CT20102 timeout OK\n"); + } + else { + fprintf(stderr, "CT20101 timeout NG\n"); + } + return NULL; +} + +int main(int argc, char **argv) +{ + int rc; + + fprintf(stderr, "CT20001 futex START\n"); + rc = syscall(__NR_util_indicate_clone, + SPAWN_TO_REMOTE, NULL); + if (rc) { + fprintf(stderr, + "util_indicate_clone rc=%d, errno=%d\n", + rc, errno); + fflush(stderr); + } + + rc = pthread_create(&thr, NULL, util_thread, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "CT20002 pthread_create OK\n"); + + while (!passed) { + cpu_pause(); + } + usleep(2000 * 1000UL); + + flag = 1; + rc = syscall(__NR_futex, &sem, FUTEX_WAKE, 1, NULL, NULL, 0); + if (rc != 0) { + fprintf(stderr, + "CT20003 FUTEX_WAKE missing the waiter NG (%d,%s)\n", + rc, strerror(errno)); + } + else { + fprintf(stderr, + "CT20003 FUTEX_WAKE missing the waiter OK\n"); + } + + pthread_join(thr, NULL); + fprintf(stderr, "CT20004 pthread_join OK\n"); + + fprintf(stderr, "CT20005 END\n"); + exit(0); +} diff --git a/test/uti/arm64/README b/test/uti/arm64/README new file mode 100644 index 00000000..29538e56 --- /dev/null +++ b/test/uti/arm64/README @@ -0,0 +1,64 @@ +/* README COPYRIGHT FUJITSU LIMITED 2019 */ + +arm64版UTIテストセットREADME + +(1) テストの実行方法 + 事前準備 + 1. arm64版syscall_interceptライブラリを用意する + https://github.com/RIKEN-SysSoft/syscall_intercept.git + + 2. McKernelはENABLE_UTI=ONでビルドしたものを用意する + + 以下の手順でテストを実行する + 1. $HOME/.mck_test_configを用意する + 当該ファイルは、McKernelをビルドした際に生成されるmck_test_config.sample + ファイルを$HOMEにコピーし、適宜編集する + + 2. 必要に応じて、LD_LIBRARY_PATH環境変数を設定する + + 3. make testを実行する + +(2) テスト項目詳細 + CT12-CT20 + test/uti/READMEを参照のこと + +(3) 実行結果ログ + result.logファイル内に実行時のログを記載する + 実行に利用したIHK/McKernelは、以下のものである + + IHK + https://github.com/RIKEN-SysSoft/ihk.git + tag: fj_test_201902 + + commit f4c2dbbb0f1ba87b2b6b33a1e683c313bd2006fa + Author: Dominique Martinet + Date: Thu Feb 7 14:02:00 2019 +0900 + + 上記に加えて、以下の修正を取り込む + https://review.gerrithub.io/c/RIKEN-SysSoft/ihk/+/447014 + https://review.gerrithub.io/c/RIKEN-SysSoft/ihk/+/446206 + + McKernel + https://github.com/RIKEN-SysSoft/mckernel.git + tag: fj_test_201902 + + commit 21cf953a03d54e6ca01a39f52637d79134ad4e0e + Author: Dominique Martinet + Date: Wed Feb 6 16:55:14 2019 +0900 + + 上記に加えて、以下の修正を取り込む + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/446205 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/447017 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/447015 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/446581 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/446583 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/446584 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/446797 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/445448 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/442533 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/442534 + https://review.gerrithub.io/c/RIKEN-SysSoft/mckernel/+/447439 + patch/futex_wait_on_Linux_use_global_struct.patch + + +以上。 diff --git a/test/uti/arm64/patch/futex_wait_on_Linux_use_global_struct.patch b/test/uti/arm64/patch/futex_wait_on_Linux_use_global_struct.patch new file mode 100644 index 00000000..b7046225 --- /dev/null +++ b/test/uti/arm64/patch/futex_wait_on_Linux_use_global_struct.patch @@ -0,0 +1,79 @@ +## futex_wait_on_Linux_use_global_struct.patch COPYRIGHT FUJITSU LIMITED 2019 ## +diff --git a/kernel/futex.c b/kernel/futex.c +index 6a7eb1f..4534100 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -820,18 +820,27 @@ static int futex_wait_setup(uint32_t __user *uaddr, uint32_t val, int fshared, + return ret; + } + ++struct futex_q gq; + static int futex_wait(uint32_t __user *uaddr, int fshared, + uint32_t val, uint64_t timeout, uint32_t bitset, int clockrt, + struct cpu_local_var *clv_override) + { + struct futex_hash_bucket *hb; +- struct futex_q q; + int64_t time_remain; ++ struct futex_q lq; ++ struct futex_q *q = NULL; + int ret; + + if (!bitset) + return -EINVAL; + ++ if (!clv_override) { ++ q = &lq; ++ } ++ else { ++ q = &gq; ++ } ++ + #ifdef PROFILE_ENABLE + if (cpu_local_var_with_override(current, clv_override)->profile && + cpu_local_var_with_override(current, clv_override)->profile_start_ts) { +@@ -841,24 +850,24 @@ static int futex_wait(uint32_t __user *uaddr, int fshared, + } + #endif + +- q.bitset = bitset; +- q.requeue_pi_key = NULL; +- q.uti_futex_resp = cpu_local_var_with_override(uti_futex_resp, clv_override); ++ q->bitset = bitset; ++ q->requeue_pi_key = NULL; ++ q->uti_futex_resp = cpu_local_var_with_override(uti_futex_resp, clv_override); + + retry: + /* Prepare to wait on uaddr. */ +- ret = futex_wait_setup(uaddr, val, fshared, &q, &hb, clv_override); ++ ret = futex_wait_setup(uaddr, val, fshared, q, &hb, clv_override); + if (ret) { + uti_dkprintf("%s: tid=%d futex_wait_setup returns zero, no need to sleep\n", __FUNCTION__, cpu_local_var_with_override(current, clv_override)->tid); + goto out; + } + + /* queue_me and wait for wakeup, timeout, or a signal. */ +- time_remain = futex_wait_queue_me(hb, &q, timeout, clv_override); ++ time_remain = futex_wait_queue_me(hb, q, timeout, clv_override); + + /* If we were woken (and unqueued), we succeeded, whatever. */ + ret = 0; +- if (!unqueue_me(&q)) { ++ if (!unqueue_me(q)) { + uti_dkprintf("%s: tid=%d unqueued\n", __FUNCTION__, cpu_local_var_with_override(current, clv_override)->tid); + goto out_put_key; + } +@@ -878,11 +887,11 @@ retry: + } + + /* RIKEN: no signals */ +- put_futex_key(fshared, &q.key); ++ put_futex_key(fshared, &q->key); + goto retry; + + out_put_key: +- put_futex_key(fshared, &q.key); ++ put_futex_key(fshared, &q->key); + out: + #ifdef PROFILE_ENABLE + if (cpu_local_var_with_override(current, clv_override)->profile) { diff --git a/test/uti/arm64/result.log b/test/uti/arm64/result.log new file mode 100644 index 00000000..e66de03f --- /dev/null +++ b/test/uti/arm64/result.log @@ -0,0 +1,101 @@ +gcc -Wall -lpthread CT12.c -o CT12 +gcc -Wall -lpthread CT13.c -o CT13 +gcc -Wall -lpthread CT14.c -o CT14 +gcc -Wall -lpthread CT15.c -o CT15 +gcc -Wall -lpthread CT16.c -o CT16 +gcc -Wall -lpthread CT17.c -o CT17 +gcc -Wall -lpthread CT18.c -o CT18 +gcc -Wall -lpthread CT19.c -o CT19 +gcc -Wall -lpthread CT20.c -o CT20 +./run.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 512M@0 ... done +CT12001 futex START +CT12002 pthread_create OK +CT12100 running on Linux CPU OK +CT12003 FUTEX_WAKE OK +CT12101 FUTEX_WAIT OK +CT12004 pthread_join OK +CT12005 END +CT12: OK. +CT13001 futex START +CT13002 pthread_create OK +CT13100 running on Linux CPU OK +CT13003 FUTEX_WAIT OK +CT13101 FUTEX_WAKE OK +CT13004 pthread_join OK +CT13005 END +CT13: OK. +CT14001 futex START +CT14002 util_indicate_clone OK +CT14003 pthread_create OK +CT14004 lock first OK +CT14100 running on Linux OK +CT14101 lock second OK +CT14005 pthread_join OK +CT14006 END +nsec=475228464, nspw=47.522846 +CT14: OK. +CT15001 futex START +CT15002 util_indicate_clone OK +CT15003 pthread_create OK +CT15100 running on Linux OK +CT15101 lock first OK +CT15004 lock second OK +CT15005 pthread_join OK +CT15006 END +nsec=466067664, nspw=46.606766 +CT15: OK. +CT16001 futex START +CT16002 util_indicate_clone OK +CT16003 pthread_create OK +CT16101 running on Linux OK +CT16102 return from pthread_cond_wait() OK +CT16004 pthread_join OK +CT16005 END +CT16: OK. +CT17001 futex START +CT17002 util_indicate_clone OK +CT17003 pthread_create OK +CT17004 lock on 0x4200a8 OK +CT17100 running on Linux OK +CT17005 wake on 0x4200e0 OK +CT17006 pthread_join OK +CT17007 END +CT17: OK. +CT18001 futex START +CT18002 pthread_create OK +CT18101 running on Linux CPU OK +start=1552371255.811177536 +op=109 +end=1552371256.658158304 +CT18102 FUTEX_WAIT OK +CT18103 timeout OK +CT18003 FUTEX_WAKE missing the waiter OK +CT18004 pthread_join OK +CT18005 END +CT18: OK. +CT19001 futex START +CT19002 pthread_create OK +CT19100 running on Linux CPU OK +start=1363.826803456 +op=9 +end=1364.640704608 +CT19101 FUTEX_WAIT OK +CT19102 timeout OK +CT19003 FUTEX_WAKE missing the waiter OK +CT19004 pthread_join OK +CT19005 END +CT19: OK. +CT20001 futex START +CT20002 pthread_create OK +CT20100 running on Linux CPU OK +start=1552371275.945834096 +end=1552371276.817846064 +CT20101 FUTEX_WAIT OK +CT20102 timeout OK +CT20003 FUTEX_WAKE missing the waiter OK +CT20004 pthread_join OK +CT20005 END +CT20: OK. +mcstop+release.sh ... done diff --git a/test/uti/arm64/run.sh b/test/uti/arm64/run.sh new file mode 100755 index 00000000..f033c2e7 --- /dev/null +++ b/test/uti/arm64/run.sh @@ -0,0 +1,19 @@ +#!/bin/sh +## run.sh COPYRIGHT FUJITSU LIMITED 2019 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +for i in `seq 12 20` +do + ${MCEXEC} --enable-uti ./CT${i} + if [ $? == 0 ]; then + echo "CT${i}: OK." + else + echo "CT${i}: NG." + fi +done + +mcstop diff --git a/test/uti/arm64/uti.h b/test/uti/arm64/uti.h new file mode 100644 index 00000000..947aea0b --- /dev/null +++ b/test/uti/arm64/uti.h @@ -0,0 +1,28 @@ +/* uti.h COPYRIGHT FUJITSU LIMITED 2019 */ +#ifndef __UTIL_H_INCLUDED__ +#define __UTIL_H_INCLUDED__ + +#define __NR_util_migrate_inter_kernel 730 + +#define __NR_util_indicate_clone 731 +#define SPAWN_TO_LOCAL 0 +#define SPAWN_TO_REMOTE 1 + +#define __NR_get_system 732 + +static inline void cpu_pause(void) +{ + asm volatile("yield" ::: "memory"); +} + +static inline void FIXED_SIZE_WORK(unsigned long *ptr) +{ + asm volatile("mov %x0, x20\n" + "add x20, x20, #1\n" + "mov x20, %x0\n" + : "+rm" (*ptr) + : + : "x20", "cc", "memory"); +} + +#endif /* !__UTIL_H_INCLUDED__ */