0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <stdio.h>
0020 #include <unistd.h>
0021 #include <stdlib.h>
0022 #include <sys/time.h>
0023 #include <pthread.h>
0024 #include "../kselftest.h"
0025
0026
0027 pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
0028
0029 pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
0030
0031
0032 #define MAX_THREADS 128
0033 #define LISTSIZE 128
0034
0035 int done = 0;
0036
0037 struct timespec global_list[LISTSIZE];
0038 int listcount = 0;
0039
0040
0041 void checklist(struct timespec *list, int size)
0042 {
0043 int i, j;
0044 struct timespec *a, *b;
0045
0046
0047 for (i = 0; i < size-1; i++) {
0048 a = &list[i];
0049 b = &list[i+1];
0050
0051
0052 if ((b->tv_sec <= a->tv_sec) &&
0053 (b->tv_nsec < a->tv_nsec)) {
0054
0055
0056 done = 1;
0057
0058
0059 pthread_mutex_lock(&print_lock);
0060
0061
0062 printf("\n");
0063 for (j = 0; j < size; j++) {
0064 if (j == i)
0065 printf("---------------\n");
0066 printf("%lu:%lu\n", list[j].tv_sec, list[j].tv_nsec);
0067 if (j == i+1)
0068 printf("---------------\n");
0069 }
0070 printf("[FAILED]\n");
0071
0072 pthread_mutex_unlock(&print_lock);
0073 }
0074 }
0075 }
0076
0077
0078
0079
0080
0081 void *shared_thread(void *arg)
0082 {
0083 while (!done) {
0084
0085 pthread_mutex_lock(&list_lock);
0086
0087
0088 if (listcount >= LISTSIZE) {
0089 checklist(global_list, LISTSIZE);
0090 listcount = 0;
0091 }
0092 clock_gettime(CLOCK_MONOTONIC, &global_list[listcount++]);
0093
0094 pthread_mutex_unlock(&list_lock);
0095 }
0096 return NULL;
0097 }
0098
0099
0100
0101
0102
0103 void *independent_thread(void *arg)
0104 {
0105 struct timespec my_list[LISTSIZE];
0106 int count;
0107
0108 while (!done) {
0109
0110 for (count = 0; count < LISTSIZE; count++)
0111 clock_gettime(CLOCK_MONOTONIC, &my_list[count]);
0112 checklist(my_list, LISTSIZE);
0113 }
0114 return NULL;
0115 }
0116
0117 #define DEFAULT_THREAD_COUNT 8
0118 #define DEFAULT_RUNTIME 30
0119
0120 int main(int argc, char **argv)
0121 {
0122 int thread_count, i;
0123 time_t start, now, runtime;
0124 char buf[255];
0125 pthread_t pth[MAX_THREADS];
0126 int opt;
0127 void *tret;
0128 int ret = 0;
0129 void *(*thread)(void *) = shared_thread;
0130
0131 thread_count = DEFAULT_THREAD_COUNT;
0132 runtime = DEFAULT_RUNTIME;
0133
0134
0135 while ((opt = getopt(argc, argv, "t:n:i")) != -1) {
0136 switch (opt) {
0137 case 't':
0138 runtime = atoi(optarg);
0139 break;
0140 case 'n':
0141 thread_count = atoi(optarg);
0142 break;
0143 case 'i':
0144 thread = independent_thread;
0145 printf("using independent threads\n");
0146 break;
0147 default:
0148 printf("Usage: %s [-t <secs>] [-n <numthreads>] [-i]\n", argv[0]);
0149 printf(" -t: time to run\n");
0150 printf(" -n: number of threads\n");
0151 printf(" -i: use independent threads\n");
0152 return -1;
0153 }
0154 }
0155
0156 if (thread_count > MAX_THREADS)
0157 thread_count = MAX_THREADS;
0158
0159
0160 setbuf(stdout, NULL);
0161
0162 start = time(0);
0163 strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&start));
0164 printf("%s\n", buf);
0165 printf("Testing consistency with %i threads for %ld seconds: ", thread_count, runtime);
0166 fflush(stdout);
0167
0168
0169 for (i = 0; i < thread_count; i++)
0170 pthread_create(&pth[i], 0, thread, 0);
0171
0172 while (time(&now) < start + runtime) {
0173 sleep(1);
0174 if (done) {
0175 ret = 1;
0176 strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&now));
0177 printf("%s\n", buf);
0178 goto out;
0179 }
0180 }
0181 printf("[OK]\n");
0182 done = 1;
0183
0184 out:
0185
0186 for (i = 0; i < thread_count; i++)
0187 pthread_join(pth[i], &tret);
0188
0189
0190 if (ret)
0191 ksft_exit_fail();
0192 return ksft_exit_pass();
0193 }