gettime: use pthread_{set,get}specific() for TLS

__thread doesn't work on OSX at least (thanks...), so resort to
using the pthread functions to maintaining a per-thread clock
check.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/gettime.c b/gettime.c
index 1a7af37..921c171 100644
--- a/gettime.c
+++ b/gettime.c
@@ -18,8 +18,12 @@
 static unsigned long last_cycles;
 int tsc_reliable = 0;
 #endif
-static __thread struct timeval last_tv;
-static __thread int last_tv_valid;
+
+struct tv_valid {
+	struct timeval last_tv;
+	int last_tv_valid;
+};
+static pthread_key_t tv_tls_key;
 
 enum fio_cs fio_clock_source = FIO_PREFERRED_CLOCK_SOURCE;
 int fio_clock_source_set = 0;
@@ -122,6 +126,8 @@
 void fio_gettime(struct timeval *tp, void fio_unused *caller)
 #endif
 {
+	struct tv_valid *t;
+
 #ifdef FIO_DEBUG_TIME
 	if (!caller)
 		caller = __builtin_return_address(0);
@@ -179,15 +185,18 @@
 	 * If Linux is using the tsc clock on non-synced processors,
 	 * sometimes time can appear to drift backwards. Fix that up.
 	 */
-	if (last_tv_valid) {
-		if (tp->tv_sec < last_tv.tv_sec)
-			tp->tv_sec = last_tv.tv_sec;
-		else if (last_tv.tv_sec == tp->tv_sec &&
-			 tp->tv_usec < last_tv.tv_usec)
-			tp->tv_usec = last_tv.tv_usec;
+	t = pthread_getspecific(tv_tls_key);
+	if (t) {
+		if (t->last_tv_valid) {
+			if (tp->tv_sec < t->last_tv.tv_sec)
+				tp->tv_sec = t->last_tv.tv_sec;
+			else if (t->last_tv.tv_sec == tp->tv_sec &&
+				 tp->tv_usec < t->last_tv.tv_usec)
+				tp->tv_usec = t->last_tv.tv_usec;
+		}
+		t->last_tv_valid = 1;
+		memcpy(&t->last_tv, tp, sizeof(*tp));
 	}
-	last_tv_valid = 1;
-	memcpy(&last_tv, tp, sizeof(*tp));
 }
 
 #ifdef ARCH_HAVE_CPU_CLOCK
@@ -262,12 +271,28 @@
 }
 #endif
 
+void fio_local_clock_init(int is_thread)
+{
+	struct tv_valid *t;
+
+	t = calloc(sizeof(*t), 1);
+	if (pthread_setspecific(tv_tls_key, t))
+		log_err("fio: can't set TLS key\n");
+}
+
+static void kill_tv_tls_key(void *data)
+{
+	free(data);
+}
+
 void fio_clock_init(void)
 {
 	if (fio_clock_source == fio_clock_source_inited)
 		return;
 
-	last_tv_valid = 0;
+	if (pthread_key_create(&tv_tls_key, kill_tv_tls_key))
+		log_err("fio: can't create TLS key\n");
+
 	fio_clock_source_inited = fio_clock_source;
 	calibrate_cpu_clock();