0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "dscr.h"
0013
0014 static unsigned long dscr;
0015 static unsigned long sequence;
0016 static unsigned long result[THREADS];
0017
0018 static void *do_test(void *in)
0019 {
0020 unsigned long thread = (unsigned long)in;
0021 unsigned long i;
0022
0023 for (i = 0; i < COUNT; i++) {
0024 unsigned long d, cur_dscr, cur_dscr_usr;
0025 unsigned long s1, s2;
0026
0027 s1 = READ_ONCE(sequence);
0028 if (s1 & 1)
0029 continue;
0030 rmb();
0031
0032 d = dscr;
0033 cur_dscr = get_dscr();
0034 cur_dscr_usr = get_dscr_usr();
0035
0036 rmb();
0037 s2 = sequence;
0038
0039 if (s1 != s2)
0040 continue;
0041
0042 if (cur_dscr != d) {
0043 fprintf(stderr, "thread %ld kernel DSCR should be %ld "
0044 "but is %ld\n", thread, d, cur_dscr);
0045 result[thread] = 1;
0046 pthread_exit(&result[thread]);
0047 }
0048
0049 if (cur_dscr_usr != d) {
0050 fprintf(stderr, "thread %ld user DSCR should be %ld "
0051 "but is %ld\n", thread, d, cur_dscr_usr);
0052 result[thread] = 1;
0053 pthread_exit(&result[thread]);
0054 }
0055 }
0056 result[thread] = 0;
0057 pthread_exit(&result[thread]);
0058 }
0059
0060 int dscr_default(void)
0061 {
0062 pthread_t threads[THREADS];
0063 unsigned long i, *status[THREADS];
0064 unsigned long orig_dscr_default;
0065
0066 SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
0067
0068 orig_dscr_default = get_default_dscr();
0069
0070
0071 dscr = 1;
0072 set_default_dscr(dscr);
0073
0074
0075 for (i = 0; i < THREADS; i++) {
0076 if (pthread_create(&threads[i], NULL, do_test, (void *)i)) {
0077 perror("pthread_create() failed");
0078 goto fail;
0079 }
0080 }
0081
0082 srand(getpid());
0083
0084
0085 for (i = 0; i < COUNT; i++) {
0086 double ret = uniform_deviate(rand());
0087
0088 if (ret < 0.0001) {
0089 sequence++;
0090 wmb();
0091
0092 dscr++;
0093 if (dscr > DSCR_MAX)
0094 dscr = 0;
0095
0096 set_default_dscr(dscr);
0097
0098 wmb();
0099 sequence++;
0100 }
0101 }
0102
0103
0104 for (i = 0; i < THREADS; i++) {
0105 if (pthread_join(threads[i], (void **)&(status[i]))) {
0106 perror("pthread_join() failed");
0107 goto fail;
0108 }
0109
0110 if (*status[i]) {
0111 printf("%ldth thread failed to join with %ld status\n",
0112 i, *status[i]);
0113 goto fail;
0114 }
0115 }
0116 set_default_dscr(orig_dscr_default);
0117 return 0;
0118 fail:
0119 set_default_dscr(orig_dscr_default);
0120 return 1;
0121 }
0122
0123 int main(int argc, char *argv[])
0124 {
0125 return test_harness(dscr_default, "dscr_default_test");
0126 }