예제 #1
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;
}
예제 #2
0
void Main(struct Boot_Info *bootInfo) {
    Init_BSS();
    Init_Screen();
    Init_Mem(bootInfo);
    Init_CRC32();
    Init_TSS();

    lockKernel();
    Init_Interrupts(0);
    Init_SMP();
    TODO_P(PROJECT_VIRTUAL_MEMORY_A,
           "initialize virtual memory page tables.");
    Init_Scheduler(0, (void *)KERN_STACK);
    Init_Traps();
    Init_Local_APIC(0);
    Init_Timer();

    Init_Keyboard();
    Init_DMA();
    /* Init_Floppy(); *//* floppy initialization hangs on virtualbox */
    Init_IDE();
    Init_PFAT();
    Init_GFS2();
    Init_GOSFS();
    Init_CFS();
    Init_Alarm();

    Release_SMP();

    /* Initialize Networking */
    Init_Network_Devices();
    Init_ARP_Protocol();
    Init_IP();
    Init_Routing();
    Init_Sockets();
    Init_RIP();
    /* End networking subsystem init */

    /* Initialize Sound */
    Init_Sound_Devices();
    /* End sound init */

    Mount_Root_Filesystem();

    TODO_P(PROJECT_VIRTUAL_MEMORY_A, "initialize page file.");

    Set_Current_Attr(ATTRIB(BLACK, GREEN | BRIGHT));
    Print("Welcome to GeekOS!\n");
    Set_Current_Attr(ATTRIB(BLACK, GRAY));

    TODO_P(PROJECT_SOUND, "play startup sound");

    Spawn_Init_Process();

    /* it's time to shutdown the system */
    Hardware_Shutdown();

    /* we should not get here */
}
/**
 * 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;
}
예제 #4
0
/**
 * Add a waiting activity to the waiting queue.
 *
 * @param waitingAct The activity to queue up.
 * @param release    If true, the kernel lock should be released on completion.
 */
void ActivityManager::addWaitingActivity(RexxActivity *waitingAct, bool release )
{
    ResourceSection lock("ActivityManager::addWaitingActivity", 0);                // need the control block locks
    addWaitingActivityCount += 1;

    // nobody waiting yet?  If the release flag is true, we already have the
    // kernel lock, but nobody is waiting.  In theory, this can't really
    // happen, but we can return immediately if that is true.
    if (waitingActivities.empty())
    {
        // we're done if we already have the lock and the queue is empty.
        if (release)
        {
            return;
        }
        // add to the end
        waitingActivities.push_back(waitingAct);
        // this will ensure this happens before the lock is released
        sentinel = false;
        // we should end up getting the lock immediately, but you never know.
        lock.release();                  // release the lock now
    }
    else
    {
        // add to the end
        waitingActivities.push_back(waitingAct);
        // this will ensure this happens before the lock is released
        sentinel = false;
        // we're going to wait until posted, so make sure the run semaphore is cleared
        waitingAct->clearWait();
        sentinel = true;
        lock.release();                    // release the lock now
        sentinel = false;
        // if we are the current kernel semaphore owner, time to release this
        // so other waiters can
        if (release)
        {
            unlockKernel();
        }
        SysActivity::yield();            // yield the thread
        waitingAct->waitForDispatch();   // wait for this thread to get dispatched again
    }

    sentinel = true;
    lockKernel();                        // get the kernel lock now
    // belt and braces.  it is possible the dispatcher was
    // reentered on the same thread, in which case we have an
    // earlier stack frame waiting on the same semaphore.  Clear it so it
    // get get reposted later.
    waitingAct->clearWait();
    sentinel = false;
    lock.reacquire();                    // get the resource lock back
    sentinel = false;                    // another memory barrier

    // We only get dispatched if we end up at the front of the queue again,
    // so just pop the front element.
    waitingActivities.pop_front();
    sentinel = true;
    // if there's something else in the queue, then post the run semaphore of
    // the head element so that it wakes up next and starts waiting on the
    // run semaphore
    if (hasWaiters())
    {
        waitingActivities.front()->postDispatch();
    }
    // the setting of the sentinel variables acts as a memory barrier to
    // ensure that the assignment of currentActivitiy occurs precisely at this point.
    sentinel = false;
    currentActivity = waitingAct;        /* set new current activity          */
    sentinel = true;
    /* and new active settings           */
    Numerics::setCurrentSettings(waitingAct->getNumericSettings());
}