Beispiel #1
0
 @Override
 public void classInitialized(ClassInitializedEvent e) {
   final ShadowThread currentThread = e.getThread();
   final CV cv = this.ts_get_cv(currentThread);
   Util.log("Class Init for " + e + " -- " + cv);
   classInitTime.get(e.getRRClass()).max(cv);
   this.incEpochAndCV(currentThread, e);
   super.classInitialized(e);
 }
Beispiel #2
0
 @Override
 public void preWait(WaitEvent we) {
   FastTrackLockData lockData = get(we.getLock());
   this.incEpochAndCV(we.getThread(), we);
   synchronized (lockData) {
     lockData.cv.max(ts_get_cv(we.getThread()));
   }
   super.preWait(we);
 }
Beispiel #3
0
  @Override
  public void acquire(final AcquireEvent ae) {
    final ShadowThread td = ae.getThread();
    final ShadowLock shadowLock = ae.getLock();
    final FastTrackLockData fhbLockData = get(shadowLock);

    this.maxEpochAndCV(td, fhbLockData.cv, ae);

    super.acquire(ae);
  }
Beispiel #4
0
  @Override
  public void postJoin(final JoinEvent je) {
    final ShadowThread td = je.getThread();
    final ShadowThread joining = je.getJoiningThread();

    if (joining.getTid() != -1) {
      this.incEpochAndCV(joining, je);
      this.maxEpochAndCV(td, ts_get_cv(joining), je);
    }

    super.postJoin(je);
  }
Beispiel #5
0
  @Override
  public void release(final ReleaseEvent re) {
    final ShadowThread td = re.getThread();
    final ShadowLock shadowLock = re.getLock();
    final FastTrackLockData fhbLockData = get(shadowLock);

    CV cv = ts_get_cv(td);
    fhbLockData.cv.max(cv);
    this.incEpochAndCV(td, re);

    super.release(re);
  }
Beispiel #6
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);
  }
Beispiel #7
0
  @Override
  public void preStart(final StartEvent se) {

    final ShadowThread td = se.getThread();
    final ShadowThread forked = se.getNewThread();

    final CV curCV = ts_get_cv(td);

    CV forkedCV = ts_get_cv(forked);
    this.maxAndIncEpochAndCV(forked, curCV, se);

    this.incEpochAndCV(td, se);

    super.preStart(se);
  }
Beispiel #8
0
  @Override
  public void volatileAccess(final VolatileAccessEvent fae) {
    final ShadowVar orig = fae.getOriginalShadow();
    final ShadowThread td = fae.getThread();

    FastTrackVolatileData vd = get((fae).getShadowVolatile());
    final CV cv = ts_get_cv(td);
    if (fae.isWrite()) {
      vd.cv.max(cv);
      this.incEpochAndCV(td, fae);
    } else {
      cv.max(vd.cv);
    }
    super.volatileAccess(fae);
  }
Beispiel #9
0
 @Override
 public void postWait(WaitEvent we) {
   FastTrackLockData lockData = get(we.getLock());
   this.maxEpochAndCV(we.getThread(), lockData.cv, we);
   super.postWait(we);
 }
Beispiel #10
0
 @Override
 public void preNotify(NotifyEvent we) {
   super.preNotify(we);
 }
Beispiel #11
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);
    }
  }
Beispiel #12
0
 @Override
 public void stop(ShadowThread td) {
   super.stop(td);
 }