brintos

brintos / linux-shallow public Read only

0
0
Text · 4.3 KiB · d5564bb Raw
194 lines · c
1/* threadtest.c2 *		by: john stultz (johnstul@us.ibm.com)3 *		(C) Copyright IBM 2004, 2005, 2006, 20124 *		Licensed under the GPLv25 *6 *  To build:7 *	$ gcc threadtest.c -o threadtest -lrt8 *9 *   This program is free software: you can redistribute it and/or modify10 *   it under the terms of the GNU General Public License as published by11 *   the Free Software Foundation, either version 2 of the License, or12 *   (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 of16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the17 *   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 */27pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;28/* serializes console output */29pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;30 31 32#define MAX_THREADS 12833#define LISTSIZE 12834 35int done = 0;36 37struct timespec global_list[LISTSIZE];38int listcount = 0;39 40 41void checklist(const struct timespec *list, int size)42{43	int i, j;44	const 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 list78 * that each thread fills while holding the lock.79 * This stresses clock synchronization across cpus.80 */81void *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 own101 * list. This stresses clock_gettime() lock contention.102 */103void *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 8118#define DEFAULT_RUNTIME 30119 120int 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 184out: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	ksft_exit_pass();193}194