root/tools/testing/selftests/timers/threadtest.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. checklist
  2. shared_thread
  3. independent_thread
  4. main

   1 /* threadtest.c
   2  *              by: john stultz (johnstul@us.ibm.com)
   3  *              (C) Copyright IBM 2004, 2005, 2006, 2012
   4  *              Licensed under the GPLv2
   5  *
   6  *  To build:
   7  *      $ gcc threadtest.c -o threadtest -lrt
   8  *
   9  *   This program is free software: you can redistribute it and/or modify
  10  *   it under the terms of the GNU General Public License as published by
  11  *   the Free Software Foundation, either version 2 of the License, or
  12  *   (at your option) any later version.
  13  *
  14  *   This program is distributed in the hope that it will be useful,
  15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17  *   GNU General Public License for more details.
  18  */
  19 #include <stdio.h>
  20 #include <unistd.h>
  21 #include <stdlib.h>
  22 #include <sys/time.h>
  23 #include <pthread.h>
  24 #include "../kselftest.h"
  25 
  26 /* serializes shared list access */
  27 pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
  28 /* serializes console output */
  29 pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
  30 
  31 
  32 #define MAX_THREADS 128
  33 #define LISTSIZE 128
  34 
  35 int done = 0;
  36 
  37 struct timespec global_list[LISTSIZE];
  38 int listcount = 0;
  39 
  40 
  41 void checklist(struct timespec *list, int size)
  42 {
  43         int i, j;
  44         struct timespec *a, *b;
  45 
  46         /* scan the list */
  47         for (i = 0; i < size-1; i++) {
  48                 a = &list[i];
  49                 b = &list[i+1];
  50 
  51                 /* look for any time inconsistencies */
  52                 if ((b->tv_sec <= a->tv_sec) &&
  53                         (b->tv_nsec < a->tv_nsec)) {
  54 
  55                         /* flag other threads */
  56                         done = 1;
  57 
  58                         /*serialize printing to avoid junky output*/
  59                         pthread_mutex_lock(&print_lock);
  60 
  61                         /* dump the list */
  62                         printf("\n");
  63                         for (j = 0; j < size; j++) {
  64                                 if (j == i)
  65                                         printf("---------------\n");
  66                                 printf("%lu:%lu\n", list[j].tv_sec, list[j].tv_nsec);
  67                                 if (j == i+1)
  68                                         printf("---------------\n");
  69                         }
  70                         printf("[FAILED]\n");
  71 
  72                         pthread_mutex_unlock(&print_lock);
  73                 }
  74         }
  75 }
  76 
  77 /* The shared thread shares a global list
  78  * that each thread fills while holding the lock.
  79  * This stresses clock syncronization across cpus.
  80  */
  81 void *shared_thread(void *arg)
  82 {
  83         while (!done) {
  84                 /* protect the list */
  85                 pthread_mutex_lock(&list_lock);
  86 
  87                 /* see if we're ready to check the list */
  88                 if (listcount >= LISTSIZE) {
  89                         checklist(global_list, LISTSIZE);
  90                         listcount = 0;
  91                 }
  92                 clock_gettime(CLOCK_MONOTONIC, &global_list[listcount++]);
  93 
  94                 pthread_mutex_unlock(&list_lock);
  95         }
  96         return NULL;
  97 }
  98 
  99 
 100 /* Each independent thread fills in its own
 101  * list. This stresses clock_gettime() lock contention.
 102  */
 103 void *independent_thread(void *arg)
 104 {
 105         struct timespec my_list[LISTSIZE];
 106         int count;
 107 
 108         while (!done) {
 109                 /* fill the list */
 110                 for (count = 0; count < LISTSIZE; count++)
 111                         clock_gettime(CLOCK_MONOTONIC, &my_list[count]);
 112                 checklist(my_list, LISTSIZE);
 113         }
 114         return NULL;
 115 }
 116 
 117 #define DEFAULT_THREAD_COUNT 8
 118 #define DEFAULT_RUNTIME 30
 119 
 120 int main(int argc, char **argv)
 121 {
 122         int thread_count, i;
 123         time_t start, now, runtime;
 124         char buf[255];
 125         pthread_t pth[MAX_THREADS];
 126         int opt;
 127         void *tret;
 128         int ret = 0;
 129         void *(*thread)(void *) = shared_thread;
 130 
 131         thread_count = DEFAULT_THREAD_COUNT;
 132         runtime = DEFAULT_RUNTIME;
 133 
 134         /* Process arguments */
 135         while ((opt = getopt(argc, argv, "t:n:i")) != -1) {
 136                 switch (opt) {
 137                 case 't':
 138                         runtime = atoi(optarg);
 139                         break;
 140                 case 'n':
 141                         thread_count = atoi(optarg);
 142                         break;
 143                 case 'i':
 144                         thread = independent_thread;
 145                         printf("using independent threads\n");
 146                         break;
 147                 default:
 148                         printf("Usage: %s [-t <secs>] [-n <numthreads>] [-i]\n", argv[0]);
 149                         printf("        -t: time to run\n");
 150                         printf("        -n: number of threads\n");
 151                         printf("        -i: use independent threads\n");
 152                         return -1;
 153                 }
 154         }
 155 
 156         if (thread_count > MAX_THREADS)
 157                 thread_count = MAX_THREADS;
 158 
 159 
 160         setbuf(stdout, NULL);
 161 
 162         start = time(0);
 163         strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&start));
 164         printf("%s\n", buf);
 165         printf("Testing consistency with %i threads for %ld seconds: ", thread_count, runtime);
 166         fflush(stdout);
 167 
 168         /* spawn */
 169         for (i = 0; i < thread_count; i++)
 170                 pthread_create(&pth[i], 0, thread, 0);
 171 
 172         while (time(&now) < start + runtime) {
 173                 sleep(1);
 174                 if (done) {
 175                         ret = 1;
 176                         strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&now));
 177                         printf("%s\n", buf);
 178                         goto out;
 179                 }
 180         }
 181         printf("[OK]\n");
 182         done = 1;
 183 
 184 out:
 185         /* wait */
 186         for (i = 0; i < thread_count; i++)
 187                 pthread_join(pth[i], &tret);
 188 
 189         /* die */
 190         if (ret)
 191                 ksft_exit_fail();
 192         return ksft_exit_pass();
 193 }

/* [<][>][^][v][top][bottom][index][help] */