/**
 * We're leaving the current thread.  So we need to deactivate
 * this.
 */
void InterpreterInstance::exitCurrentThread()
{
    // find the current activity and deactivate it, and
    // release the kernel lock.
    RexxActivity *activity = findActivity();
    activity->exitCurrentThread();
}
Example #2
0
RexxActivity *ActivityManager::findActivity()
/******************************************************************************/
/* Function:  Locate the activity associated with a thread                    */
/******************************************************************************/
{
    return findActivity(SysActivity::queryThreadID());
}
/**
 * Attach a thread to an interpreter instance.
 *
 * @return The attached activity.
 */
RexxActivity *InterpreterInstance::attachThread()
{
    // first check for an existing activity
    RexxActivity *activity = findActivity();
    // do we have this?  we can just return it
    if (activity != OREF_NULL)
    {
        // make sure we mark this as attached...we might be nested and don't want to
        // clean this up until we complete
        activity->nestAttach();
        return activity;
    }

    // we need to get a new activity set up for this particular thread
    activity = ActivityManager::attachThread();

    // resource lock must come AFTER we attach the thread, otherwise
    // we can create a deadlock situation when we attempt to get the kernel
    // lock
    ResourceSection lock("InterpreterInstance::attachThread", 0);
    // add this to the activity lists
    allActivities->append((RexxObject *)activity);
    // associate the thread with this instance
    activity->setupAttachedActivity(this);
    return activity;
}
Example #4
0
/**
 * Attach an activity to an interpreter instance
 *
 * @param instance The interpreter instance involved.
 *
 * @return Either an existing activity, or a new activity created for
 *         this thread.
 */
RexxActivity *ActivityManager::attachThread()
{
    // it's possible we already have an activity active for this thread.  That
    // most likely occurs in nested RexxStart() calls.
    RexxActivity *oldActivity = findActivity();
    // we have an activity created for this thread already.  The interpreter instance
    // should already have handled the case of an attach for an already attached thread.
    // so we're going to have a new activity to create, and potentially an existing one to
    // suspend
    // we need to lock the kernel to have access to the memory manager to
    // create this activity.
    lockKernel();
    RexxActivity *activityObject = createCurrentActivity();
    // Do we have a nested interpreter call occurring on the same thread?  We need to
    // mark the old activity as suspended, and chain this to the new activity.
    if (oldActivity != OREF_NULL)
    {
        oldActivity->setSuspended(true);
        // this pushes this down the stack.
        activityObject->setNestedActivity(oldActivity);
    }

    unlockKernel();                /* release kernel semaphore          */

    // now we need to have this activity become the kernel owner.
    activityObject->requestAccess();
    // this will help ensure that the code after the request access call
    // is only executed after access acquired.
    sentinel = true;
    // belt-and-braces.  Make sure the current activity is explicitly set to
    // this activity before leaving.
    currentActivity = activityObject;
    return activityObject;
}
/**
 * Flip on external trace for a thread.
 *
 * @param thread_id The target thread id.
 * @param on_or_off The trace setting.
 *
 * @return true if this worked, false otherwise.
 */
bool ActivityManager::setActivityTrace(thread_id_t thread_id, bool  on_or_off )
{
    ResourceSection lock;
    // locate the activity associated with this thread_id.  If not found, return
    // a failure.
    Activity *activity = findActivity(thread_id);
    if (activity != OREF_NULL)
    {
        return activity->setTrace(on_or_off);
    }
    return false;                        // this was a failure
}
/**
 * Raise a halt condition on an activity.
 *
 * @param thread_id The target thread identifier.
 * @param description
 *                  The description of the halt.
 *
 * @return Returns the halt result.  Returns false if a halt
 *         condition is already pending or the target activity
 *         is not found.
 */
bool ActivityManager::haltActivity(thread_id_t  thread_id, RexxString * description )
{
    ResourceSection lock;
    // locate the activity associated with this thread_id.  If not found, return
    // a failure.
    Activity *activity = findActivity(thread_id);
    if (activity != OREF_NULL)
    {
        return activity->halt(description);
    }
    return false;                        // this was a failure
}
Example #7
0
/**
 * Get an already existing activity for the current thread and
 * give it kernel access before returning.  This will fail if
 * the thread has not been properly attached.
 *
 * @return The activity for this thread.
 */
RexxActivity *ActivityManager::getActivity()
{
    // it's possible we already have an activity active for this thread.  That
    // most likely occurs in nested RexxStart() calls.
    RexxActivity *activityObject = findActivity();
    if (activityObject == OREF_NULL)     /* Nope, 1st time through here.      */
    {
        // this is an error....not sure how to handle this.
        return OREF_NULL;
    }
    // go acquire the kernel lock and take care of nesting
    activityObject->enterCurrentThread();
    return activityObject;             // Return the activity for thread
}
/**
 * Get an already existing activity for the current thread and
 * give it kernel access before returning.  This will fail if
 * the thread has not been properly attached.
 *
 * @return The activity for this thread.
 */
Activity *ActivityManager::getActivity()
{
    // it's possible we already have an activity active for this thread.  That
    // most likely occurs in nested RexxStart() calls.
    Activity *activityObject = findActivity();
    // we generally should have something.  Somehow we have an improperly
    // attached thread.  Just return a failure indicator.
    if (activityObject == OREF_NULL)
    {
        return OREF_NULL;
    }
    // go acquire the kernel lock and take care of nesting
    activityObject->enterCurrentThread();
    return activityObject;             // Return the activity for thread
}
Example #9
0
bool ActivityManager::setActivityTrace(
     thread_id_t thread_id,            /* target thread id                  */
     bool  on_or_off )                 /* trace on/off flag                 */
/******************************************************************************/
/* Function:   Flip on a bit in a target activities top activation            */
/******************************************************************************/
{
    ResourceSection lock("ActivityManager::setActivityTrace", 0);
    // locate the activity associated with this thread_id.  If not found, return
    // a failure.
    RexxActivity *activity = findActivity(thread_id);
    if (activity != OREF_NULL)
    {
        return activity->setTrace(on_or_off);
    }
    return false;                        // this was a failure
}
Example #10
0
bool ActivityManager::haltActivity(
     thread_id_t  thread_id,           /* target thread id                  */
     RexxString * description )        /* description to use                */
/******************************************************************************/
/* Function:   Flip on a bit in a target activities top activation            */
/******************************************************************************/
{
    ResourceSection lock("ActivityManager::haltActivity", 0);
    // locate the activity associated with this thread_id.  If not found, return
    // a failure.
    RexxActivity *activity = findActivity(thread_id);
    if (activity != OREF_NULL)
    {
        return activity->halt(description);
    }
    return false;                        // this was a failure
}
/**
 * Get a root activity for a new interpreter instance.
 *
 * @return The newly created activity.
 */
Activity *ActivityManager::getRootActivity()
{
    // it's possible we already have an activity active for this thread.  That
    // most likely occurs in nested RexxStart() calls.  Get that activity first,
    // and if we have one, we'll need to push this down.
    Activity *oldActivity = findActivity();

    // we need to lock the kernel to have access to the memory manager to
    // create this activity.
    lockKernel();

    // get a new activity object
    Activity *activityObject = createCurrentActivity();
    unlockKernel();
    // mark this as the root activity for an interpreter instance.  Some operations
    // are only permitted from the root threads.
    activityObject->setInterpreterRoot();

    // Do we have a nested interpreter call occurring on the same thread?  We need to
    // mark the old activity as suspended, and chain this to the new activity.
    if (oldActivity != OREF_NULL)
    {
        oldActivity->setSuspended(true);
        // this pushes this down the stack.
        activityObject->setNestedActivity(oldActivity);
    }

    // now we need to have this activity become the kernel owner.
    activityObject->requestAccess();
    // this will help ensure that the code after the request access call
    // is only executed after access acquired.
    sentinel = true;

    activityObject->activate();        // let the activity know it's in use, potentially nested
    // belt-and-braces.  Make sure the current activity is explicitly set to
    // this activity before leaving.
    currentActivity = activityObject;
    return activityObject;
}
/**
 * Attempt to shutdown the interpreter instance.  This can only be done
 * from the root activity.
 *
 * @return true if shutdown has been initiated, false otherwise.
 */
bool InterpreterInstance::terminate()
{
    // if our current activity is not the root one, we can't do that
    RexxActivity *current = findActivity();
    // we also can't be doing active work on the root thread
    if (current != rootActivity || rootActivity->isActive())
    {
        return false;
    }

    terminated = false;
    // turn on the global termination in process flag
    terminating = true;

    {

        ResourceSection lock("InterpreterInstance::terminate", 0);
        // remove the current activity from the list so we don't clean everything
        // up.  We need to
        allActivities->removeItem((RexxObject *)current);
        // go remove all of the activities that are not doing work for this instance
        removeInactiveActivities();
        // no activities left?  We can leave now
        terminated = allActivities->items() == 0;
        // we need to restore the rootActivity to the list for potentially running uninits
        allActivities->append((RexxObject *)current);
    }

    // if there are active threads still running, we need to wait until
    // they all finish
    if (!terminated)
    {
        terminationSem.wait("InterpreterInstance::terminate", 0);
    }

    // if everything has terminated, then make sure we run the uninits before shutting down.
    // This activity is currently the current activity.  We're going to run the
    // uninits on this one, so reactivate it until we're done running
    enterOnCurrentThread();
    // release any global references we've been holding.
    globalReferences->empty();
    // before we update of the data structures, make sure we process any
    // pending uninit activity.
    memoryObject.verboseMessage("Calling runUninits through collectAndUninit from InterpreterInstance::terminate\n");
    memoryObject.collectAndUninit(Interpreter::lastInstance());

    // do system specific termination of an instance
    sysInstance.terminate();

    // ok, deactivate this again...this will return the activity because the terminating
    // flag is on.
    exitCurrentThread();
    terminationSem.close();

    // make sure the root activity is removed by the ActivityManager;
    ActivityManager::returnRootActivity(current);

    // tell the main interpreter controller we're gone.
    Interpreter::terminateInterpreterInstance(this);
    return true;
}
/**
 * Find an activity for the current thread that's associated
 * with this activity.
 *
 * @return The target activity.
 */
RexxActivity *InterpreterInstance::findActivity()
{
    return findActivity(SysActivity::queryThreadID());
}
/**
 * Detach a thread from this interpreter instance.
 *
 * @return true if this worked ok.
 */
bool InterpreterInstance::detachThread()
{
    // first check for an existing activity
    return detachThread(findActivity());
}
/**
 * Locate the activity associated with the current thread
 *
 * @return The Activity for this thread, if it exists.
 */
Activity *ActivityManager::findActivity()
{
    return findActivity(SysActivity::queryThreadID());
}