Exemplo n.º 1
0
  public static boolean readFastPath(final ShadowVar gs, final ShadowThread td) {
    if (gs instanceof FastTrackGuardState) {
      final FastTrackGuardState x = ((FastTrackGuardState) gs);
      final int tdEpoch = ts_get_epoch(td);
      final long orig = x.getWREpochs();
      final int lastReadEpoch = EpochPair.read(orig);

      if (lastReadEpoch == tdEpoch) {
        return true; // commit : same epoch
      }

      final int tid = td.getTid();

      final int lastWriteEpoch = EpochPair.write(orig);
      final CV tdCV = ts_get_cv(td);

      if (lastReadEpoch == Epoch.READ_SHARED) {
        if (x.get(tid) != tdEpoch) { // (*)
          synchronized (x) {
            if (orig != x.getWREpochs()) return false;
            x.set(tid, tdEpoch);
          }
        }
      } else {
        final int lastReader = Epoch.tid(lastReadEpoch);
        if (lastReader == tid) {
          if (!x.cas(orig, lastWriteEpoch, tdEpoch)) return false;
          // commit: read-exclusive fast case
        } else if (lastReadEpoch <= tdCV.get(lastReader)) {
          if (!x.cas(orig, lastWriteEpoch, tdEpoch)) return false;
          // commit: read-exclusive slow case
        } else {
          synchronized (x) {
            x.makeCV(INIT_CV_SIZE); // do first, incase we need it above at (*)...					
            if (!x.cas(orig, lastWriteEpoch, Epoch.READ_SHARED)) return false;
            // commit: read share
            x.set(lastReader, lastReadEpoch);
            x.set(td.getTid(), tdEpoch);
          }
        }
      }

      final int lastWriter = Epoch.tid(lastWriteEpoch);
      if (lastWriter != tid && lastWriteEpoch > tdCV.get(lastWriter)) {
        ts_set_preStateOnError(td, new FastTrackGuardState(x, orig));
        return false;
      }

      return true;

    } else {
      return false;
    }
  }
Exemplo n.º 2
0
  public static boolean writeFastPath(final ShadowVar gs, final ShadowThread td) {
    if (gs instanceof FastTrackGuardState) {
      final FastTrackGuardState x = ((FastTrackGuardState) gs);
      final int tdEpoch = ts_get_epoch(td);

      final long orig = x.getWREpochs();
      final int lastWriteEpoch = EpochPair.read(orig);

      if (lastWriteEpoch == tdEpoch) {
        return true; // commit: same epoch
      }

      final int tid = td.getTid();
      final CV tdCV = ts_get_cv(td);

      final int lastReadEpoch = EpochPair.read(orig);
      if (lastReadEpoch == tdEpoch) {
        if (!x.cas(orig, tdEpoch, tdEpoch)) return false;
        // commit: write exclusive fast case
      } else if (lastReadEpoch != Epoch.READ_SHARED) {
        if (!x.cas(orig, tdEpoch, tdEpoch))
          return false; // make read be tdEpoch to ignore older reads
        // commit: write exclusive slow case
        final int lastReader = Epoch.tid(lastReadEpoch);
        if (lastReader != tid && lastReadEpoch > tdCV.get(lastReader)) {
          ts_set_preStateOnError(td, new FastTrackGuardState(x, orig));
          return false;
        }
      } else {
        synchronized (x) {
          if (!x.cas(orig, tdEpoch, tdEpoch)) return false;
          // commit write shared
          if (x.anyGt(tdCV)) {
            ts_set_preStateOnError(td, new FastTrackGuardState(x, orig));
            return false;
          }
        }
      }

      final int lastWriter = Epoch.tid(lastWriteEpoch);
      if (lastWriter != tid && lastWriteEpoch > tdCV.get(lastWriter)) {
        ts_set_preStateOnError(td, new FastTrackGuardState(x, orig));
        return false;
      }

      return true;
    } else {
      return false;
    }
  }
Exemplo n.º 3
0
  @Override
  public void create(NewThreadEvent e) {
    ShadowThread currentThread = e.getThread();
    CV cv = ts_get_cv(currentThread);

    if (cv == null) {
      cv = new CV(INIT_CV_SIZE);
      ts_set_cv(currentThread, cv);
      cv.set(currentThread.getTid(), Epoch.make(currentThread.getTid(), 0));
      this.incEpochAndCV(currentThread, null);
    }

    super.create(e);
  }
Exemplo n.º 4
0
 public static String toString(final ShadowThread td) {
   return String.format(
       "[tid=%-2d   cv=%s   epoch=%s]",
       td.getTid(), ts_get_cv(td), Epoch.toString(ts_get_epoch(td)));
 }
Exemplo n.º 5
0
  @Override
  public void access(final AccessEvent fae) {
    final ShadowVar var = fae.getOriginalShadow();
    final ShadowThread td = fae.getThread();

    if (var instanceof FastTrackGuardState) {

      // load the error guard state set by the fast path if it exists.
      final FastTrackGuardState isItAnError = ts_get_preStateOnError(td);
      final FastTrackGuardState x = (isItAnError != null) ? isItAnError : (FastTrackGuardState) var;
      ts_set_preStateOnError(td, null);

      final int tdEpoch = ts_get_epoch(td);
      final CV tdCV = ts_get_cv(td);

      Object target = fae.getTarget();
      if (target == null) {
        CV initTime = classInitTime.get(((FieldAccessEvent) fae).getInfo().getField().getOwner());
        tdCV.max(initTime);
      }
      if (!fae.isWrite()) {
        // READ
        retry:
        do {
          final long orig = x.getWREpochs();
          final int lastReadEpoch = EpochPair.read(orig);

          if (lastReadEpoch == tdEpoch) {
            break; // commit : same epoch
          }

          final int tid = td.getTid();

          final int lastWriteEpoch = EpochPair.write(orig);

          if (lastReadEpoch == Epoch.READ_SHARED) {
            if (x.get(tid) != tdEpoch) { // (*) racy access -> should be fine.
              synchronized (x) {
                if (orig != x.getWREpochs()) {
                  Yikes.yikes("concurrent mod");
                  continue retry;
                }
                x.set(tid, tdEpoch);
              }
            }
          } else {
            final int lastReader = Epoch.tid(lastReadEpoch);
            if (lastReader == tid) {
              if (!x.cas(orig, lastWriteEpoch, tdEpoch)) {
                Yikes.yikes("concurrent mod");
                continue retry;
              }
              // commit: read-exclusive fast case
            } else if (lastReadEpoch <= tdCV.get(lastReader)) {
              if (!x.cas(orig, lastWriteEpoch, tdEpoch)) {
                Yikes.yikes("concurrent mod");
                continue retry;
              }
              // commit: read-exclusive slow case
            } else {
              synchronized (x) {
                x.makeCV(INIT_CV_SIZE); // do first, in case we need it at (*)
                if (!x.cas(orig, lastWriteEpoch, Epoch.READ_SHARED)) {
                  Yikes.yikes("concurrent mod");
                  continue retry;
                }
                // commit: read share
                x.set(lastReader, lastReadEpoch);
                x.set(td.getTid(), tdEpoch);
              }
            }
          }

          final int lastWriter = Epoch.tid(lastWriteEpoch);
          if (lastWriter != tid && lastWriteEpoch > tdCV.get(lastWriter)) {
            error(fae, 4, "write-by-thread-", lastWriter, "read-by-thread-", tid);
          }
        } while (false); // awesome...
      } else {
        // WRITE
        retry:
        do {
          final long orig = x.getWREpochs();
          final int lastWriteEpoch = EpochPair.write(orig);

          if (lastWriteEpoch == tdEpoch) {
            break; // commit: same epoch
          }

          final int tid = td.getTid();

          final int lastReadEpoch = EpochPair.read(orig);
          if (lastReadEpoch == tdEpoch) {
            if (!x.cas(orig, tdEpoch, tdEpoch)) {
              Yikes.yikes("concurrent mod");
              continue retry;
            }
            // commit: write exclusive fast case
          } else if (lastReadEpoch != Epoch.READ_SHARED) {
            if (!x.cas(orig, tdEpoch, tdEpoch)) {
              Yikes.yikes("concurrent mod");
              continue retry;
            }
            // commit: write exclusive slow case
            final int lastReader = Epoch.tid(lastReadEpoch);
            if (lastReader != tid && lastReadEpoch > tdCV.get(lastReader)) {
              error(fae, 2, "read-by-thread-", lastReader, "write-by-thread-", tid);
            }
          } else {
            synchronized (x) {
              if (!x.cas(orig, tdEpoch, tdEpoch)) {
                Yikes.yikes("concurrent mod");
                continue retry;
              }
              // commit write shared
              if (x.anyGt(tdCV)) {
                int errorCount = 0;
                for (int prevReader = x.nextGt(tdCV, 0);
                    prevReader > -1;
                    prevReader = x.nextGt(tdCV, prevReader + 1)) {
                  if (prevReader != tid) {
                    errorCount++;
                    error(fae, 3, "read-by-thread-", prevReader, "write-by-thread-", tid);
                  }
                }
                if (errorCount == 0) {
                  Assert.fail("Bad error count");
                }
              }
            }
          }

          final int lastWriter = Epoch.tid(lastWriteEpoch);
          if (lastWriter != tid && lastWriteEpoch > tdCV.get(lastWriter)) {
            error(fae, 1, "write-by-thread-", lastWriter, "write-by-thread-", tid);
          }
        } while (false);
      }
    } else {
      super.access(fae);
    }
  }
Exemplo n.º 6
0
 public void testQualifiedName() throws Exception {
   Epoch epoch = Epoch.create("Epoch", "A", "B");
   assertEquals("Epoch: A", epoch.getStudySegments().get(0).getQualifiedName());
   assertEquals("Epoch: B", epoch.getStudySegments().get(1).getQualifiedName());
 }
Exemplo n.º 7
0
 public void testQualifiedNameZeroStudySegmentEpoch() throws Exception {
   assertEquals("Epoch", Epoch.create("Epoch").getStudySegments().get(0).getQualifiedName());
 }
Exemplo n.º 8
0
 public void testFindMatchingChildSegmentWhenNotPresent() throws Exception {
   Epoch e = Epoch.create("E", "A1", "A2");
   assertNull(e.findNaturallyMatchingChild("A0"));
 }