| 1 | |
| 2 | |
| 3 | * Copyright 2015, Cyril Bur, IBM Corp.
|
| 4 | *
|
| 5 | * This test attempts to see if the FPU registers change across a syscall (fork).
|
| 6 |
|
| 7 |
|
| 8 | #include <stdio.h>
|
| 9 | #include <unistd.h>
|
| 10 | #include <sys/syscall.h>
|
| 11 | #include <sys/time.h>
|
| 12 | #include <sys/types.h>
|
| 13 | #include <sys/wait.h>
|
| 14 | #include <stdlib.h>
|
| 15 |
|
| 16 | #include "utils.h"
|
| 17 | #include "fpu.h"
|
| 18 |
|
| 19 | extern int test_fpu(double *darray, pid_t *pid);
|
| 20 |
|
| 21 | double darray[32];
|
| 22 |
|
| 23 | int syscall_fpu(void)
|
| 24 | {
|
| 25 | pid_t fork_pid;
|
| 26 | int i;
|
| 27 | int ret;
|
| 28 | int child_ret;
|
| 29 |
|
| 30 | randomise_darray(darray, ARRAY_SIZE(darray));
|
| 31 |
|
| 32 | for (i = 0; i < 1000; i++) {
|
| 33 |
|
| 34 | ret = test_fpu(darray, &fork_pid);
|
| 35 | if (fork_pid == -1)
|
| 36 | return -1;
|
| 37 | if (fork_pid == 0)
|
| 38 | exit(ret);
|
| 39 | waitpid(fork_pid, &child_ret, 0);
|
| 40 | if (ret || child_ret)
|
| 41 | return 1;
|
| 42 | }
|
| 43 |
|
| 44 | return 0;
|
| 45 | }
|
| 46 |
|
| 47 | int test_syscall_fpu(void)
|
| 48 | {
|
| 49 | |
| 50 | * Setup an environment with much context switching
|
| 51 |
|
| 52 | pid_t pid2;
|
| 53 | pid_t pid = fork();
|
| 54 | int ret;
|
| 55 | int child_ret;
|
| 56 | FAIL_IF(pid == -1);
|
| 57 |
|
| 58 | pid2 = fork();
|
| 59 |
|
| 60 | if (pid2 == -1) {
|
| 61 | |
| 62 | * Couldn't fork, ensure test is a fail
|
| 63 |
|
| 64 | child_ret = ret = 1;
|
| 65 | } else {
|
| 66 | ret = syscall_fpu();
|
| 67 | if (pid2)
|
| 68 | waitpid(pid2, &child_ret, 0);
|
| 69 | else
|
| 70 | exit(ret);
|
| 71 | }
|
| 72 |
|
| 73 | ret |= child_ret;
|
| 74 |
|
| 75 | if (pid)
|
| 76 | waitpid(pid, &child_ret, 0);
|
| 77 | else
|
| 78 | exit(ret);
|
| 79 |
|
| 80 | FAIL_IF(ret || child_ret);
|
| 81 | return 0;
|
| 82 | }
|
| 83 |
|
| 84 | int main(int argc, char *argv[])
|
| 85 | {
|
| 86 | return test_harness(test_syscall_fpu, "syscall_fpu");
|
| 87 |
|
| 88 | }
|