Beispiel #1
0
 // Notifies all the threads waiting on the object.
 protected final void notifyAll(Component host_, Object o_) {
   if (o_ == null) return;
   String old_ = state;
   setState(State_NOTIFYING);
   // sleepOn = o_;
   LockPack p_ = lookforLock(host_, o_);
   synchronized (o_) {
     // setState(State_NOTIFYING2);
     // sleepOn = null;
     if (p_.waitCount == 0) return;
     // runtime._notifyMany(o_, p_.waitCount, this);
     synchronized (aruntime) {
       if (aruntime.getWorkforce(p_.waitCount)) {
         o_.notifyAll(); // dont know who's going to wake up
         aruntime.nthreadsWaiting -= p_.waitCount;
       } else {
         int remainingWorkforce_ = aruntime.getRemainingWorkforce();
         // notify "remainingWorkforce_" threads
         for (int i = 0; i < remainingWorkforce_; i++) o_.notify();
         aruntime.nthreadsWaiting -= remainingWorkforce_;
         for (int i = p_.waitCount - remainingWorkforce_; i > 0; i--)
           aruntime.newTask(Task.createNotify(o_), this);
       }
     }
     p_.waitCount = 0;
   }
   setState(old_);
 }
Beispiel #2
0
 protected final void releaseAllLocks(Component host_) {
   String old_ = state;
   setState(State_UNLOCKING);
   for (LockPack p_ = (LockPack) host_.locks; p_ != null; p_ = p_.next)
     if (p_.holder == this) {
       // unlock(host_, p_.target, true);
       // below is copied from unlock()
       synchronized (p_) {
         p_.holder = null;
         p_.counter = -1;
         // p_.counter is not zero, see Note 1 above
         if (p_.lockReqCount == 0) {
           continue;
         }
         p_.lockReqCount--;
         synchronized (aruntime) {
           if (aruntime.getWorkforce()) {
             p_.notify(); // dont know who's going to wake up
             aruntime.nthreadsWaiting--;
           } else aruntime.newTask(Task.createNotify(p_), this);
         }
       }
     }
   setState(old_);
 }
Beispiel #3
0
  protected void unlock(Component host_, Object o_, boolean release_) {
    LockPack p_ = lookforLock(host_, o_);

    String old_ = state;
    setState(State_UNLOCKING);
    synchronized (p_) {
      if (release_ || --p_.counter < 0) p_.counter = 0;

      if (p_.counter == 0) {
        if (p_.lockReqCount == 0) {
          p_.holder = null;
          return;
        }
        // Note 1:
        // what if another thread grabs the lock before
        // the one being notified below?
        // p_.counter is not zero so other threads cannot just grab it
        p_.lockReqCount--;
        p_.counter = -1;
        p_.holder = null;
        synchronized (aruntime) {
          if (aruntime.getWorkforce()) {
            p_.notify(); // dont know who's going to wake up
            aruntime.nthreadsWaiting--;
          } else {
            aruntime.newTask(Task.createNotify(p_), this);
          }
        }
        // ---
      }
    }
    setState(old_);
  }
Beispiel #4
0
  // Make thread wait on the object until being notified by another thread.
  protected final void wait(Component host_, Object o_) {
    // if (nextTask != null) _semanticsError("wait(Object)");
    // looking for LockPack in host
    LockPack p_ = lookforLock(host_, o_);

    String old_ = state;
    setState(State_WAITING);
    synchronized (o_) {
      // Records the status if the thread holds the lock.
      if (waitPack == null) waitPack = new WaitPack();
      waitPack.target = p_.target;
      if (p_.holder == this) {
        waitPack.counter = p_.counter;
        // unlock(host_, o_, true/* release all grabs */);
        // below is copied from unlock()
        synchronized (p_) {
          p_.holder = null;
          if (p_.lockReqCount == 0) p_.counter = 0;
          else {
            p_.counter = -1;
            // p_.counter is not zero, see Note 1 above
            p_.lockReqCount--;
            synchronized (aruntime) {
              if (aruntime.getWorkforce()) {
                p_.notify(); // dont know who's going to wake up
                aruntime.nthreadsWaiting--;
              } else aruntime.newTask(Task.createNotify(p_), this);
            }
          }
        }
      }
      p_.waitCount++;

      // waited to be notified
      _sleepOn(o_, State_WAITING, null);

      if (isOrphan()) throw new WorkerThreadInterruptedException("Orphan thread");

      // _awakened();

      // re-grabbing the lock if necessary.
      if (waitPack.counter > 0) {
        synchronized (p_) {
          if (p_.holder != null) lock(host_, p_.target);
          else {
            p_.holder = this;
            p_.counter = waitPack.counter;
          }
        }
      }
    }

    if (p_ != null) {
      waitPack.counter = 0;
      waitPack.target = null;
    }
  }
Beispiel #5
0
  /**
   * Returns the thread that is holding the lock of the target object. The returned thread may be an
   * orphan thread from previous run. final WorkerThread getHolder(Object o_) { Component host_ =
   * getHost(); if (host_ == null) return null; LockPack p_ = lookforLock(host_, o_); return p_ ==
   * null? null: p_.holder; }
   */
  protected void yieldToRuntime() {
    synchronized (this) { // avoid racing with runtime.stop()
      if (aruntime.isSuspend())
        // go into sleep if runtime is suspended
        __sleepOn(this, State_PREACTIVE, state);
      else if (runtime.resetting) throw new WorkerThreadInterruptedException();

      aruntime.newTask(Task.createNotify(this), this);
      _sleepOn(this, State_YIELD, null);
    }
  }
Beispiel #6
0
 // Notifies the first thread waiting on the object.
 protected final void notify(Component host_, Object o_) {
   if (o_ == null) return;
   String old_ = state;
   setState(State_NOTIFYING);
   // sleepOn = o_;
   LockPack p_ = lookforLock(host_, o_);
   synchronized (o_) {
     // setState(State_NOTIFYING2);
     // sleepOn = null;
     if (p_.waitCount == 0) return;
     p_.waitCount--;
     synchronized (aruntime) {
       if (aruntime.getWorkforce()) {
         o_.notify(); // dont know who's going to wake up
         aruntime.nthreadsWaiting--;
       } else {
         aruntime.newTask(Task.createNotify(o_), this);
       }
     }
   }
   setState(old_);
 }