コード例 #1
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
 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_);
 }
コード例 #2
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
 // 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_);
 }
コード例 #3
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  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_);
  }
コード例 #4
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  // 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;
    }
  }
コード例 #5
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  /**
   * 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);
    }
  }
コード例 #6
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  void _sleepOn(Object sleepOn_, String prestate_, String poststate_) {
    if (poststate_ == null) poststate_ = state;

    sleepOn = sleepOn_;
    synchronized (sleepOn) {
      if (nextTask != null) _semanticsError("wait()");
      aruntime.threadBecomesWaiting(this);
      __sleepOn(sleepOn_, prestate_, State_AWAKENING);
      // runtime.threadAwakeFromWaiting(this);
      if (aruntime.debug && aruntime.isDebugEnabledAt(aruntime.Debug_Q))
        aruntime.println(
            aruntime.Debug_Q, this, "awaked from indefinite sleep: " + _currentContext());
    }
    setState(poststate_);
  }
コード例 #7
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
 protected void changeCurrentContext(Port port_, Object data_, String state_) {
   // mainContext = new Task(port_, data_, mainContext.type, 0.0);
   if (currentContext == mainContext || currentContext == null)
     currentContext = new TaskReceive(port_, data_);
   else {
     currentContext.data = data_;
     currentContext.port = port_;
   }
   if (state_ != null) state = state_;
   ;
   if (aruntime.debug && aruntime.isDebugEnabledAt(ARuntime.Debug_THREAD))
     aruntime.println(
         ARuntime.Debug_THREAD,
         this,
         "currentContext ---> " + "state:" + state + "," + _currentContext());
 }
コード例 #8
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  protected final void setState(String new_) {
    if (state == new_) return;

    if (aruntime.debug) aruntime.threadStateChange(this, state, new_);

    // if (stateQ.isFull()) stateQ.dequeue(); // temporary
    // stateQ.enqueue(state); // temporary
    state = new_;
  }
コード例 #9
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
 // 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_);
 }
コード例 #10
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  void _sleepUntil(double time_, String poststate_) {
    if (poststate_ == null) poststate_ = state;

    setWakeupTime(time_);
    // set the following two lines before calling
    // runtime.threadRequestsWaiting() to avoid racing
    // (see codes below)
    if (sleepOn == null) sleepOn = this;
    // for wait(Object, double), sleepOn is preset
    synchronized (sleepOn) {
      if (nextTask != null) _semanticsError("sleep()");
      if (aruntime.threadRequestsSleeping(this, time_)) {
        __sleepOn(sleepOn, State_SLEEPING, State_AWAKENING);
        // runtime.threadAwakeFromSleeping(this);
        if (aruntime.debug && aruntime.isDebugEnabledAt(aruntime.Debug_Q))
          aruntime.println(
              aruntime.Debug_Q, this, "awaked from finite sleep, " + _currentContext());
      }
      setWakeupTime(Double.NaN);
    }
    setState(poststate_);
  }
コード例 #11
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  /** Delay the starting until the time specified later(second). */
  public void start() {
    // if (port != null) System.out.println(this + " starts: " + data);
    // runtime.startRegister(this);

    if (aruntime.isSuspend()) return;

    if (isAlive()) {
      // __wakeUp();
      synchronized (this) {
        lastsleepon = this;
        lastwakeupthread = Thread.currentThread();

        try {
          this.notify();
        } catch (Exception e_) {
          drcl.Debug.error(this, "start()| " + e_, false);
        }
      }
    } else {
      // the thread is newly created
      setState(State_INACTIVE);
      super.start();
    }
  }
コード例 #12
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
 /** Let go of the thread from sleep in idle. */
 public void kill() {
   if (isAlive()) interrupt();
   else aruntime.remove(this);
 }
コード例 #13
0
ファイル: AWorkerThread.java プロジェクト: manoj-g-nair/j-sim
  /** Standard Thread.run(). */
  public /*final*/ void run() {
    if (Thread.currentThread() != this) {
      throw new WorkerThreadException(
          "not run() by the owning thread.  Current thread:"
              + Thread.currentThread()
              + "---owning thread:"
              + this);
    }

    try {
      if (aruntime.debug && aruntime.isDebugEnabledAt(ARuntime.Debug_THREAD))
        aruntime.println(ARuntime.Debug_THREAD, this, "THREAD STARTS");

      for (; ; ) {

        // Note:
        // getTask() and recycle() must happen atomically because
        // during the time after this thread cannot get more tasks
        // from runtime.getTask() and before it goes to recycle() to
        // return workforce, another thread may produce a new task in
        // the ready queue (without this thread knowing it) and that
        // thread goes to the waiting state.  Due to this racing,
        // the simulation could be stalled as no thread is actively
        // running to execute the new task in the ready queue.
        synchronized (aruntime) {
          if (mainContext == null || mainContext == DUMMY_CONTEXT) {
            // grab a task from worker pool
            nextTask = GETTING_TASK;
            // XXX: temporary for debug
            nextTask = aruntime.getTask(mainContext == null);
            if (nextTask != null) {
              // so null wont override DUMMY_CONTEXT
              mainContext = nextTask;
              nextTask = null;
            } else {
              setState(State_RECYCLING);
              sleepOn = this;
              aruntime.recycle(this);
              // return workforce in recycle()
            }
          }
        }

        if (state == State_RECYCLING) {
          setState(State_INACTIVE);
          // BOOKMARK1:
          // At this point, other threads may assign a new task
          // to this thread and start this thread, so check if
          // mainContext is being assigned within
          // the following synchronized claus
          synchronized (this) {
            if (mainContext == DUMMY_CONTEXT) mainContext = null;

            if (mainContext == null) {
              __sleepOn(this, State_INACTIVE, State_INACTIVE);
              continue;
            } else sleepOn = null;
          }
        }

        if (runtime.resetting) {
          throw new WorkerThreadInterruptedException();
        } else if (aruntime.isSuspend()) {
          // go into sleep if runtime is suspended
          synchronized (this) {
            __sleepOn(this, State_PREACTIVE, State_ACTIVE);
          }
        }

        if (mainContext.threadGroup != null) {
          if (mainContext instanceof TaskNotify) {
            // mainContext is TaskNotify:
            // the object to be notified on is in "data"
            synchronized (mainContext.data) {
              if (aruntime.debug && aruntime.isDebugEnabledAt(ARuntime.Debug_THREAD))
                aruntime.println(
                    ARuntime.Debug_THREAD,
                    this,
                    "EXECUTING notify:" + mainContext.data + "," + System.currentTimeMillis());
              mainContext.data.notify();
              aruntime.nthreadsWaiting--;
            }
            mainContext = null;
            // workforce transfered to the waked up thread
            continue;
          } else if (getThreadGroup() != mainContext.threadGroup) {
            aruntime.immediatelyStart(mainContext);
            mainContext = null;
            // workforce transfered to new thread
            continue;
          }
        }

        if (aruntime.debug && aruntime.isDebugEnabledAt(ARuntime.Debug_THREAD))
          aruntime.println(ARuntime.Debug_THREAD, this, "EXECUTING:" + mainContext);

        setState(State_ACTIVE);

        // runtime.runCheck(this);
        String method_ = "process()";
        currentContext = mainContext;
        returnPort = currentContext.returnPort;
        // from server port, new context
        try {
          mainContext.execute(this);
        } catch (NullPointerException e_) {
          if (runtime == null) return;
          e_.printStackTrace();
          drcl.Debug.error(info());
        } catch (Exception e_) {
          e_.printStackTrace();
          drcl.Debug.error(info());
        } catch (SendReceiveException e_) {
          e_.printStackTrace();
          drcl.Debug.error(info());
        }
        currentContext.port = null;
        currentContext.data = null;

        finishing();
        mainContext = DUMMY_CONTEXT;
        // to maintain the ownership of workforce

        if (!RECYCLING) {
          aruntime.remove(this);
          break;
        }

        if (nextTask != null) {
          // error checking
          if (mainContext != null && mainContext != DUMMY_CONTEXT)
            drcl.Debug.systemFatalError("task assigned to occupied thread:" + this);
          mainContext = nextTask;
          nextTask = null;
        }
      } // for(;;)
      drcl.Debug.systemFatalError("Unexpected finish at " + this);
    } catch (WorkerThreadInterruptedException e_) {
      // if (!runtime.resetting) {
      //  e_.printStackTrace();
      //  drcl.Debug.systemFatalError(
      //    "AWorkerThread terminates abnormally, " + this
      //      + "\nManager: " + runtime.diag());
      // }
      // Will releaseAllLocks()/cancelAllWaits() clean up the lock
      //   structure in components?
      // Not if the thread comes across multiple components...
      if (mainContext != null && mainContext.port != null) releaseAllLocks(mainContext.port.host);
      aruntime.remove(this);
    } catch (NullPointerException e_) {
      if (runtime != null) {
        e_.printStackTrace();
        drcl.Debug.error(info());
      }
    }
    runtime = null; // become an orphan
    aruntime = null;
  }