1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_clock_test.cc ------------------------------------------------===//
2da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//                     The LLVM Compiler Infrastructure
4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is distributed under the University of Illinois Open Source
6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// License. See LICENSE.TXT for details.
7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
10da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector.
11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
13da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_clock.h"
14da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_rtl.h"
15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "gtest/gtest.h"
16799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#include <sys/time.h>
172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <time.h>
18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanynamespace __tsan {
20da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
216d1862363c88c183b0ed7740fca876342cf0474bStephen HinesClockCache cache;
226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
23da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Clock, VectorBasic) {
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock clk(0);
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.size(), 1U);
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  clk.tick();
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.size(), 1U);
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.get(0), 1U);
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  clk.set(3, clk.get(3) + 1);
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.size(), 4U);
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.get(0), 1U);
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.get(1), 0U);
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.get(2), 0U);
342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.get(3), 1U);
352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  clk.set(3, clk.get(3) + 1);
362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(clk.get(3), 2U);
37da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
38da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Clock, ChunkedBasic) {
402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock vector(0);
41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  SyncClock chunked;
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector.size(), 1U);
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(chunked.size(), 0U);
446d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  vector.acquire(&cache, &chunked);
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector.size(), 1U);
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(chunked.size(), 0U);
476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  vector.release(&cache, &chunked);
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector.size(), 1U);
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(chunked.size(), 1U);
506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  vector.acq_rel(&cache, &chunked);
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector.size(), 1U);
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(chunked.size(), 1U);
536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  chunked.Reset(&cache);
54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Clock, AcquireRelease) {
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock vector1(100);
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  vector1.tick();
59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  SyncClock chunked;
606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  vector1.release(&cache, &chunked);
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(chunked.size(), 101U);
622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock vector2(0);
636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  vector2.acquire(&cache, &chunked);
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector2.size(), 101U);
652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector2.get(0), 0U);
662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector2.get(1), 0U);
672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector2.get(99), 0U);
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(vector2.get(100), 1U);
696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  chunked.Reset(&cache);
702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesTEST(Clock, RepeatedAcquire) {
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock thr1(1);
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  thr1.tick();
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock thr2(2);
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  thr2.tick();
772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SyncClock sync;
796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  thr1.ReleaseStore(&cache, &sync);
806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  thr2.acquire(&cache, &sync);
826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  thr2.acquire(&cache, &sync);
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  sync.Reset(&cache);
85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
87da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Clock, ManyThreads) {
88da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  SyncClock chunked;
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (unsigned i = 0; i < 100; i++) {
902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ThreadClock vector(0);
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    vector.tick();
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    vector.set(i, 1);
936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.release(&cache, &chunked);
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ASSERT_EQ(i + 1, chunked.size());
956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.acquire(&cache, &chunked);
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ASSERT_EQ(i + 1, vector.size());
97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  }
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (unsigned i = 0; i < 100; i++)
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ASSERT_EQ(1U, chunked.get(i));
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock vector(1);
1036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  vector.acquire(&cache, &chunked);
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(100U, vector.size());
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (unsigned i = 0; i < 100; i++)
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ASSERT_EQ(1U, vector.get(i));
1076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
1086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  chunked.Reset(&cache);
109da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
110da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
111da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Clock, DifferentSizes) {
112da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  {
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ThreadClock vector1(10);
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    vector1.tick();
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ThreadClock vector2(20);
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    vector2.tick();
117da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    {
118da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany      SyncClock chunked;
1196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector1.release(&cache, &chunked);
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ASSERT_EQ(chunked.size(), 11U);
1216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector2.release(&cache, &chunked);
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ASSERT_EQ(chunked.size(), 21U);
1236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      chunked.Reset(&cache);
124da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    }
125da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    {
126da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany      SyncClock chunked;
1276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector2.release(&cache, &chunked);
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ASSERT_EQ(chunked.size(), 21U);
1296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector1.release(&cache, &chunked);
1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ASSERT_EQ(chunked.size(), 21U);
1316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      chunked.Reset(&cache);
132da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    }
133da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    {
134da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany      SyncClock chunked;
1356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector1.release(&cache, &chunked);
1366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector2.acquire(&cache, &chunked);
1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ASSERT_EQ(vector2.size(), 21U);
1386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      chunked.Reset(&cache);
139da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    }
140da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    {
141da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany      SyncClock chunked;
1426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector2.release(&cache, &chunked);
1436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      vector1.acquire(&cache, &chunked);
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ASSERT_EQ(vector1.size(), 21U);
1456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      chunked.Reset(&cache);
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1506d1862363c88c183b0ed7740fca876342cf0474bStephen HinesTEST(Clock, Growth) {
1516d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  {
1526d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ThreadClock vector(10);
1536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.tick();
1546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.set(5, 42);
1556d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    SyncClock sync;
1566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.release(&cache, &sync);
1576d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.size(), 11U);
1586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(0), 0ULL);
1596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(1), 0ULL);
1606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(5), 42ULL);
1616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(9), 0ULL);
1626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(10), 1ULL);
1636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    sync.Reset(&cache);
1646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
1656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  {
1666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ThreadClock vector1(10);
1676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector1.tick();
1686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ThreadClock vector2(20);
1696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector2.tick();
1706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    SyncClock sync;
1716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector1.release(&cache, &sync);
1726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector2.release(&cache, &sync);
1736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.size(), 21U);
1746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(0), 0ULL);
1756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(10), 1ULL);
1766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(19), 0ULL);
1776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(20), 1ULL);
1786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    sync.Reset(&cache);
1796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
1806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  {
1816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ThreadClock vector(100);
1826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.tick();
1836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.set(5, 42);
1846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.set(90, 84);
1856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    SyncClock sync;
1866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector.release(&cache, &sync);
1876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.size(), 101U);
1886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(0), 0ULL);
1896d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(1), 0ULL);
1906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(5), 42ULL);
1916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(60), 0ULL);
1926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(70), 0ULL);
1936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(90), 84ULL);
1946d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(99), 0ULL);
1956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(100), 1ULL);
1966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    sync.Reset(&cache);
1976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
1986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  {
1996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ThreadClock vector1(10);
2006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector1.tick();
2016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ThreadClock vector2(100);
2026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector2.tick();
2036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    SyncClock sync;
2046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector1.release(&cache, &sync);
2056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    vector2.release(&cache, &sync);
2066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.size(), 101U);
2076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(0), 0ULL);
2086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(10), 1ULL);
2096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(99), 0ULL);
2106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    ASSERT_EQ(sync.get(100), 1ULL);
2116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    sync.Reset(&cache);
2126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
2136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
2146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
21586277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesconst uptr kThreads = 4;
21686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesconst uptr kClocks = 4;
2172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// SimpleSyncClock and SimpleThreadClock implement the same thing as
2192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// SyncClock and ThreadClock, but in a very simple way.
2202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct SimpleSyncClock {
2212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  u64 clock[kThreads];
2222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr size;
2232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SimpleSyncClock() {
2252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    Reset();
2262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void Reset() {
2292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    size = 0;
2302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < kThreads; i++)
2312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      clock[i] = 0;
2322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool verify(const SyncClock *other) const {
2352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < min(size, other->size()); i++) {
2362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (clock[i] != other->get(i))
2372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
2382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
2392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = min(size, other->size()); i < max(size, other->size()); i++) {
2402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (i < size && clock[i] != 0)
2412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (i < other->size() && other->get(i) != 0)
2432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return true;
2462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct SimpleThreadClock {
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  u64 clock[kThreads];
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr size;
2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unsigned tid;
2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  explicit SimpleThreadClock(unsigned tid) {
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    this->tid = tid;
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    size = tid + 1;
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < kThreads; i++)
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      clock[i] = 0;
2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void tick() {
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    clock[tid]++;
2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void acquire(const SimpleSyncClock *src) {
2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (size < src->size)
2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      size = src->size;
2682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < kThreads; i++)
2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      clock[i] = max(clock[i], src->clock[i]);
2702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void release(SimpleSyncClock *dst) const {
2732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (dst->size < size)
2742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      dst->size = size;
2752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < kThreads; i++)
2762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      dst->clock[i] = max(dst->clock[i], clock[i]);
2772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void acq_rel(SimpleSyncClock *dst) {
2802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    acquire(dst);
2812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    release(dst);
2822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void ReleaseStore(SimpleSyncClock *dst) const {
2852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (dst->size < size)
2862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      dst->size = size;
2872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < kThreads; i++)
2882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      dst->clock[i] = clock[i];
2892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool verify(const ThreadClock *other) const {
2922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = 0; i < min(size, other->size()); i++) {
2932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (clock[i] != other->get(i))
2942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
2952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
2962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (uptr i = min(size, other->size()); i < max(size, other->size()); i++) {
2972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (i < size && clock[i] != 0)
2982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
2992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (i < other->size() && other->get(i) != 0)
3002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
301da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany    }
3022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return true;
3032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
3042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
3052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic bool ClockFuzzer(bool printing) {
3072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Create kThreads thread clocks.
3082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SimpleThreadClock *thr0[kThreads];
3092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ThreadClock *thr1[kThreads];
3102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unsigned reused[kThreads];
3112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (unsigned i = 0; i < kThreads; i++) {
3122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    reused[i] = 0;
3132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    thr0[i] = new SimpleThreadClock(i);
3142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    thr1[i] = new ThreadClock(i, reused[i]);
3152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
3162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Create kClocks sync clocks.
3182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SimpleSyncClock *sync0[kClocks];
3192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SyncClock *sync1[kClocks];
3202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (unsigned i = 0; i < kClocks; i++) {
3212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    sync0[i] = new SimpleSyncClock();
3222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    sync1[i] = new SyncClock();
3232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
3242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Do N random operations (acquire, release, etc) and compare results
3262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // for SimpleThread/SyncClock and real Thread/SyncClock.
3272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (int i = 0; i < 10000; i++) {
3282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    unsigned tid = rand() % kThreads;
3292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    unsigned cid = rand() % kClocks;
3302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    thr0[tid]->tick();
3312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    thr1[tid]->tick();
3322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    switch (rand() % 6) {
3342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    case 0:
3352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (printing)
3362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("acquire thr%d <- clk%d\n", tid, cid);
3372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr0[tid]->acquire(sync0[cid]);
3386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      thr1[tid]->acquire(&cache, sync1[cid]);
3392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      break;
3402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    case 1:
3412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (printing)
3422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("release thr%d -> clk%d\n", tid, cid);
3432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr0[tid]->release(sync0[cid]);
3446d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      thr1[tid]->release(&cache, sync1[cid]);
3452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      break;
3462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    case 2:
3472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (printing)
3482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("acq_rel thr%d <> clk%d\n", tid, cid);
3492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr0[tid]->acq_rel(sync0[cid]);
3506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      thr1[tid]->acq_rel(&cache, sync1[cid]);
3512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      break;
3522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    case 3:
3532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (printing)
3542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("rel_str thr%d >> clk%d\n", tid, cid);
3552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr0[tid]->ReleaseStore(sync0[cid]);
3566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      thr1[tid]->ReleaseStore(&cache, sync1[cid]);
3572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      break;
3582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    case 4:
3592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (printing)
3602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("reset clk%d\n", cid);
3612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      sync0[cid]->Reset();
3626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      sync1[cid]->Reset(&cache);
3632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      break;
3642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    case 5:
3652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (printing)
3662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("reset thr%d\n", tid);
3672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      u64 epoch = thr0[tid]->clock[tid] + 1;
3682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      reused[tid]++;
3692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      delete thr0[tid];
3702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr0[tid] = new SimpleThreadClock(tid);
3712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr0[tid]->clock[tid] = epoch;
3722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      delete thr1[tid];
3732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr1[tid] = new ThreadClock(tid, reused[tid]);
3742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      thr1[tid]->set(epoch);
3752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      break;
3762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
3772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (printing) {
3792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      for (unsigned i = 0; i < kThreads; i++) {
3802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("thr%d: ", i);
3812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        thr1[i]->DebugDump(printf);
3822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("\n");
3832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
3842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      for (unsigned i = 0; i < kClocks; i++) {
3852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("clk%d: ", i);
3862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        sync1[i]->DebugDump(printf);
3872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("\n");
3882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
3892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf("\n");
3912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
3922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (!thr0[tid]->verify(thr1[tid]) || !sync0[cid]->verify(sync1[cid])) {
3942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (!printing)
3952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        return false;
3962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf("differs with model:\n");
3972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      for (unsigned i = 0; i < kThreads; i++) {
3982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("thr%d: clock=[", i);
3992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        for (uptr j = 0; j < thr0[i]->size; j++)
4002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          printf("%s%llu", j == 0 ? "" : ",", thr0[i]->clock[j]);
4012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("]\n");
4022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
4032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      for (unsigned i = 0; i < kClocks; i++) {
4042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("clk%d: clock=[", i);
4052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        for (uptr j = 0; j < sync0[i]->size; j++)
4062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          printf("%s%llu", j == 0 ? "" : ",", sync0[i]->clock[j]);
4072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        printf("]\n");
4082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
4092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      return false;
4102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
4112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
4126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
4136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  for (unsigned i = 0; i < kClocks; i++) {
4146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    sync1[i]->Reset(&cache);
4156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
4162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return true;
4172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
4182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesTEST(Clock, Fuzzer) {
420799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  struct timeval tv;
421799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  gettimeofday(&tv, NULL);
422799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int seed = tv.tv_sec + tv.tv_usec;
4232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  printf("seed=%d\n", seed);
4242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  srand(seed);
4252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!ClockFuzzer(false)) {
4262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // Redo the test with the same seed, but logging operations.
4272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    srand(seed);
4282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ClockFuzzer(true);
4292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ASSERT_TRUE(false);
430da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  }
431da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
432da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
433da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}  // namespace __tsan
434