Exemple #1
0
/*
 * Performs a context switch from one MACHINE_CONTEXT (thread) to another.
 */
void ContextSwitch(struct CONTEXT * oldStack, struct CONTEXT * newStack)
{
#ifdef DEBUG
        TIME time = TimeGet();
#endif

        if( oldStack != newStack ) {
                //The NextStack is set, so we need to context switch.
#ifdef DEBUG
                CounterAdd(&newStack->TimesSwitched, 1);
                CounterAdd(&newStack->TimesRun, 1);
                newStack->LastRanTime = time;
                newStack->LastSelectedTime = time;
#endif

                //The Hal requires that no interrupts fire during the switch.
                IsrDisable(IRQ_LEVEL_MAX);

                //now that the system looks like the switch has
                //happened, go ahead and do the switch.
                //NOTE: If you change anything below here, you have to update ContextBootstrap.
                HalContextSwitch(&oldStack->MachineState, &newStack->MachineState);

                IsrEnable(IRQ_LEVEL_MAX);
        } else {
                //we are critical but the thread was the same,
                //so dont bother doing context switch.
#ifdef DEBUG
                CounterAdd(&newStack->TimesRun, 1);
                newStack->LastRanTime = time;
#endif
        }
}
Exemple #2
0
COUNT SerialRead(char * buf, COUNT len)
{
        COUNT read = 0;
        COUNT readGeneration;
        BOOL wasFull = FALSE;

        do {
                IsrDisable(IRQ_LEVEL_SERIAL_READ);

                if ( RingBufferIsFull( &SerialInputRing ) ) {
                        wasFull = TRUE;
                }

                read = RingBufferRead(buf, len, &SerialInputRing);
                readGeneration = ReadGenerationCount;

                IsrEnable(IRQ_LEVEL_SERIAL_READ);

                if (read == 0) {
                        GenerationWait(&ReadGeneration, readGeneration, NULL);
                }
        } while (read == 0);

        // We were full, so lets make sure there wasn't any data buffered
        // in the hal.
        if ( wasFull ) {
                HalRaiseInterrupt( IRQ_LEVEL_SERIAL_READ );
        }
        return read;
}
Exemple #3
0
void TimerRegister(
                struct HANDLER_OBJECT * newTimer,
                TIME wait,
                HANDLER_FUNCTION * handler,
                void * context )
{
        TIME time = TimeGet();
        TIME timerTime = time + wait;

        IsrDisable(IRQ_LEVEL_MAX);

        //Construct timer
        HandlerRegister( newTimer );
        newTimer->Function = handler;
        newTimer->Context = context;

        //Add to heap
        if ( timerTime >= time ) {
                HeapAdd(timerTime, &newTimer->Link.WeightedLink, Timers );
        } else {
                //Overflow ocurred
                HeapAdd(timerTime, &newTimer->Link.WeightedLink, TimersOverflow);
        }

        IsrEnable(IRQ_LEVEL_MAX);
        //Because we added a new timer, we may want to wait
        //a different amount of time than previously thought.
        //Lets update the hardware countdown.
        TimerSetNextTimer(time);

}
Exemple #4
0
/*
 * WorkerItemIsFinished should be used by creator of a work item
 * to see if his work item structure is free for use. If
 * WorkerItemIsFinished returns TRUE, then it is safe to use
 * the work item.
 *
 * If it returns FALSE, then the work item is still either
 * queued, or currently running.
 *
 * USAGE:
 * Only the work item's owner should call WorkerItemIsFinished.
 * It is the caller's responsibility to avoid racing to reclaim
 * work items.
 */
BOOL WorkerItemIsFinished( struct WORKER_ITEM * item )
{
        BOOL result;
        IsrDisable(IRQ_LEVEL_MAX);
        result = item->Finished;
        IsrEnable(IRQ_LEVEL_MAX);
        return result;
}
Exemple #5
0
void ContextBootstrap(void * arg)
{
        struct CONTEXT * context = arg;

        //Here is where we end up if the kernel context switches to a new thread.
        //i.e. this is the same state as the line after HalContextSwitch.
        IsrEnable(IRQ_LEVEL_MAX);

        context->Main(context->MainArg);
        //Should never return.
        KernelPanic();
}
Exemple #6
0
COUNT SerialWrite(char * buf, COUNT len)
{
        COUNT write;

        IsrDisable(IRQ_LEVEL_SERIAL_WRITE);
        write = RingBufferWrite(buf, len, &SerialOutputRing);
        IsrEnable(IRQ_LEVEL_SERIAL_WRITE);

        HalRaiseInterrupt(IRQ_LEVEL_SERIAL_WRITE);

        return write;
}
Exemple #7
0
void WatchdogAddFlag( INDEX index )
{
        FLAG flag = FLAG_NONE;

        ASSERT( index <= FLAG_MAX_INDEX );

        flag = FlagGetBit( index );

        IsrDisable(IRQ_LEVEL_WATCHDOG);
        FlagOn( WatchdogDesiredMask, flag );
        IsrEnable(IRQ_LEVEL_WATCHDOG);
}
Exemple #8
0
/*
 * Call this routine to tell the watchdog that the flag
 * owner has run.
 */
void WatchdogNotify( INDEX index )
{
        FLAG flag;
#ifdef DEBUG
        TIME time;
#endif

        //Ensure that we are using a valid flag.
        ASSERT( index <= FLAG_MAX_INDEX );

        //find the bit we want to flip.
        flag = FlagGetBit( index );

        IsrDisable(IRQ_LEVEL_WATCHDOG);

        //Assert that this flag is present in the desired mask.
        ASSERT(FlagGet(flag, WatchdogDesiredMask));

#ifdef DEBUG
        time = TimeGet();
        WatchdogLastUpdatedTime = time;
#endif
        FlagOn( WatchdogCurMask, flag );
        //check to see if all of the players have shown up.
        if ( FlagsEqual(WatchdogCurMask, WatchdogDesiredMask) ) {
                //We have flipped all the flags required.
                //So lets pet the watchdog.
                HalPetWatchdog(Timeout);
                //Now lets clear the mask because we need to
                //restart our checking.
                WatchdogCurMask = FLAG_NONE;

#ifdef DEBUG
                WatchdogLastClearedTime = time;
#endif
        }
        IsrEnable(IRQ_LEVEL_WATCHDOG);
}