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_); }
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()); }
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_); }
/** 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; }