1/* quick time() and gmtime() tester. */
2/* As of Dec. 20, 2000, this test demonstrates that stdlib time() is thread-safe, but
3 * gmtime() is NOT thread safe. */
4#include <time.h>
5#include <stdio.h>
6#include "testParams.h"
7#include <security_utilities/threading.h>
8#include <CoreFoundation/CFDate.h>
9
10#define DO_CF_TIME		1
11#define DO_TIME_LOCK	1
12
13#if		DO_CF_TIME
14int timeInit(TestParams *tp)
15{
16	return 0;
17}
18
19#define INNER_LOOPS		100
20
21int timeThread(TestParams *tp)
22{
23	CFAbsoluteTime cfTimes[INNER_LOOPS];
24
25	for(unsigned dex=0; dex<tp->numLoops; dex++) {
26		if(tp->verbose) {
27			printf("timeThread loop %u\n", dex);
28		}
29		else if(!tp->quiet) {
30			printChar(tp->progressChar);
31		}
32
33		for(unsigned innerLoop=0; innerLoop<INNER_LOOPS; innerLoop++) {
34			cfTimes[innerLoop] = CFAbsoluteTimeGetCurrent();
35		}
36	}
37	return 0;
38}
39
40#else
41
42/* process-wide time base */
43static time_t baseTime = 0;
44static tm baseTm;
45static Mutex timeLock;
46
47/* init time base first time thru */
48int timeInit(TestParams *tp)
49{
50	if(baseTime != 0) {
51		return 0;
52	}
53	baseTime = time(NULL);
54	baseTm = *gmtime(&baseTime);
55	return 0;
56}
57
58int timeThread(TestParams *tp)
59{
60	unsigned dex;
61
62	for(dex=0; dex<(100 * tp->numLoops); dex++) {
63		time_t nowTime;
64		struct tm nowTm;
65		nowTime = time(NULL);
66		#if DO_TIME_LOCK
67		timeLock.lock();
68		#endif
69		nowTm = *gmtime(&nowTime);
70		#if	DO_TIME_LOCK
71		timeLock.unlock();
72		#endif
73		if(nowTime < baseTime) {
74			printf("\n***time() went backwards: base %d  now %d\n",
75				(int)baseTime, (int)nowTime);
76			return 1;
77		}
78		if((nowTm.tm_year < baseTm.tm_year) ||
79		   (nowTm.tm_mon  < baseTm.tm_mon) ||
80		   (nowTm.tm_mday  < baseTm.tm_mday) ||
81		   /* careful, this overflows at midnight */
82		   (nowTm.tm_hour  < baseTm.tm_hour)) {
83			printf("\n***gmtime() went backwards\n");
84			printf(" baseTm y:%d m:%d d:%d h:%d m:%d\n",
85				baseTm.tm_year, baseTm.tm_mon, baseTm.tm_mday,
86				baseTm.tm_hour, baseTm.tm_min);
87			printf(" nowTm  y:%d m:%d d:%d h:%d m:%d\n",
88				nowTm.tm_year, nowTm.tm_mon, nowTm.tm_mday,
89				nowTm.tm_hour, nowTm.tm_min);
90			return 1;
91		}
92		if(((dex % 100) == 0) && !tp->quiet) {
93			printChar(tp->progressChar);
94		}
95	}
96	return 0;
97}
98
99#endif	/* DO_CF_TIME */
100